NACLは「無慈悲な門番」である:ステートレスが突きつけるネットワーク設計の真髄
クラウドアーキテクトやSREとして現場に立つと、セキュリティグループ(SG)とネットワークアクセスコントロールリスト(NACL)のどちらで制御すべきかという議論に出くわす。多くのエンジニアは「SGはステートフルで楽、NACLはステートレスで面倒」という表層的な理解で止まっている。
だが、パケットがVPCの境界を跨ぎ、サブネットの出口でNACLという名の「無慈悲な門番」に突き当たるとき、そこで何が起きているのか。今回は、単なるフィルタリングルールを超えた、パフォーマンスとセキュリティの深淵について語ろう。
—
ステートレスなNACLの挙動:記憶なき門番と対峙する
NACLがステートフルなSGと決定的に違うのは、パケットの状態(SYN/ACKといったTCPフラグやセッションの継続性)を一切記憶しない点だ。
SGは「一度許可した通信の戻りは自動的に通す」という親切な設計だが、NACLは違う。パケットが来るたびに、ルールリストの番号(Rule Number)を上から順に舐め、一致した瞬間にアクション(Allow/Deny)を即断する。
なぜこれが設計を歪めるのか?
例えば、Webサーバが 80/443 ポートでリクエストを受け付ける場合、NACLには以下の設定が必要になる。
- インバウンド: クライアントからのリクエスト(
1024-65535番ポートから80/443への流入) - アウトバウンド: サーバからのレスポンス(
80/443から1024-65535への流出)
ここでエフェメラルポート(一時的なポート)の範囲を考慮し損ねると、TCPの3ウェイハンドシェイクすら完結しない。特に、AWSなどのクラウド環境で 1024-65535 を全開放することに恐怖を感じるかもしれないが、これはNACLの仕様上、避けては通れない「コスト」だ。
—
パフォーマンスの極致:TLSハンドシェイクとRTTの削減
ネットワークの遅延(RTT)を削ることは、現代のSREにとって至上命令だ。NACLのルール数が数百に膨れ上がると、パケットごとの評価コストが無視できないレベルになるのか? と問われれば、クラウドベンダーの物理インフラ層ではハードウェア的に高速化されているとはいえ、設計としては「ルール数は最小化すべき」というのが鉄則だ。
特に、TLS 1.3 を導入している場合、ハンドシェイクの往復回数は削減されている。この貴重なRTTをNACLの複雑な評価で浪費してはならない。
トラブルシューティング:MTUとパケット断片化の罠
NACL設計で最も多い失敗は、Path MTU Discovery (PMTUD) を阻害することだ。
# PMTUDを機能させるためのNACL設定指針
# インバウンド/アウトバウンド双方でICMP Type 3, Code 4 (Fragmentation Needed) を許可する
# これを忘れると、特定のパケットサイズを超えた瞬間にコネクションがハングする
もし、特定のAPIリクエストだけがタイムアウトするなら、それはNACLが ICMP の「到達不能」メッセージをブロックし、MTUのネゴシエーションを殺している可能性が高い。これはパケットキャプチャでも特定しにくい、現場のSREを泣かせる典型的な罠だ。
—
カーネルレベルのチューニング:TCPバッファとNACLの共存
NACLを通過するトラフィックを最大化するためには、OS側のTCPスタックも最適化しておく必要がある。特に高負荷なマイクロサービス間通信では、カーネルのバッファがボトルネックになる。
以下は、スループットを最大化するためのLinuxカーネルパラメータの最適化例だ。
# /etc/sysctl.conf への追記例
# TCP受信ウィンドウの拡大
net.ipv4.tcp_rmem = 4096 87380 16777216
# TCP送信バッファの拡大
net.ipv4.tcp_wmem = 4096 65536 16777216
# 高速な接続切断後の再利用
net.ipv4.tcp_tw_reuse = 1
これらの設定はパケットの「流れ」をスムーズにするが、NACLが適切にエフェメラルポートを許可していない場合、tcp_tw_reuse が有効でもポート枯渇を起こし、サービスは沈黙する。NACLの静的な設定と、OSの動的な挙動を同期させる意識が必要だ。
—
結論:NACLは「設計の美学」である
NACLを単なる「拒否リスト」として扱うのはもったいない。これは、VPCという巨大なネットワーク空間における最後の防波堤であり、同時にパケットフローを強制的に可視化するツールでもある。
- ルール番号は100単位で空けておく: 後から緊急パッチを割り込ませる余地を作る。
- ログを吐かせる: VPC Flow Logsを有効化し、NACLで拒否されたパケットを定期的に分析する。
- 過剰な設計を避ける: ステートレスであることを理解し、SGで制御できるものはSGに任せる。
ネットワークエンジニアリングとは、結局のところ「パケットの旅をどれだけ正確に予測し、障害を排除できるか」という技術的想像力の勝負だ。NACLという無慈悲な門番を味方につけ、堅牢で低遅延なアーキテクチャを築き上げてほしい。
それが、私たちの仕事だ。
コメント