検証環境
- FortiGate-60E
- version v7.2.3
非対称ルーティングとパケットドロップ
非対称ルーティングとは、ある送信元と宛先間の通信において「送信元から宛先への行きの経路」と「宛先から送信元への戻りの経路」が異なるようなルーティングがなされることを指します。
非対称ルーティングが発生する通信が FortiGate を通る場合、FortiGate にて該当パケットがドロップされる場合があります。
以下では、非対称ルーティング発生時に FortiGate でパケットがドロップされる 2 つの原因について記載します。
原因① セッションに存在しない応答パケットのドロップ
以下のネットワークを考えます。

各機器で以下の通りルーティング設定がされています。
- FotiGate:デフォルトルートはルータA向け、10.2.2.0/24 へはルータB向け
- ルータA:デフォルトルートはルータB向け
- ルータB:デフォルトルートは FotiGate 向け
このネットワークで端末Aから端末Bへ通信する場合、以下の図のような経路になります。

上図の通り、
- 行き経路: 端末A → ルータA → ルータB → 端末B
- 戻り経路: 端末B → ルータB → FotiGate → ルータA → 端末A
となり FortiGate を通るのは戻りの通信だけになります。
そうなると、FotiGate ではセッションテーブルに存在しない応答パケットを受信することになりますが、FortiGate のデフォルトの設定ではセッションテーブルに存在しない応答パケットは非対称ルーティングと判断されてドロップされます。

これが一つ目の原因です。
- FortiGate のデフォルトの設定ではセッションテーブルに存在しない応答パケットは、非対称ルーティングと判断されてドロップされる
事象の検知方法
この原因でパケットがドロップされた場合、トラフィックログ等には何も出力されません。
事象を検知するためにはリアルタイムにフローのデバッグを行う必要があります。
例えば以下のようにデバッグの設定をした上でデバッグを行います。
diagnose debug console timestamp enable
diagnose debug flow filter daddr 10.1.1.100
diagnose debug flow trace start 1000
diagnose debug enable
事象発生時には以下のようなログが表示されます。
2023-08-17 11:47:13 id=65308 trace_id=94 func=print_pkt_detail line=5899 msg="vd-root:0 received a packet(proto=6, 192.168.10.1:23->10.1.1.100:44692) tun_id=0.0.0.0 from internal1. flag [S.], seq 3181926688, ack 216298944, win 4128"
2023-08-17 11:47:13 id=65308 trace_id=94 func=vf_ip_route_input_common line=2606 msg="find a route: flag=00000000 gw-192.168.30.254 via wan1"
2023-08-17 11:47:13 id=65308 trace_id=94 func=fw_forward_dirty_handler line=378 msg="no session matched"
msg=”no session matched” というメッセージを確認できます。
この原因によりブロックされた場合はこのログが出力されるようです。
回避策
以下の設定により、非対称ルーティングを有効としてパケットドロップされないようにすることもできますが、セキュリティレベルが低下するため非推奨とされています。切り分けのために一時的に設定する程度に留めておく方が良いでしょう。
config system settings
set asymroute enable
end
また tcp-session-without-syn
設定をすることにより、ポリシー個別に SYN チェックを無効にするという方法もありますが、この設定をするためには非対称ルーティングを有効化する必要があります。
いずれにしても根本的な解決には、非対称ルーティングが発生しないようにネットワーク設計を見直す必要があります。
原因② 送信元アドレスへの戻りルートが無いことによるドロップ
原因①で考えたネットワークと同じ構成に対して、FotiGate で 10.2.2.0/24 向けのルートを削除した構成を考えます。

このネットワークで端末Aから端末Bへ通信する場合、相変わらず以下の図のような経路になります。
- 行き経路: 端末A → ルータA → ルータB → 端末B
- 戻り経路: 端末B → ルータB → FotiGate → ルータA → 端末A

ここで、端末Bから FotiGate へのルートと、FotiGate から端末B へのルートを考えると以下図のようになります。

ここで注目するのは、FotiGate への入力インタフェースと、FotiGate からの出力インターフェースが異なっているという点です。
FotiGate には RPF (Reverse Path Forwarding) (またはアンチスプーフィングとも呼ばれている)という機能があり、これにより受信したパケットの送信元へのルートの出力インターフェースが入力インタフェースと異なっている(戻りのルートが無い)場合、パケットをドロップします。

これが二つ目の原因です。
- FortiGate のデフォルトの設定では、受信したパケットの送信元アドレスへの戻りルートが無い場合はパケットがドロップされる
事象の検知方法
この原因でパケットがドロップされた場合も、トラフィックログ等には何も出力されません。
事象を検知するためにはリアルタイムにフローのデバッグを行う必要があります。
例えば以下のようにデバッグの設定をした上でデバッグを行います。
diagnose debug console timestamp enable
diagnose debug flow filter daddr 10.1.1.100
diagnose debug flow trace start 1000
diagnose debug enable
すると以下のログが確認できます。
2023-08-17 11:28:27 id=65308 trace_id=1 func=print_pkt_detail line=5899 msg="vd-root:0 received a packet(proto=1, 192.168.10.1:4->10.1.1.100:0) tun_id=0.0.0.0 from internal1. type=0, code=0, id=4, seq=0."
2023-08-17 11:28:27 id=65308 trace_id=1 func=ip_route_input_slow line=2267 msg="reverse path check fail, drop"
2023-08-17 11:28:27 id=65308 trace_id=1 func=ip_session_handle_no_dst line=6159 msg="trace"
msg=”reverse path check fail, drop” というメッセージを確認できます。
このログから、RPF(アンチスプーフィング)機能によってドロップされていることが分かります。
回避策
RPF は、非対称ルーティングを有効化すると無効になります。よって、非対称ルーティングを有効化することで回避することが可能です。
config system settings
set asymroute enable
end
ただし上で記載した通り、非対称ルーティングを有効化することは推奨されないため、切り分けのために一時的に設定する程度に留めたほうが良いでしょう。
また、インターフェース毎に RPF を無効化することもできます。
config system interface
edit <interface>
set src-check disable
end
こちらの原因についても、根本的な解決には戻りルートが無い状況が発生しないようにルーティング設計を見直す必要があります。