Azure Gateway Load Balancer を FortiGate で試す

azure fortigate
Published: 2022-07-16

はじめに

Azure Gateway Load Balancer が GA になりました。

Generally available: Azure Gateway Load Balancer

公式ドキュメントによると、Gateway Load Balancer には次のメリットがあります。

Azure Gateway Load Balancer を使用すると、管理上のオーバーヘッドが増えずに、高度なネットワーク機能を簡単に追加または削除できます。 これにより、パブリック エンドポイントへのすべてのトラフィックがアプリケーションの前にアプライアンスに最初に送信されるのを確認するために必要な、ネットワーク内の Bump-in-the-wire テクノロジが提供されます。 NVA を使用するシナリオでは、フローが対称的である点が特に重要です。 Azure Gateway Load Balancer は、バックエンド プール内の特定のインスタンスへのフローの保持性と、フローの対称性を維持します。 その結果、手動で構成することなく、追加ネットワーク仮想アプライアンスへの一貫したルートが保証されます。 その結果、パケットは両方向に同じネットワーク パスを通過し、このキー機能を必要とするアプライアンスはシームレスに機能できます。

引用:Azure Gateway Load Balancer

「実際にやってみないとわからん…」ということで、Fortinet 社が提供している ARM テンプレートを利用して環境を構築して、Gateway Load Balancer の挙動を確認しました。

参考:FortiGate Next-Generation Firewall in Azure GWLB

Gateway Load Balancer の設定

Gateway Load Balancer の特徴が VXLAN の設定です。Gateway Load Balancer は NVA との間に2本の VXLAN トンネルを張ります。External が FortiGate から見たインターネット側の VXLAN トンネル、Internal が FortiGate から見た VNET 側の VXLAN トンネルです。これらのトンネルを張るための VID とポート番号を指定する必要があります。

VXLAN の設定

また、すべてのトラフィックを負荷分散するために HA ポートを利用します。

HA ポートの設定

ヘルスチェックには FortiGate が管理用にリッスンしているポートを利用します。

ヘルスチェックの設定

FortiGate の設定

FortiGate には、Gateway Load Balancer と VXLAN のトンネルを張るための NIC と管理用の NIC がアタッチされます。

デプロイされた FortiGate の NIC

管理用の NIC は FortiGate 自身がインターネットにアクセスするために必要です。Gateway Load Balancer は Standard 内部ロードバランサのため、Gateway Load Balancer と関連付けた NIC からはインターネットにアクセスできません。この仕様を回避するために、Public IP アドレスを割り当てた NIC を管理用として別途用意しているようです。管理用 NIC の Public IP アドレスにブラウザでアクセスすると FortiGate の管理画面にアクセスできます。

参考:Azure Load Balancer の SNAT (Outbound 通信) がわからん

Fortinet 社が提供するテンプレートではカスタムデータを利用して複数のコンフィグを投入しています。

まずは NIC 周りの設定です。DHCP でデフォルトゲートウェイを受け取らないようにしたうえで、VXLAN 用 NIC の MTU のサイズを1570にしています。FortiGate は VXLAN でカプセル化されたパケットを Gateway Load Balancer とやりとりしますので、追加で付与される VXLAN のヘッダ分だけ MTU を増やす必要があります。

また、VXLAN 用 NIC が Gateway Load Balancer からのヘルスチェックに応答できるように VXLAN 用ポートの allowaccess がprobe-response になっています。

config system probe-response
    set mode http-probe
end
config system interface
    edit "port1"
        set vdom "root"
        set mode dhcp
        set allowaccess probe-response
        set description "Provider"
        set defaultgw disable
        set mtu-override enable
        set mtu 1570
    edit "port2"
        set vdom "root"
        set mode dhcp
        set allowaccess ping https ssh fgfm probe-response
        set type physical
        set description "Management"
        set snmp-index 2
        set defaultgw disable
    next
    edit "extvxlan"
        set vdom "root"
        set type vxlan
        set snmp-index 7
        set interface "port1"
    next
    edit "intvxlan"
        set vdom "root"
        set type vxlan
        set snmp-index 8
        set interface "port1"
    next
end

複数 NIC の構成なので、パケットを正しい NIC から送出するためにスタティックルートを設定しています。デフォルトルートは Public IP アドレスを関連付けている管理用 NIC に向いています。また、Gateway Load Balancer からのヘルスチェックへの応答を正しい NIC から送出するために、168.63.129.16 へのパケットを VXLAN 用 NIC から送出するためのスタティックルートが設定されています。

config firewall address
    edit "AzureProbeSourceIP"
        set allow-routing enable
        set subnet 168.63.129.16 255.255.255.255
    next
end
config router static
    edit 1
        set gateway 172.16.10.129
        set device "port2"
    next
    edit 2
        set gateway 172.16.10.1
        set device "port1"
        set dstaddr "AzureProbeSourceIP"
    next
end

