境界防衛の深層:SGとNACLが織りなすパケットの「関所」を解剖する
クラウドインフラを設計する際、多くのエンジニアは「セキュリティグループ(SG)があるからNACLは不要」あるいは「とりあえず全開放」という甘い誘惑に駆られる。だが、本物のSREにとってネットワークは、カーネルのバッファからNIC、そして物理的な境界まで続く「パケットの旅路」そのものだ。
今回は、AWSを主戦場とするインフラアーキテクトが避けては通れない、ステートフルなSGとステートレスなNACLの「二重防衛」の真実を、パケットの挙動レベルから解き明かしていく。
—
1. パケットの通り道:処理順序という「物理的必然」
パケットがAWSのVPC境界を越え、サブネットに到達し、最終的にEC2インスタンス(あるいはENI)のNICへ届くまでのパスを想像してほしい。
1. Ingress NACL(サブネット境界): パケットはまずサブネットの入り口という「関所」でチェックされる。ここはステートレスだ。つまり、戻りパケットのために自動で許可ルールを作るような気の利いたことはしてくれない。
2. Ingress SG(インスタンス境界): 次にNIC直前でSGのチェックを受ける。ここはステートフル。一度接続が許可されれば、戻りのトラフィックはルールに関わらず通過できる。
3. Egress SG(インスタンス境界): 出ていくパケットのチェック。
4. Egress NACL(サブネット境界): 出ていくパケットに対するステートレスな最後の関所。
現場の教訓:なぜ「戻りパケット」で死ぬのか
最も多いトラブルは「NACLのEgressを忘れて通信が死ぬ」ことだ。SGの概念が染み付いていると、往路だけ許可すればいいと考えがちだが、NACLは往復それぞれに対して明示的な許可が必要だ。特にエフェメラルポート(1024-65535)を許可し忘れると、TCPのハンドシェイクすら完結せずにタイムアウトする。
—
2. ネットワークパフォーマンスの深淵:RTTとTCPチューニング
セキュリティ防御を重ねるということは、わずかながらもパケット処理のオーバーヘッドを生む可能性がある。しかし、真のボトルネックは往々にしてカーネルパラメータにある。
高トラフィックなマイクロサービスにおいて、NACLやSGを通過するパケットの遅延を最小化するには、TCPスタックの最適化が不可欠だ。例えば、以下のようなsysctlチューニングは、クラウド上のパケットバッファを最適化する定石である。
# /etc/sysctl.conf に追記し、大規模通信のバッファを拡張
# TCPの送受信バッファの最小値・デフォルト値・最大値を調整
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 高RTT環境でウィンドウサイズを拡張し、パイプラインを埋める
net.ipv4.tcp_window_scaling = 1
# TIME_WAIT状態のソケットを再利用し、ポート枯渇を防ぐ
net.ipv4.tcp_tw_reuse = 1
—
3. TLSハンドシェイクとヘッダー圧縮の最適化
インフラ層でパケットを制限するだけでなく、アプリケーション層の通信効率も考慮しなければならない。現代のWeb通信においては、TLS 1.3の採用が絶対条件だ。
- 0-RTTハンドシェイク: TLS 1.3では接続の再開時にRTTを削減できるが、リプレイ攻撃のリスクがある。これを許容するかどうかは、アプリケーションの冪等性設計とセットで議論すべきだ。
- HPACK/QPACK: HTTP/2以降、ヘッダー圧縮が標準化されている。インフラエンジニアとしては、ALBやNginx等のプロキシ層でこの圧縮率を最大化する設定を施し、パケットあたりの有効ペイロード比率を高めるべきだ。
—
4. トラブルシューティングの極意:パケットを「見る」技術
ネットワークの障害調査において、pingを打つだけのエンジニアで終わってはいけない。パケットがどこでドロップされたかを特定するには、VPCフローログとtcpdumpの合わせ技が必須だ。
もし通信が確立しない場合、以下の順序で追いかける。
1. VPCフローログの確認: REJECTされているパケットが、NACL由来かSG由来かを見極める(ただしフローログはパケットそのものではない点に注意)。
2. tcpdumpによるキャプチャ: インスタンス内で直接パケットの到達を確認する。
# 特定のポートへの通信が到達しているかを確認する
# eth0インターフェースでTCP 443のパケットを監視
sudo tcpdump -i eth0 port 443 -v -n
もしtcpdumpでパケットが見えるのにアプリケーションに応答がない場合、SGは突破しているが、カーネルレベルのiptablesやnftables、あるいはアプリケーションのバインド先IP(0.0.0.0か127.0.0.1か)を疑うのが、熟練のSREの直感だ。
—
終わりに:二重防御は「階層化」の哲学である
セキュリティグループは「IDベース(インスタンスの役割)」の防衛であり、NACLは「ネットワークトポロジーベース(サブネットの境界)」の防衛だ。この二つを使い分けることは、単なる冗長性ではない。
SGが誤って0.0.0.0/0に開放されたとしても、NACLという「最後の砦」が特定のCIDRしか通さない設計になっていれば、壊滅的なデータ流出は防げる。この「階層化された防御(Defense in Depth)」こそが、クラウド時代のエンジニアが持つべき矜持だ。
ネットワークは生き物だ。パケットの旅路を常に可視化し、カーネルの奥底で何が起きているかを想像できる力こそが、あなたのインフラを最強の要塞に変える鍵となる。
コメント