検証環境
- FortiGate-60E
- version v7.2.3
非対称ルーティングとは
非対称ルーティングとは、ある送信元と宛先間の通信において「送信元から宛先への行きの経路」と「宛先から送信元への戻りの経路」が異なるようなルーティングがなされることを指します。
例えば、以下のネットワークを考えます。

ルータBのデフォルトルートは FortiGate を向いていて、FortiGate のデフォルトルートはルータAを向いています。その他のスタティックルートや NAT は設定されていません。
この時、端末からルータBのアドレス 192.168.10.1 宛に通信を行った場合、行きの経路と戻りの経路は以下図のようになります。

- 行きの経路: 端末 → ルータA → ルータB
- 戻りの経路: ルータB → FortiGate → ルータA → 端末
上記の通り、行きと戻りで経路が異なります。これは非対称ルーティングの一例です。
ここで、上記の例では端末からルータBのアドレス 192.168.10.1 宛に通信を行った際に FortiGate を通るのは戻りの通信のみとなります。
このような、[行き/戻り]の通信のうち片方向の通信のみが FortiGate を通る場合について特に注意が必要です。
FortiGate では非対称ルーティングに対してデフォルトでブロック
FortiGate のデフォルトの設定では、FortiGate がセッションテーブルに存在しない応答パケットを受信した場合、そのパケットは非対称ルーティングによるものと判断されてブロックされます。
※ファイアウォールポリシーのチェック以前の段階でブロックされます
非対称ルーティングに対して許可するよう設定することも可能
以下のように config system settings
の asymroute
を enable
とすることで、非対称ルーティングとなるパケットを許可することが可能です。デフォルトでは disable
です。
config system settings
set asymroute enable
end
ただし、非対称ルーティングを有効にすることはセキュリティレベルを著しく低下させることになる点を考慮してください。
非対称ルーティングを有効とした場合の FortiGate の動作
非対称ルーティングを有効とした場合の FortiGate の動作は以下のようになります。
※参考: https://community.fortinet.com/t5/FortiGate/Technical-Note-How-the-FortiGate-behaves-when-asymmetric-routing/ta-p/198575?externalID=FD39943
◆TCP パケットの場合
- パケットが SYN の場合
- 非対称ルーティングが無効の場合と全く同じ次の動作
- セッションを作成し、ファイアウォールポリシーをチェックし、一致するポリシーの設定 (UTM インスペクション、NAT、トラフィック シェーピングなど) を適用する
- 非対称ルーティングが無効の場合と全く同じ次の動作
- パケットが SYN ではなく、セッションがファイアウォール上にすでに存在する場合
- 非対称ルーティングが無効の場合と全く同じ動作
- FortiGate はトラフィックを通過させる
- 非対称ルーティングが無効の場合と全く同じ動作
- パケットが SYN でなく、セッションが存在しない場合 (非対称ルーティング)
- すべてのパケットは CPU に渡され、FortiGate は一致するファイアウォールポリシーを検索しない
- パケットはルーティングテーブルに基づいて単純に転送される
- FortiGate はルーティングの決定のみを行うルーターとして機能する
上記の通り、パケットが SYN ではなくセッションが存在しない場合はファイアウォール機能を持たない単純なルータとして動作するため、セキュリティレベルが低下します。
◆ICMP パケットの場合
ICMP パケットの場合の動作は TCP パケットの場合と同じです。
- パケットがリクエストの場合
- 非対称ルーティングが無効の場合と全く同じ動作
- パケットがリクエストではなく、セッションが存在しない場合 (非対称ルーティング)
- ICMP 応答はセキュリティ検査なしで単純にルーティングされる
◆UDP パケットの場合
- パケットは非対称ルーティングに関係なくセッションテーブルによってチェックされる
- 非対称ルーティングは UDP パケットには影響しない
- UDP を許可するには、それを許可するポリシーが必要
非対称ルーティング有効化が推奨されない理由
上に記載している通り、非対称ルーティング時に TCP パケットと ICMP パケットに対してファイアウォールポリシーやセキュリティプロファイルが適用されることなく単にルーティングされてしまう点がセキュリティ上の懸念点になります。この点から非対称ルーティング有効化は非推奨とされています。
非対称ルーティングの動作検証
最初に掲載した以下のネットワークで FortiGate の動作を検証してみます。