そして VXLAN の設定です。対向は Gateway Load Balancer のプライベート IP アドレス、VNI とポート番号は Gateway Load Balancer に設定した値になっています。

config system vxlan
    edit "extvxlan"
        set interface "port1"
        set vni 801
        set dstport 2001
        set remote-ip "172.16.10.4"
    next
    edit "intvxlan"
        set interface "port1"
        set vni 800
        set dstport 2000
        set remote-ip "172.16.10.4"
    next
end

設定が正しければ、NIC の画面に VXLAN のトンネルが出現します。

VXLAN インターフェース

そしてこの2つの VXLAN インターフェースを Virtual Wire に設定することで、NAT モードでもパケットを透過的に処理できるようにしています。

config system virtual-wire-pair
    edit "vxlanvwpair"
        set member "extvxlan" "intvxlan"
    next
end

なお、テンプレートには設定されていませんが、複数の FortiGate を導入する場合は、設定を同期するために auto-scale の設定を入れるのもよさそうです。複数の FortiGate に同じ設定を何度も投入するのは手間です。

# For Master node
config system auto-scale
    set status enable
    set role primary
    set sync-interface "port2"
    set psksecret <YOUR-SECRET>
end

# For other nodes
config system auto-scale
    set status enable
    set sync-interface "port2"
    set primary-ip 172.16.10.132
    set psksecret <YOUR-SECRET>
end

いったん振り返り

ここまで時点で次のような構成が出来上がっています。

Gateway LB と FortiGate の構成イメージ

Gateway Load Balancer と Azure リソースの紐づけ

できあがった Gateway Load Balancer を NVA で保護したい Standard Public LB や Public IP アドレスと紐づけます。

Gateway LB と Standard Public LB の紐づけ

Gateway LB と Standard Public IP の紐づけ

この紐づけをチェーンと呼びます。このチェーンはサブスクリプションを越えられます。上記の Standard Public IP とのチェーンは同一テナント別サブスクリプションです。ドキュメントを見る限りでは、ポータル以外の方法を用いることでテナントも越えられるようです。

テナント間のチェーンは、Azure portal を介してはサポートされません。

参考:制限事項

1つの Gateway Load Balancer とチェーンできるリソースの数は最大100です。

参考:Load balancer limits

通信フロー

通信フローは次のようになります。Standard Public LB/IP に到達したパケットは、バックエンドのサーバに直接転送されるのではなく Gateway Load Balancer に転送されます。そして、Gateway Load Balancer は External の VXLAN のトンネル経由でパケットを FortiGate に転送します。FortiGate は Gateway Load Balancer から受信したパケットを Internal の VXLAN トンネルから排出します。排出されたパケットは、Gateway Load Balancer 経由で Standard Public LB/IP 配下のバックエンドサーバに転送されます。

Gateway LB と FortiGate の通信フローのイメージ

ポリシーの設定

最後に、FortiGate で通信を許可するために、ポリシーを設定します。Gateway Load Balancer 経由で FortiGate に到達するパケットの特徴は次の3つです。

  1. Inbound 通信の送信元 IP アドレスは SNAT されない。インターネット上のクライアントのグローバル IP アドレスのまま。
  2. Inbound 通信の宛先 IP アドレスは、チェーンしている Standard Public LB/IP のグローバル IP アドレスになる。バックエンドの仮想マシンのプライベート IP アドレスではない
  3. Outbound 通信の送信元 IP アドレスは、チェーンしている Standard Public LB/IP のグローバル IP アドレスになる。バックエンドの仮想マシンのプライベート IP アドレスではない

したがって、FortiGate のポリシーは次のようになります。

FortiGate のポリシー

1行目はインターネットから Standard Public LB/IP への Inbound 通信を制御するためのポリシーです。External の VXLAN から Internal の VXLAN トンネルに流れる Standard Public LB/IP 宛の HTTP と SSH のみを許可しています。通信の制御で利用する IP アドレスは Standard Public LB/IP のグローバル IP アドレスです。

2行目は Standard Public LB/IP 配下の仮想マシンからインターネットへの Outbound 通信を制御するためのポリシーです。このポリシーでも、利用する IP アドレスは Standard Public LB/IP のグローバル IP になります。

なお、Gateway Load Balancer を利用する場合、Inbound と Outbound ともに NVA での SNAT は不要です。

動作確認

Ubuntu 1台に対して SSH を負荷分散する Standard Public LB を Gateway Load Balancer とチェインしました。Standard Public LB のグローバル IP アドレスに対して SSH すると、当然 Ubuntu にログインできます。Inbound 通信の送信元 IP アドレスは維持されるので、Ubuntu に記録される SSH の送信元 IP アドレスは我が家のグローバル IP アドレスになります。

> ssh <USERNAME>@52.xxx.xxx.31
<USERNAME>@52.xxx.xxx.31's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.13.0-1031-azure x86_64)

@ubuntu02:~$
@ubuntu02:~$
@ubuntu02:~$ more /var/log/auth.log

