Azure Firewall と NVA を多段で併用する

azure
Published: 2023-06-14

はじめに

やってみたことがなかったので、次の構成を試してみました。

  • VNet 間のルーティングと通信制御のために Azure Firewall を内部ファイアウオールとして利用する
  • インターネットとの通信制御のために NVA を外部ファイアウオールとして利用する

構成図は次の通りです。

構成図

Azure Firewall と NVA の併用は環境を複雑にするだけにも思えます。ですが、「インターネットとの通信制御では高機能な NVA を使いたい。しかし、VNET 間の通信も NVA で制御しようとすると、処理するトラフィック量が増えてしまい大きなサイズの仮想マシンが必要になる。その結果として vCPU の数が増えて NVA のライセンス費用が高くなってしまう。NVA はインターネットとの通信制御だけに専念させたい」というようなケースで使えるかもしれません。

なお、Azure Firewall と NVA を併用する構成としては「外部 NVA を 内部 Azure Firewall と同じハブ VNet に置く」「外部 NVA を置いた VNet を各 Spoke VNet と新たにピアリングする」といった方式もありえます。ですが今回はこれまで試したことのない多段 ファイアウォールな構成に挑戦しました。

考慮事項

この構成を実現するためには、内部 Azure Firewall のデフォルトルートを外部 NVA に向ける必要があります。ですが、普通の Azure Firewall を利用する際には、AzureFirewallSubnet のデフォルトルートが Azure のインターネットに向いている必要があります。

デフォルトルートが Azure のインターネットに向いていない環境に Azure の Firewall をデプロイしたい場合には、強制トンネリングのオプションを有効化します。このオプションを有効化することで、0.0.0.0/0 が 外部 NVA に向いている UDR を持つルートテーブルを AzureFirewallSubnet に設定できます。

Azure Firewall の強制トンネリング

また、Azure Firewall の SNAT 設定も変更する必要があります。Azure Firewall は、強制トンネリングのオプションが有効化されていたとしても、プライベート IP アドレス以外の宛先への通信を自身のプライベート IP アドレスで SNAT します。その結果として、内部 Azure Firewall を経由するインターネット宛ての通信の送信元アドレスが Azure Firewall のプライベート IP アドレスになってしまい、外部 NVA からすると全ての通信が内部 Azure Firewall から来ているように見えます。これでは外部 NVA でスポーク VNet の VM ごとに通信を制御できません。

Azure Firewall は SNAT する対象のアドレス帯をカスタマイズできます。この機能を利用して Azure Firewall の SNAT を無効化することで、外部 NVA に到達する通信の送信元 IP アドレスがスポーク VNet の VM のまま保持されるようにします。

Azure Firewall の SNAT プライベート IP アドレス範囲

SNAT の設定例

なお、通信を Azure Firewall のアプリケーションルールで許可してしまうと、上記の設定に関係なく通信が SNAT されてしまいます。そのため、外部 NVA に向かう通信を許可する際にはネットワークルールを利用しなければなりません。

その他設定

各ポイントで UDR を設定します。

  • スポーク VNET の VM のサブネットで「0.0.0.0/0 が内部 Azure Firewall に向いている UDR」を持つルートテーブルを設定する
  • Azure Firewall Subnet で「0.0.0.0/0が 外部 NVA 用ロードバランサに向いている UDR」を持つルートテーブルを設定する
  • NVA のサブネットで「Azure 内のプライベート IP アドレスが内部 Azure Firewall に向いている UDR」を持つルートテーブルを設定する

設定した UDR

スポーク VNET の VM 上で https://ifconfig.me への NextHop を確認すると次のようになります。内部 Azure Firewall と 外部 NVA を通ってインターネットに向かっていることが分かります。

Nexhop の結果

また、Ubuntu の VM を 外部 NVA として代用するために、 Outbound の NAPT と Inbound のポートフォワーダ(外部 NVA 用 VM への TCP422を スポークVNET の VM の TCP22に転送)を設定しておきます。

iptables -t nat -A POSTROUTING -s 10.2.0.0/16 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp -d 10.3.1.4 --dport 422 -j DNAT --to-destination 10.2.0.7:22

動作確認

スポークVNET の VM から http://ifconfig.me にアクセスすると、外部 NVA に割り当てたグローバル IP アドレスが返ってきます。VM から Azure Firewall を通り NVA を経てインターネットにアクセスしていますことが分かります

$ curl ifconfig.me
20.109.xxx.xxx

外部 NVA 用 VM で tcpdump すると、送信元 IP アドレスがスポーク VNET の VM のプライベート IP アドレスのままであることを確認できます。内部 Azure Firewall の SNAT 無効化が効いています。

12:32:09.318706 IP 10.2.0.7.40982 > 34.160.111.145.80: Flags [.], ack 299, win 501, options [nop,nop,TS val 2516518068 ecr 2599634201], length 0

参考:SNAT が有効な状態の tcpdump

12:29:03.928627 IP 10.1.5.5.41272 > 34.160.111.145.80: Flags [.], ack 299, win 501, options [nop,nop,TS val 2516332678 ecr 750903980], length 0

インターネットから 外部 NVA 用 VM の Public IP アドレスに対して TCP422で通信すると、スポーク VNet 内の VM に SSH で接続できます。VM のログにはグローバル IP アドレスからの SSH であることが記録されています。

Jun 13 13:11:13 testubu02 sshd[21018]: Accepted password for xxxxxxx from 217.178.xx.xx port 48131 ssh2

なお、今回は NVA 用 VM が1台ですので Inbound の通信を処理する際に NVA で SNAT していません。そのため、サーバはクライアントの IP アドレスを確認できます。ですが、NVA が複数台いる場合には、非対称ルーティングを避けるために Inbound の通信に対して NVA で SNAT が必要です。この場合、サーバはクライアントの IP アドレスを確認できなくなります。

多段になっているので、間の 内部 Azure Firewall にトラフィックログが記録されます。スポーク VNET の VM から http://ifconfig.me へのアクセスや、インターネットから外部 NVA 経由での スポーク VNET の VM への SSH が確認できます。

Azure Firewall のログ

まとめ

Azure Firewall と NVA を多段で併用してみました。一般的な構成ではないと思いますが、Azure Firewall の設定とルーティングを整えれば実現できました。

Note

  • 当サイトは個人のブログです。このブログに示されている見解や意見は個人的なものであり、所属組織の見解や意見を表明するものではありません。
  • 公開情報を踏まえて正確な情報を掲載するよう努めますが、その内容の完全性や正確性、有用性、安全性、最新性について一切保証しません。
  • 添付文章やリンク先などを含む本サイトの内容は作成時点でのものであり、予告なく変更される場合があります。