戻りの通信のみが FortiGate を通過するパターン
以下の設定とします。
- ルータBのデフォルトルートは FortiGate を向いている
- FortiGate のデフォルトルートはルータAを向いている
- その他スタティックルートや NAT の設定は無し

端末からルータBのアドレス 192.168.10.1 宛に通信する場合を考えます。

FortiGate の設定として
- 非対称ルーティングの[有効/無効]の 2 パターン
- ルータBから端末への戻りの通信を許可するポリシーの設定[有/無]の 2 パターン
- ポリシーは[送信元/宛先/サービス]すべてを ALL とする
の合計 4 パターンを用意し、各パターンで端末からルータBへ Ping(ICMP) と Telnet(TCP) 通信を試してみました。
その結果は以下表の通りです。
# | 非対称ルーティング | 許可ポリシー | Ping | Telnet |
1 | disable | 設定無し | NG | NG |
2 | disable | 設定有り | NG | NG |
3 | enable | 設定無し | OK | OK |
4 | enable | 設定有り | OK | OK |
上記表の通り、Ping/Telnet の OK/NG は非対称ルーティングの設定に依存し、許可ポリシーは関係ないことが分かります。
ちなみに非対称ルーティングが disable 時に FortiGate で internal1 をパケットキャプチャするとルータBからの戻りのパケットを着信まではできていることが分かります。

またトラフィックログに拒否ログが無いかを探してみても拒否ログは特に何も出ません。非対称ルーティング disable によりブロックされたことは特にトラフィックログやその他ログには出力されません。
【追記】RPF (Reverse Path Forwarding) (アンチスプーフィング)
上記の動作は当初非対称ルーティングによるブロックと考えていたのですが、RPF (Reverse Path Forwarding) (またはアンチスプーフィングとも呼ばれている)機能によるものであるようです。
非対称ルーティングを有効にした場合、RPF を無効にできるようです。そのため、非対称ルーティングを有効にした場合はパケットがドロップされずに通信ができたという訳です。
※参考:https://community.fortinet.com/t5/FortiGate/Technical-Note-Details-about-FortiOS-RPF-Reverse-Path-Forwarding/ta-p/190100
上記の検証構成において、FotiGate で以下コマンドを使用して debug ログを見てみます。
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(アンチスプーフィング)機能によってドロップされていることが分かります。
従って上記検証では正確には非対称ルーティングの検証をできていませんでした。
そこで、以下のように FotiGate に 192.168.10.1 宛のスタティックルートを追加して RFP の問題を解消した上で再度検証してみます。

上記の検証構成において、FotiGate で以下コマンドを使用して debug ログを見てみます。
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” というメッセージを確認できます。
非対称ルーティングによりブロックされた場合はこのログが出力されるようです。
また非対称ルーティングを有効化した場合、パケットはブロックされずに通信できたことを確認しています。
行きの通信のみが FortiGate を通過するパターン
以下の設定とします。
- ルータAのデフォルトルートは FortiGate を向いている
- ルータBのデフォルトルートはルータAを向いている
- FortiGate のデフォルトルートはルータBを向いている
- その他スタティックルートや NAT の設定は無し

端末からルータBのアドレス 192.168.20.254 宛に通信する場合を考えます。