Jul 16 14:42:04 ubuntu02 sshd[12625]: Accepted password for <USERNAME> from 157.xxx.xxx.199 port 64991 ssh2

FortiGate の通信ログは、我が家のグローバル IP アドレスである 157.xxx.xxx.199 から Standard Public LB の Standard Public IP である 52.xxx.xxx.31 への通信として記録されます。

date=2022-07-14 time=22:05:31 eventtime=1657861531819544200 tz="-0700" logid ="0000000013" type="traffic" subtype="forward" level="notice" vd="root" srcip=157.xxx.xxx.199 srcport=64721 srcintf="extvxlan" srcintfrole="undefined" dstip=52.xxx.xxx.31 dstport=22 dstintf="intvxlan" dstintfrole="undefined" srccountry="Japan" dstcountry="Japan" sessionid=3729 proto=6 action="timeout" policyid=1 policytype="policy" poluuid="c08aeeaa-03ec-51ed-a6a2-02c91b851297" policyname="int-ext_vxlan" service="SSH" trandisp="noop" duration=25 sentbyte=260 rcvdbyte=0 sentpkt=5 rcvdpkt=0 appcat="unscanned"

Standard Public LB にアウトバウンド送信規則がある場合、配下の Ubuntu サーバは Gateway Load Balancer 経由でインターネットにアクセスできます。送信元 IP アドレスは Standard Public LB のフロントエンドの Standard Public IP になります。

@ubuntu02:~$ curl ifconfig.me
52.xxx.xxx.31

FortiGate の通信ログは、Standard Public LB のフロントエンドの Standard Public IP からインターネット上のグローバル IP アドレスへの通信として記録されます。

date=2022-07-16 time=08:20:05 eventtime=1657984805805889399 tz="-0700" logid="0317013312" type="utm" subtype="webfilter" eventtype="ftgd_allow" level="notice" vd="root" policyid=3 poluuid="039848fc-03fa-51ed-a1d1-d5cb0118567c" policytype="policy" sessionid=15633 srcip=52.xxx.xxx.31 srcport=1024 srccountry="Japan" srcintf="intvxlan" srcintfrole="undefined" srcuuid="52937c74-03ff-51ed-bda8-e1acb72729c3" dstip=34.160.111.145 dstport=80 dstcountry="United States" dstintf="extvxlan" dstintfrole="undefined" dstuuid="6dbda636-03ec-51ed-5486-7fc40eb62cee" proto=6 service="HTTP" hostname="ifconfig.me" profile="monitor-all"  action="passthrough" reqtype="direct" url="http://ifconfig.me/" sentbyte=75 rcvdbyte=0 direction="outgoing" msg="URL belongs to an allowed category in policy" method="domain" cat=52 catdesc="Information Technology"

アウトバウンド規則が存在しない場合、配下の Ubuntu サーバはインターネットにアクセスできません。配下のサーバがインターネットにアクセスするためには、アウトバウンド規則を設定するか、Public IP アドレスや NAT Gateway を利用する必要があります。ただし、Public IP や NAT Gateway を利用した場合、Outbound 通信は NVA を経由しません。

@ubuntu01:~$ curl ifconfig.me
curl: (28) Failed to connect to ifconfig.me port 80: Connection timed out

Info

なお、試しにアウトバウンド規則だけ(=ヘルスチェックと負荷分散規則を作らない)の Standard Public LB 配下の Ubuntu からインターネットにアクセスしてみたところ、Gateway Load Balancer と NVA 経由でインターネットにアクセスできました。

Log
@ubuntu03:~$ curl ifconfig.me
20.xxx.xxx.240
date=2022-07-16 time=08:17:09 eventtime=1657984629699220901 tz="-0700" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" srcip=20.xxx.xxx.240 srcport=1024 srcintf="intvxlan" srcintfrole="undefined" dstip=34.160.111.145 dstport=80 dstintf="extvxlan" dstintfrole="undefined" srccountry="Japan" dstcountry="United States" sessionid=10781 proto=6 action="close" policyid=3 policytype="policy" poluuid="039848fc-03fa-51ed-a1d1-d5cb0118567c" policyname="Outbound-web" service="HTTP" trandisp="noop" duration=1 sentbyte=395 rcvdbyte=512 sentpkt=6 rcvdpkt=4 appcat="unscanned" utmaction="allow" countweb=1 utmref=65535-238

まとめ

GA になった Gateway Load Balancer を FortiGate を利用して試しました。本エントリで試した通り、Standard Public LB/IP と Gateway Load Balancer をチェインするだけで NVA を透過的に導入できるので、インターネットからの Inbound 通信を保護するための NVA の導入が劇的に簡単になりました。

一方で、現時点での Gateway Load Balancer がチェインできるリソースが Standard Public LB/IP に限られているため、インターネットへの Outbound 通信を制御するための NVA や VNET 間の通信を制御するための NVA には利用できません。今後の機能拡張に期待です。