こんにちは😺
カスタマーサクセス部の山本です。
社内からの技術問い合わせで、解説していて有意義だったものがあったので、ブログ記事にします。
質問
AWS Network Firewall の「ストリーム例外ポリシー」において、「Continue」を選択するケースはあるでしょうか。
参考
公式ドキュメント:
ストリーム例外ポリシー
Stream exception policy in your firewall policy - AWS Network Firewall
2023/5 のニュース:
AWS Network Firewall がストリーム例外ポリシーにおける拒否アクションのサポートを開始
AWS Network Firewall がストリーム例外ポリシーにおける拒否アクションのサポートを開始
TCP のストリーム通信と再送制御、コネクション
TCP はコネクション型のプロトコルです。
クライアントのある一つのポートと、サーバーのある一つのポートを組み合わせて、コネクションを作ります。
コネクションの中では、セグメント化したデータの送受信を行います。ストリーム通信と言ったりします。一時的なネットワークの切断などで、データをロストした際はストリーム内で再送を行います。
再送は以下のように行います。
最初の送信:▶相手からの受信確認を受け取れない
1 回目の再送:最初の送信から 1 秒後▶相手からの受信確認を受け取れない
2 回目の再送:1 回目の再送から 2 秒後▶相手からの受信確認を受け取れない
3 回目の再送:2 回目の再送から 4 秒後▶相手からの受信確認を受け取れない
・・・
n 回目の再送で相手からの受信確認を受け取れれば正常に再送できています。
しかし、指定回数に達するとタイムアウトとなります。
再送のタイムアウトは OS やアプリケーション毎に設定できます。
タイムアウトした場合にはコネクションは切断されます。
もう一度通信したい場合は、新しくコネクションを作ります。
AWS Network Firewall の 「ストリーム例外ポリシー」
AWS Network Firewall の 「ストリーム例外ポリシー」では、クライアントとサーバーがTCPコネクションを貼ってストリーム通信をしている際に、中間のネットワークで一時的な切断があった際の動作を定義します。
クライアントとサーバーの間で通信を検疫している Network Firewall が、ネットワーク内で一時的な切断があったときに、実行中のストリーム通信にどう関与するかです。
AWS Network Firewall でステートフルルールを適用している際には、TCP ストリームの通信の流れをファイアーウォール内にコンテキストとして保存しています。コンテキストを参照して、ストリーム内の前後のセッション情報を確認し、検閲するパケットが正常なものか判定しています。
ネットワーク内で一時的な切断があったときには、AWS Network Firewall がコンテキスト情報を失っている可能性があります。コンテキストが失われると、切断からの回復時にストリーム通信が再開した場合にも、正しくルールを適用できないことになります。
ステートフルルールを正しく動作させるには、ストリーム通信をしているコネクション自体をクローズしてしまって、切断からの回復時に新しくコネクションを作るしかないようです。新しいコネクションを作って、新しいコンテキストを保持させるということです。
「ストリーム例外ポリシー」は、Drop
、Reject
、Continue
から選びます。
Drop
では、ネットワーク内で一時的な切断があったときに、クライアントとサーバーの間で通信を検疫している Network Firewall が、ストリーム通信のデータをドロップします。ドロップさせることで TCP の再送を失敗させ、タイムアウトさせます。
タイムアウトした場合にはコネクションは切断となるため、必要に応じて新規コネクションを作成する必要があります。新規コネクションを作成した際には、AWS Network Firewall がコンテキストを完全に保持できるため、正しくルールを適用できるようになります。デフォルトはこの Drop
です。
Reject
を選ぶ場合にも、データをドロップします。加えて、クライアントとサーバーに TCP RESET を送信します。TCP RESET を送信すると、通信はすぐに切断されるため、 drop とは異なり再送タイムアウトを待つ必要はなくなります。ただし、TCP RESET は強制切断なので、アプリケーションとしては意図しない動作をすることがあります。コネクションは切断となるため、必要に応じて新規コネクションを作成する必要があります。新規コネクションを作成した際には、AWS Network Firewall がコンテキストを完全に保持できるため、正しくルールを適用できるようになります。
Continue
を選ぶと、AWS Network Firewall は通常と同様にデータを処理し続けます。drop はさせないので、ネットワークの回復時には再送処理が成功する可能性があります。しかし、AWS Network Firewall がコンテキスト情報を失っている可能性があります。コンテキストが失われると、切断からの回復時にストリーム通信が再開した場合にも、正しくルールを適用できないことになります。
従いまして、要件に応じてDrop
、Reject
、Continue
から選ぶことになります。
- 「ネットワークの一時的な切断が起きた際にコネクションが切断になることは許容する。セキュリティが優先で、ネットワークの回復時にはステートフルルールには完璧なコンテキストを持たせて処理させたい。」▶
Drop
- 「ネットワークの一時的な切断が起きた際にコネクションが切断になることは許容する。セキュリティが優先で、ネットワークの回復時にはステートフルルールには完璧なコンテキストを持たせて処理させたい。タイムアウトしないためコネクションが残ってしまうアプリケーションがあり、Network Firewall で切断したい。」▶
Reject
- 「ネットワークの一時的な切断が起きた際にコネクションが切断になることは問題になる。切断後にコネクションを作り直すのでは処理が間に合わない。可能な限り再送処理したい。」▶
Continue
データベースのコネクションプーリングする場合( Keep alive 。同じコネクションを使い回して効率的に通信する)と、しない場合( アプリからの呼び出しごとに DB 接続/切断)で考えてみると分かりやすいかもしれません。
- 「ネットワークの切断時にコネクションプーリングを貼り直すのは通常運用。Firewall に正しく動作してほしい。」▶
drop
- 「コネクションプーリングは切断しちゃうと貼り直す必要があって、可能な限り保持したい」▶
Continue
を視野に入れる - 「コネクションプーリングはしていないし、一回一回の DB 接続のタイムアウトも短い設定だから
drop
で問題ない」 - 「ネットワークの切断時にコネクションプーリングが切れて、タイムアウトまでに時間がかかる。Network Firewall から TCP RESET で切断したいから
Reject
」
Drop
と Reject
は Network Firewall のステートフルルールのコンテキスト保持を重要視するパラメータで、Continue
は Network Firewall よりも通信の持続性を重要視するパラメータです。
AWS Network Firewall の「ストリーム例外ポリシー」において、「Continue」を選択するケース
要件としては上に書いた以下になります。
「ネットワークの一時的な切断が起きた際にコネクションが切断になることは問題になる。切断後にコネクションを作り直すのでは処理が間に合わない。可能な限り再送処理したい。」
想像になるものの例として以下のシナリオを挙げます。( AD のレプリケーションの再送処理を完全に理解しているわけではないのはお許しください。)
シナリオ:「AD のサイト間レプリケーションが VPN の帯域不足で一時切断した際に、AWS Network Firewall がレプリケーション処理を中断させてしまう」
Active Directory (AD) を採用していて、複数のサイトがあります。オブジェクトの更新が多く、レプリケーションには 2 時間かかります。そのため、サイト間レプリケーションの間隔はデフォルトの 3 時間のままにしています。タイムアウト= 3時間ということです。 オンプレAD と AWS 上の AD で VPN 回線を経由してレプリケーションをしています。VPN の通信を AWS Network Firewall で検閲しています。VPN は帯域が十分でなく、多数のユーザーの使用によって、一時的な通信障害が2-3 時間おきに発生しています。AWS Network Firewall の 「ストリーム例外ポリシー」はデフォルトの drop
です。一時的な通信断により、Network Firewall が レプリケーションのパケットを drop し、レプリケーション処理は 3 時間後にタイムアウトとなります。レプリケーションの失敗した後には、新しく AD に追加したユーザーが、他のサイトのサーバーにログインできないことがあります。これにより、業務上の支障が出ます。タイムアウトした時間に次のレプリケーションが再開しているものの、更新オブジェクトが多く、1時間後にVPNの一時的な通信断が発生し、レプリケーション処理は次の 3 時間後にタイムアウトとなります。
レプリケーションが失敗しないことの重要度が高いため、AWS Network Firewall の「ストリーム例外ポリシー」において、Continue
を選択しました。
次のレプリケーションからは、ネットワークの一時的な切断時にも、AD のレプリケーション処理が drop されず、回復時には再送処理が続行し、無事にレプリケーションが終わりました。
弊害としては、ネットワークの一時的な切断時に、Network Firewall のステートフルルールがコンテキストを保持できないため、検閲が不完全になることです。
レプリケーションが失敗しているのは VPN の帯域が十分でないことなので、専用線や、帯域の追加を検討することにしました。
VPN の帯域を確保できた際には、AWS Network Firewall の「ストリーム例外ポリシー」を drop
に戻し、完璧なコンテキストでステートフルルールでの検閲を行う予定です。
終わり。
補足
本記事では図を一切書かなかったので、TCP のストリーム通信について、イメージが持ちにくかったかも知れません。
「TCPの再送制御」などと検索してもらえますと、イメージが持てるかと思います。
無料で見れる資料では、電子情報通信学会『知識の森』
にある資料が分かりやすかったです。
1 章 TCP(Transmission Control Protocol)の基礎
雑談
同僚と山登りに行ってきました。
サムネ用にも写真を載せます。
本栖湖(山梨県)の横にある竜ヶ岳という山で、雲がなければ富士山が綺麗です。
雲さえなければ。
山本 哲也 (記事一覧)
カスタマーサクセス部のエンジニア。2024 Japan AWS Top Engineers に選んでもらいました。
今年の目標は Advanced Networking – Specialty と Machine Learning - Specialty を取得することです。
山を走るのが趣味です。今年の目標は 100 km と 100 mile を完走することです。 100 km は Gran Trail みなかみで完走しました。残すは OSJ koumi 100 で 100 mile 走ります。実際には 175 km らしいです。「草 100 km / mile」 もたまに企画します。
基本的にのんびりした性格です。座右の銘は「いつか着く」