Fortigateなどの一般的なファイアウォールは、ステートフルインスペクションという方式でパケット通過の可否を判断しています。 この記事ではステートフルインスペクションの概要とその機能に伴い通信エラーが発生するような場面とチューニング設定(サービスタイムアウト設定、SYNチェック無効化、非対称ルーティング、アンチリプレイ)を確認していきます。
ステートフルインスペクションの概要
ステートフルインスペクションでは、通信パケットの中身を識別し、通信をセッションという形で管理した上に、戻りパケットのポートを動的に開放したりします。
例えば、端末からインターネットへの通信のみファイアウォールで許可していることを前提とし、 一例として端末(192.168.1.1)からインターネットのサーバ(1.1.1.1)へのアクセスを図にしてみます。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/35C21D17-68A5-49AF-A8ED-B8A2F73E8827.png)
端末(192.168.1.1)が、インターネットのサーバ(1.1.1.1)へのHTTPS(TCP443)をFortigateが受信すると、それをセッションテーブルに記録します。
なぜ、セッションテーブルを保持するかというと、それは戻り通信を許可させるためです。戻り通信は、セッションテーブルを見て、通信を許可させます。
セッションテーブルの更新
セッションの追加
通信がセッションテーブルに記録される条件ですが、まず大前提として、ファイアウォールポリシーで該当通信を許可しておく必要があります。 その上で、例えば、TCPの場合は、TCP接続を開始するフラグ(TCP SYN)のパケットを契機に、セッションテーブルに該当通信を記録します。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/85C648C8-EDF7-426D-8590-E778D6EC1757.png)
セッションの消去
セッションテーブルは限られたメモリ上で保持されるため、不要になると、消去する必要があります。一般的な消去する仕組みは、 例えば、TCPの場合は、フラグの内容を見て、TCP 終了処理(FINなど)が完了すると、セッションが終了したと判断し、セッションテーブルから該当セッションを消去します。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/B4FFD831-75B8-44C6-B92D-5037D7AB8C56.png)
上記のようなTCPセッションの終了が判断できない場合、一定の無通信(アイドル)時間を超えると、セッションを自動的に破棄します。 Fortigateの場合、デフォルトのセッションタイムアウト値は以下の通りです。セッション生成後、以下の時間、当該セッションが無通信の場合はセッションテーブルから破棄されます。
- TCP :3,600秒
- UDP : 180秒
- ICMP : 60秒
![](https://hirotanoblog.com/wp-content/uploads/2021/01/72489CF2-CA3F-4735-8064-75001B6B5AF9.png)
ステートフルインスペクションのために、システムによっては、稀に通信エラーなどの問題になる場合があります。
セッションタイムアウト問題
起こり得る事象
端末やサーバではTCPセッションを保持しているにも関わらず、ファイアウォール側でセッションテーブルが破棄されている場合に通信エラーになる場合があります。
例えば、端末やサーバがFortigateで設定しているセッションタイムアウト値を超えて、無通信のままセッションを保持するパターンです。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/B2144720-3BAA-4F13-AA44-C2D9213EB266.png)
端末からは既存セッションの通信を継続しているため、TCP SYNパケットでありません。そのため、セッションテーブルは記録されず、ファイアウォールポリシーは許可しているにも関わらず、通信は破棄されます。
この問題を対策するいくつかの方法を確認します。
サービスタイムアウトの変更
通信の特性に合わせて、サービスタイムアウト時間を変更します。朝に端末を立ち上げ、TCPセッションを確立したら、業務時間中はずっと、そのセッションを使用し続けるような通信特性の場合、例えば、1日の業務時間である8時間(28800秒)に変更してみます。
サービスタイムアウトは、サービスオブジェクト単位で設定します。
以下の例では、カスタムでOracle用のTCPポート1521番を作成し、サービスタイムアウトを変更します。
ポリシー&オブジェクト >> サービス に移動し、以下の通り、カスタムサービスを作成します。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/A677E147-3885-4537-BF41-01F5868F1180.png)
サービスタイムアウトはCLIにて変更します。以下の通り、set session-ttlコマンドにより、タイムアウト値を変更します。
FortiGate # config firewall service custom FortiGate (custom) # edit "Oracle-DB" FortiGate (Oracle-DB) # set session-ttl 28800 FortiGate (Oracle-DB) # end FortiGate # config firewall service custom FortiGate (custom) # show config firewall service custom ・ ・ ・ edit "Oracle-DB" set tcp-portrange 1521 set session-ttl 28800 next end
SYNチェック無効化
サービスタイムアウト値を特定できないTCP通信の場合、TCP SYN以外でもセッションテーブルの記録するよう変更することができます。(これは、セキュリティ上は推奨されません。)
これにより、セッションテーブルが破棄された後でも、既存セッションを継続することができます。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/1D6C81B0-0B21-412C-9C8F-A1BC700A936D.png)
デフォルトではGUI上でポリシー上のSYNチェックは設定できないため、、ポリシーの詳細設定ができるよう、GUIの表示機能設定を変更します。 システム >> 表示機能設定 で ポリシーの詳細オプション を有効にし、適用をクリックします。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/4D2F6F41-1FF1-4E05-A68C-7F17BCE1B81C.png)
ポリシー&オブジェクト >> ファイアウォールポリシー へ移動し、任意のポリシーを開くと、高度な設定 の表示が追加されていることを確認します。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/8A13EEDA-3E71-4E2A-988D-E76651236CB1.png)
CLIにて、tcp-session-without-syn コマンドにより設定します。
FortiGate # config system settings
FortiGate (settings) # set tcp-session-without-syn
enable Allow TCP session without SYN flags.
disable Do not allow TCP session without SYN flags.
FortiGate (settings) # set tcp-session-without-syn enable
FortiGate (settings) # end
再度、ポリシーの高度な設定を確認すると、SYNなしのTCPセッションを許可という項目が増えているので、これを有効にします。これで、該当ポリシーを通過する通信はSYNチェックが無効化されます。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/812D1A92-103C-4993-A5E8-CE1C65A98F10.png)
非対称ルーティング (asymroute)
上の2つの例は、セッションタイムアウト経過後、端末から既存セッションを継続させる場合に有効な対策です。ただし、サーバから既存セッションを継続させるような場合は、ファイアウォールポリシーによりドロップされます。
![](https://hirotanoblog.com/wp-content/uploads/2021/01/1C8CD073-78FB-47B0-8387-D0561101F3B7.png)
このような通信破棄の場合、非対称ルーティング(asymroute)を有効にすると回避できます。TCPの場合、TCP SYNではなく、かつセッションテーブルに載っていない通信は、ファイアウォールポリシーによりチェックを行わず、ルーティングされます。(これは、セキュリティ上は推奨されません。)
FortiGate # config system settings
FortiGate (settings) # set asymroute enable
FortiGate (settings) # end
TCP シーケンス問題
デフォルトでFortigateでは、TCPシーケンスチェックを使用して、範囲の外れたシーケンス番号でパケットを受信すると、パケットを破棄します。この動きにより、アプリケーションの通信挙動によって、TCPのシーケンスが不正とみなされ、ファイアウォールでパケットが破棄される場合が稀にあります。この場合、anti-replayを無効化(デフォルトはstrict)することで、事象が解消することがあります。(これは、セキュリティ上は推奨されません。)
FortiGate # config system global
FortiGate (global) # set anti-replay
disable Disable anti-replay check.
loose Loose anti-replay check.
strict Strict anti-replay check.
FortiGate (global) # set anti-replay disable
FortiGate (global) # end
以上、ファイアウォールポリシーでは該当通信は許可されているのに、なぜか通信が切断される、通信できないなどが発生した場合は、上記の観点で確認してみてはいかがでしょうか。
コメント