【テクニカル・上級編】 インターネットゲートウェイ(IGW)におけるTCP MSSクランプとMTU管理 – クラウドインフラと仮想化ネットワーク実践ガイド

AWSネットワークの深淵:MTU、MSS、そして「消えたパケット」の真実

インフラエンジニアとして現場に長くいると、OSのカーネルチューニングやコンテナのオーケストレーションには血眼になる一方で、「L3/L4の境界線」で起きている静かな闘争を見過ごしているケースによく遭遇する。

AWS VPC内では、インスタンス間通信で 9001 バイトのジャンボフレームが許可されている。だが、一度パケットがインターネットゲートウェイ(IGW)を跨ぎ、広大なインターネットという「1500バイトの壁」が支配する領域へと飛び出す瞬間、そこには悲劇的なまでの不整合が待ち受けている。

今回は、このMTUとMSSの齟齬が引き起こすネットワークの「見えない詰まり」と、それをアーキテクチャレベルでどう制御すべきか、という話をしよう。

1. なぜ「フラグメンテーション」は悪なのか

AWSのVPC内で MTU 9001 を活用しているアーキテクチャにおいて、インターネット向け通信をそのまま放置すると、IGW(あるいはその先の中継ルーター)でパケットの断片化(フラグメンテーション)が発生する。

もちろん、IPレベルでの断片化はプロトコルが許容している挙動だ。しかし、現代の高性能なルーターやFW(特にステートフルな検査を行うもの)にとって、断片化されたパケットの再構築はCPUに多大な負荷をかける。結果としてスループットは低下し、最悪の場合は ICMP Fragmentation Needed パケットがブラックホールルーターによって握りつぶされ、TCPハンドシェイクの後に通信が完全にフリーズする、いわゆる「Path MTU Discovery (PMTUD) 問題」に直面する。

2. TCP MSSクランピングによる「最適化」の極致

PMTUDがうまく機能しない環境において、最もエレガントかつ確実な対策は、コネクション確立の初期段階でパケットサイズの上限を強制的に絞り込む「MSS(Maximum Segment Size)クランピング」だ。

TCPの3ウェイハンドシェイク(SYNパケット)において、クライアントとサーバーはMSSをネゴシエートする。ここで 1500 バイト(Ethernet)からIPヘッダー(20バイト)とTCPヘッダー(20バイト、オプション含め最大60バイト)を差し引いた、現実的なサイズ(通常 1360 〜 1400 バイト程度)に値を書き換えることで、断片化を物理的に防ぐのだ。

Linuxカーネルレベルでこれを制御する場合、iptables (または nftables) を用いるのが定石だ。

# FORWARDチェーンでTCP SYNパケットを捕まえ、MSS値を強制的にお手本サイズに書き換える
# 1360バイトなら、MTU 1400環境でも十分な余裕がある
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
    -j TCPMSS --set-mss 1360

# もしDockerコンテナやKubernetes Podから送信されるパケットを制御したい場合は、
# NATテーブルではなくmangleテーブルのPOSTROUTINGを叩く必要がある

3. TLSハンドシェイクとパフォーマンスの相関

最近の通信のほぼ全てはTLSで暗号化されている。ここで考慮すべきは、TLSのハンドシェイク時の「証明書チェーンの肥大化」だ。

もしMTUやMSSの設定が最適化されておらず、ハンドシェイクのパケットが断片化されると、SSL/TLSのネゴシエーション中にタイムアウトが発生する。特にクライアントが TLS 1.3 を使用してRTT(Round Trip Time)を短縮しようとしても、断片化による再送が起きれば、その努力はすべて水泡に帰す。

TCPバッファのチューニングも重要だ。高遅延・広帯域なネットワークでは、以下の値を sysctl.conf で調整し、BDP(Bandwidth Delay Product)を稼ぐ必要がある。

# 高速なデータ転送のためのTCPバッファ拡大
# メモリに余裕がある場合は、最大値を64MB程度まで引き上げるのが現代のセオリー
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.tcp_wmem = 4096 65536 33554432

# 設定を即時反映
sudo sysctl -p

4. 現場のテックリードが知るべき「回避策」

結局のところ、インフラアーキテクトとして最も推奨されるのは、「VPCのサブネット単位でMTUを制御し、パケットを最初からフラグメンテーションさせない」という設計思想だ。

AWSでは現在、MTU 1500 への制限をサブネット単位で適用できる。もしグローバルなトラフィックを大量に捌くエッジ環境であれば、ジャンボフレームの利便性を捨てる勇気も必要だ。

  • ハイブリッド構成の場合: VPN(Site-to-Site VPN)を経由する場合、IPsecのヘッダー分(約50〜70バイト)を計算に入れ、MSSクランピングを 1350 バイト以下に落とすのが安全だ。
  • コンテナ環境の場合: Kubernetesの CNI プラグインの設定をMTUに合わせて変更することを忘れてはならない。PodのインターフェースMTUとノードのMTUが食い違っていると、特定のパケットサイズでだけ通信が死ぬという、深夜のデバッグを強いる悪夢に直面することになる。

結びとして

ネットワークのトラブルシューティングにおいて、パケットの断片化やMSSの不整合は「地味」だが、解決した時のインパクトは絶大だ。ログには残らない「サイレントな失敗」を察知する感覚は、単なる知識ではなく、パケットがワイヤーの上をどう流れているかを想像する力によって養われる。

クラウドの抽象化の裏側にある、こうしたプロトコルの泥臭いルールに敬意を払うこと。それが、真に堅牢なインフラを構築する唯一の道であると、私は確信している。

コメント

タイトルとURLをコピーしました