FortiGate の設定として
- 非対称ルーティングの[有効/無効]の 2 パターン
- 端末からルータBへの行きの通信を許可するポリシーの設定[有/無]の 2 パターン
- ポリシーは[送信元/宛先/サービス]すべてを ALL とする
の合計 4 パターンを用意し、各パターンで端末からルータBへ Ping(ICMP) と Telnet(TCP) 通信を試してみました。
その結果は以下表の通りです。
# | 非対称ルーティング | 許可ポリシー | Ping | Telnet |
1 | disable | 設定無し | NG | NG |
2 | disable | 設定有り | NG | NG |
3 | enable | 設定無し | NG | NG |
4 | enable | 設定有り | OK | OK |
上記の結果は少し意外でした。というのも、非対称ルーティングが disable の場合でも許可ポリシーがあれば FortiGate は通過できると考えていましたが通過できなかったためです。
行きの通信のみが FortiGate を通る場合は非対称ルーティングを enable にすることと許可ポリシーの両方が必要ということでしょうか。
ここで以下の疑問があります。
- FortiGate に行き通信のパケットが着信した時点で、非対称ルーティングの場合と、そうでない場合をどう区別しているのか?
少し考えて以下の仮説を思いつきました。
- FortiGate に送信元 IP アドレスへのルートが無い場合は戻りのルートが無いことから非対称ルーティングと判定されているのではないか
そこで、FortiGate のスタティックルート設定について以下の 2 パターンで検証を行いました。
① 端末アドレスへのスタティックルートを追加

② デフォルトルートをルータA向けに変更

上記 2 パターンにて検証を行ったところ、端末からルータBの 192.168.20.254 に対して Ping/Telnet の結果は以下表の通りでした。
# | 非対称ルーティング | 許可ポリシー | Ping | Telnet |
パターン① | disable | 設定有り | OK | NG |
パターン① | enable | 設定有り | OK | OK |
パターン② | disable | 設定有り | OK | NG |
パターン② | enable | 設定有り | OK | OK |
上記結果から以下が推測されます。
- 送信元 IP アドレスへのルートが存在しない場合、非対称ルーティングと判定されブロックされる
- ルート有無の判定基準としては次の通り
- 送信元 IP アドレスを含むセグメントを宛先とし、かつ出力インターフェースが送信元からのパケットを着信したインターフェースと同一であるルートが存在するかどうか
また、非対称ルーティングが disable のときに Ping は OK で Telnet が NG になっていることついては、3ウェイハンドシェイクの 3 STEP 目である送信元からの SYN=0,ACK=1 の通信が非対称ルーティングと判定されてブロックされているからと考えられます。
更に調査したところ、上記の動作は非対称ルーティングというよりは、RPF (Reverse Path Forwarding) (またはアンチスプーフィングとも呼ばれている)機能によるものであるようです。
非対称ルーティングを有効にした場合、RPF を無効にできるようです。
※参考:https://community.fortinet.com/t5/FortiGate/Technical-Note-Details-about-FortiOS-RPF-Reverse-Path-Forwarding/ta-p/190100
FotiGate 宛の通信で入力 IF と出力 IF が異なるパターン
以下の構成で、端末から FotiGate の internal1 宛に通信する場合を考えます。

