断片化の深淵:なぜ今、IPv4フラグメンテーションが「悪」なのか
ネットワークエンジニアとして現場を渡り歩いていると、いまだに「フラグメンテーション(断片化)」という亡霊に出会うことがある。教科書的には「MTUを超えるパケットを分割して送る仕組み」と教わるが、現代の高速ネットワークにおいて、これは単なる「処理コストの増大」に留まらない。セキュリティの穴であり、パフォーマンスを殺す毒薬でもあるのだ。
今日は、パケットがワイヤーの上でどう引き裂かれ、そして再構築されるのか。その裏側にあるプロトコルの美学と、それが引き起こす悪夢について語ろう。
—
1. 断片化の解剖学:Identification, Flags, Offsetの三位一体
IPヘッダーには、断片化を制御するための3つの重要なフィールドが存在する。これらがパケットの「身分証明書」であり、「パズルのピース」となる。
Identification(16bit): 同一の元パケットから分割されたものかを識別するID。Flags(3bit):DF(Don’t Fragment): 1なら分割禁止。これがあるパケットがMTUを超えると、ルーターは容赦なくパケットを破棄し、ICMP Destination Unreachableを返す。MF(More Fragments): 1なら「続きがある」。0なら「これが最後のピース」。Fragment Offset(13bit): 8バイト単位で、そのパケットのデータが「元のパケットのどこから始まるか」を示す。
パケットが経路上の狭いリンク(MTU 1500から1280へ落とすようなケース)で分割される際、ルーターは元のIPヘッダーをコピーしつつ、MFフラグとOffsetを書き換える。受信側のOS(Linuxカーネル等)は、Identificationと送信元/宛先IPアドレスを見て、「あ、これはバラバラになったパケットだな」と判断し、メモリ上にバッファを確保して再構築を待つ。
なぜこれが危険なのか?
この「再構築待ち」の時間が、攻撃者にとっての格好の餌食となる。
- Fragment Overlap攻撃: 意図的に重なるような
Offsetを持つパケットを送りつけ、再構築ロジックを混乱させる。古いIDS/IPSはこれでバイパスされ、検知をすり抜けることがある。 - メモリ枯渇攻撃: 最初のパケットだけ送り、最後のパケットを送らない。ターゲットのOSは再構築用のバッファを確保したままタイムアウトまで待機し続ける。これを大量に行えば、サーバーは容易にリソース枯渇を引き起こす。
—
2. パフォーマンスの死角:なぜTLSハンドシェイクが遅れるのか
現代のWebトラフィックの9割以上はHTTPS、つまりTLSだ。TLSハンドシェイクの過程では、サーバー証明書を含む巨大なパケットがやり取りされる。ここで断片化が発生すると何が起きるか。
1. RTTの増大: 断片のどれか一つでも欠落すれば、TCPは再送制御を行うが、IPレベルの断片化の場合、受信側は「パケット全体」が揃うまでアプリケーション層にデータを渡せない。
2. TCPバッファとの相性: tcp_rmemやtcp_wmemをチューニングしていても、IP層で断片化が発生すれば、NICのオフロード機能(LRO/GRO)が正しく働かず、CPU負荷が急増する。
特に、クラウド環境のVPNやトンネルプロトコル(GREやIPsec)を使用していると、ヘッダー分だけMTUが実質的に削られる。ここで DF ビットが立っていると、ハンドシェイクの途中でパケットが消え、ブラウザは「接続がリセットされました」と表示する。いわゆる「PMTUD(Path MTU Discovery)失敗」だ。
—
3. 現場で打つべき「極限の対策」
この問題を根本から解決するには、フラグメンテーションを「発生させない」ことが唯一の正解だ。
① Path MTU Discoveryの最適化
Linuxであれば、以下のカーネルパラメータでMTUの自動調整を制御できる。
# パスMTU発見を有効にする(デフォルトは2)
sysctl -w net.ipv4.ip_no_pmtu_disc=0
# TCP MSSクランプをかける(iptables/nftablesで強制的に調整)
# 1460 (1500 - 20 - 20) が目安だが、トンネル経由なら 1360 程度まで落とす
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
② MSSの明示的な設定
nginxやApacheなどのWebサーバーで、HTTP/2やHTTP/3 (QUIC) を利用している場合、TCPの最大セグメントサイズ(MSS)を意識してバッファを設計する。特にQUIC(UDPベース)は、自前でMTUを探索し、断片化を回避する設計になっているため、現代の低レイテンシ環境ではQUICへの移行が最強のセキュリティ対策と言える。
③ セキュリティ・ハードニング
外部からの不正なフラグメントを防ぐには、ファイアウォールで「不完全なパケット」を捨てる設定が有効だ。
# 疑わしい断片化パケットをドロップする (nftables例)
nft add rule inet filter input ip frag-off 0-65535 drop
# ※実際には環境に応じて設定が必要だが、基本は「最小限の許可」
—
結びに:境界を意識するアーキテクトへ
パケットの断片化は、ネットワークの「境界」が崩れた瞬間に発生する不協和音だ。MTUという物理的な制約を無視して設計されたアーキテクチャは、どんなに高価なハードウェアを導入しても、どこかで必ずボトルネックを生む。
パケットがネットワークカードを通過するその一瞬、内部で何が起きているのか。tcpdumpで[frag]という文字を見たとき、単なるエラーと捉えるのではなく、「プロトコルスタックの限界と対話している」と意識してほしい。
プロトコルの深淵を覗くことは、ただのトラブルシューティングではない。それは、システム全体のパフォーマンスを極限まで引き出す、アーキテクトにしかできない「職人技」なのだから。
コメント