🤟

FortiGateでIPsecトンネルを同一物理インターフェイスから繋いだ際の挙動について

2024/08/21に公開

FortiGateは恐らく日本で最も流通しているメーカのファイアウォール/UTMであり、
ステートフルインスペクションを導入している機器として筆頭に挙げられるかなと思う

「ステートフルインスペクション」という概念をFWと共に初めて誕生させたのは
イスラエル発のCheckPointになる記憶だが、ライセンス体系の明快さ、費用、
及び導入実績の豊富さから来る潤沢なナレッジが採用される理由になるのかな
個人的にはASIC周りが強みな印象。。

そんなFortiGate(FGT)はステートフルインスペクションという特性上、
非対称ルーティングを強く意識する必要がある機種であり、
多くの場合はUntrust-Trustの通信を考慮しなくても良いため議題に上がることが無い、が
ルーティングプロトコルにより経路選択を軽く敷いていたりすると話題に上がり始める
クラウドとデータセンターなどとのハイブリッドな構成の場合、
特にAWSなどは非対称ルーティングの有効化をドキュメントで明確に表明しているため、
伴ってGWに置かれているFWの調整を余儀なくされている例をよく見る

「AWS Transit Gatewayトラフィックフローと非対称ルーティング」
https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/inline-traffic-inspection-third-party-appliances/transit-gateway-asymmetric-routing.html
(TransitGatewayで調整できるけどね)

そんなこんなで、FGTとTransitGatewayの間でIPsecトンネルを冗長化させることが結構ある
Active-Active運用というより、やはり冗長化なのでActive-Standbyが多い印象
(でかいエコシステムの設計に携わったことないから中途半端な所感だけど)
BGPのASとかでFGT側でトンネルに優先度をつける感じ

しかしTransitGatewayはTransitGatewayの都合で戻りパケットを返してくるため、
FGTからすると行きと戻りの経路が異なるため非対称ルーティングの扱いとなり、
パケットがドロップされる流れ

そんな時はAWS側からの通信は成功するのに支店からAWS上のインスタンスへはpingが落ちまくったり
そもそも疎通しなかったりといったことがよく起こる

しかし、そんな中そういった事象が予想に反して発生していない例があった
その小さい支部の構成は60Fとかのローエンドモデルを採用しており、
HAを組んだりせず、単一の物理インターフェイスから2本のIPsecトンネルを張るという
少々疑問な構成になっており。。

逆に細かいことは気にしなくても良いかな、とサボる気持ちでいたところ、
客側に妙にネットワークに明るい方がおり、タバコ休憩中に非対称ルーティングにならないのかと
尋ねられ、確かになあ…と気になり持ち帰って調べてみた

結論から述べると非対称ルーティングの判定が物理インターフェイスで成されている(様に見える)ため、
異なる論理インターフェイスから行き帰りがあっても、ドロップが発生しないという理屈になるみたい

こういったパケットの扱いに疑問がある場合はUTMの判断が確認できるデバッグが一番
別にAWS上のインスタンスで無くとも検証はできるので、対抗に適当にトンネルAから来たものを
トンネルBに返すものを用意し、FGTにてdebug flowをipropeなどを有効化した状態で
取ってみるとこんな感じ


id=11833 func=print_pkt_detail line=5688 msg="vd-root:0 received a packet(proto=1, 192.168.71.2:5632->192.168.81.2:2048) from wan2.

wan2がLAN想定で71.2が配下の端末 ICMP出てるよ~というログ

id=11833 func=vf_ip_route_input_common line=2581 msg="find a route: flag=04000000 gw-192.168.81.2 via a"

via a よりIPsecトンネル「a」よりルーティングに従い発信を決定という感じ

id=11833 func=ipsecdev_hard_start_xmit line=788 msg="enter IPsec interface-a"

ポリシーヒットし、トンネル入り

trace_id=11833 func=ipsec_output_finish line=618 msg="send to 10.10.10.248 via intf-wan1"

トンネルの関連付いているwan1よりリモートGWへ発信

id=11834 func=print_pkt_detail line=5688 msg="vd-root:0 received a packet(proto=1, 192.168.81.2:5632->192.168.71.2:0) from b.

from bより、戻りがトンネル「b」を通じ着信

id=11834 func=resolve_ip_tuple_fast line=5768 msg="Find an existing session, id-0000538e, reply direction"

セッションがあると判断しております(ここがポイントかも)

id=20085 trace_id=11834 func=vf_ip_route_input_common line=2581 msg="find a route: flag=00000000 gw-192.168.71.2 via wan2"

wan2へ返しを発信 という流れ

id=11825 func=init_ip_session_common line=5858 msg="allocate a new session-0000538e"

id=11826 func=resolve_ip_tuple_fast line=5768 msg="Find an existing session, id-0000538e, reply direction"

上記2行よりセッションIDが同様だしreply directionともあるので、
異なるトンネルインターフェイスの通信を同一のセッションと捉えているのも分かるかな


と、こんな感じの結果でした
無事質問に回答できて一安心でしたとさ 知見を得たぞ!

Discussion