- FotiGate でポリシーとして、internal1(192.168.30.1)からwan1(端末IP)への通信を許可するポリシーを設定しておきます
この場合でも FotiGate で対象通信のパケットは破棄されてしまいます。
以下コマンドを使用して FotiGate で debug ログを見てみます。
diagnose debug console timestamp enable
diagnose debug flow filter saddr 10.1.1.100
diagnose debug flow trace start 1000
diagnose debug enable
端末から FotiGate へ Ping をすると以下のログを確認できます。
2023-08-17 10:21:40 id=65308 trace_id=5 func=print_pkt_detail line=5899 msg="vd-root:0 received a packet(proto=1, 10.1.1.100:10->192.168.20.1:2048) tun_id=0.0.0.0 from internal1. type=8, code=0, id=10, seq=0."
2023-08-17 10:21:40 id=65308 trace_id=5 func=init_ip_session_common line=6073 msg="allocate a new session-00002d15, tun_id=0.0.0.0"
2023-08-17 10:21:40 id=65308 trace_id=5 func=ip_route_input_slow line=2267 msg="reverse path check fail, drop"
2023-08-17 10:21:40 id=65308 trace_id=5 func=ip_session_handle_no_dst line=6159 msg="trace"
msg=”reverse path check fail, drop” というメッセージを確認できます。
このログから、RPF(アンチスプーフィング)機能によってドロップされていることが分かります。
上の方で記載している通り、非対称ルーティングを有効化することで RPF を無効化できるため、非対称ルーティングを有効化するとパケットはドロップされずに通信が可能となります。(ただし、非対称ルーティングを有効化は非推奨)
tcp-session-without-syn 設定について
以下の Fortinet コミュニティページには tcp-session-without-syn
を設定することで、SYN パケットが無くてもセッションを作成できる(SYN の無い戻りパケットを許可できる)と説明があります。
- Technical Tip: Use case of ‘tcp-session-without-syn’ in firewall policy
- Technical Note: Enable creation of TCP session on the firewall without checking for a SYN packet
上記ページの説明によるとまず、以下の設定を行い、グローバルに tcp-session-without-syn
を有効にします。
config system settings
set tcp-session-without-syn enable
end
次に、個別のポリシーで tcp-session-without-syn
を有効化します。
config firewall policy
edit N
set tcp-session-without-syn <all/data-only/disable>
next
end
all Enable TCP session without SYN.
data-only Enable TCP session data only.
disable Disable TCP session without SYN.
非対称ルーティングでの応答パケットのブロックの回避策として tcp-session-without-syn
を使用する場合は、戻りの通信を許可するようなポリシーを設定し、tcp-session-without-syn
を有効化する必要があります。このとき、戻り通信の宛先サービスポートはランダムなポートになるであろう点に注意してください。
tcp-session-without-syn を使用する条件
tcp-session-without-syn の動作検証も行ってみましたが、最初は tcp-session-without-syn を戻り通信許可ポリシーに対して設定しても戻りの通信はブロックされており、tcp-session-without-syn が機能していないように見えました。
その後色々試した結果、非対称ルーティング(asymroute)を有効にした上で tcp-session-without-syn を設定したところ以下の動作を確認しました。
config system setting
にてasymroute
とtcp-session-without-syn
の両方をenable
にした場合、(非対称ルーティングによる)セッションに存在しない戻り通信に対して以下の動作になった- 対象通信を許可するポリシーが無い場合、暗黙の拒否ポリシーで拒否された旨のログが表示された
- 対象通信を許可するポリシーがあっても、そのポリシーで
tcp-session-without-syn
が有効化されていない場合は、当該ポリシーに該当するも拒否された旨のログが表示された - 対象通信を許可するポリシーを設定し、かつ
tcp-session-without-syn
を有効化した場合、当該通信は当該ポリシーにヒットし、かつ FortiGate を通過できた
上記結果から、tcp-session-without-syn は非対称ルーティング機能(asymroute)を有効化していることを前提に使用する機能であると推測されます。
Web 上で見つけることができる tcp-session-without-syn に関する説明には非対称ルーティングを有効にする必要があることの説明が無いのが気にはなるため、実際に案件でこの機能を使用する場合には事前検証、及び可能であればサポートへの確認を行うことを推奨します。
まとめ
- 非対称ルーティングによって、[行き/戻り] のどちらか片方の通信のみが FortiGate を通ることになるようなネットワーク設計は避けましょう
- どうしても FortiGate で非対称ルーティングを有効化する場合は、FortiGate の動作とセキュリティ上のリスクを考慮しましょう
- ポリシー個別に SYN チェックを無効化する tcp-session-without-syn という設定がありますが動作仕様が明確ではないため、事前検証及びサポートへの確認を推奨します
- パケット送信元アドレスへの戻りルートが存在しない場合、非対称ルーティングとは別に RPF(Reverse Path Forwarding)(アンチスプーフィング)によりパケットがドロップされる