「パケットは断片化して消える」――現場が泣くIPフラグメンテーションの罠とセキュリティの深淵
ネットワークの現場に長くいると、「なぜか特定の環境からだけWeb APIが叩けない」「大きなPOSTリクエストを送るとセッションが即座に切れる」といった、不可解なトラブルに必ず一度は遭遇します。その犯人の多くが、今回テーマにする「IPフラグメンテーション」です。
教科書では「MTUを超えたら分割される」と一行で済まされますが、実務においてこの現象は、パケットの断片化という物理的な挙動だけでなく、セキュリティ上の「盲点」を生む元凶にもなります。今日は、インフラエンジニアとして避けては通れない、この奥深い領域を紐解いていきましょう。
—
1. なぜ「分断」は起きるのか?:MTUとフラグメンテーションの仕組み
IPパケットは、経路上の各リンクが許容する最大転送単位である MTU (Maximum Transmission Unit) を超えることはできません。多くのイーサネット環境では MTU は1500バイトですが、VPNトンネルやクラウド上の複雑なネットワーク構成では、ヘッダーのオーバーヘッド分だけ実効 MTU が小さくなることが往々にしてあります。
ここで発生するのが「フラグメンテーション」です。IPヘッダーにある以下の3つのフィールドが、再構築の鍵を握っています。
Identification: 同じパケットから分割されたものかを識別するID。Flags:More Fragments (MF)ビットが「まだ続きがあるか」を示します。Fragment Offset: その断片が、元のデータの先頭から何バイト目から始まるか(8バイト単位で記録)を示します。
シーケンスのリアル:分割されたパケットの行方
例えば、1500バイトのパケットが MTU 1400バイトのネットワークを通る際、ルーターは以下のような動きをします。
1. ルーターがパケットを受け取る。
2. MTU を超えているため、データを2つに分割。
3. 1つ目の断片:MF=1、Offset=0。
4. 2つ目の断片:MF=0、Offset=1400/8=175。
このとき、後続の断片にはTCPヘッダーが含まれません。つまり、IDS/IPSやファイアウォールは、「断片そのものを見ただけでは、それが何のプロトコルで、どのような通信なのか判断できない」という事態に陥るのです。
—
2. セキュリティの暗部:断片化を悪用した攻撃
攻撃者はこの「不完全な状態」を悪用します。代表格が Teardrop 攻撃です。
Teardrop攻撃の恐怖
Fragment Offset をわざと重複させたり、重なりを持たせたりするようにパケットを送りつける手法です。OSのTCP/IPスタックが再構築処理に失敗し、最悪の場合、カーネルパニック(BSOD)を引き起こしてシステムをダウンさせます。
現代のOSでは対策済みですが、IoTデバイスや古い組み込み機器、あるいは設定が甘いネットワーク機器は未だにこの脆弱性を抱えていることがあります。また、IDS/IPSを欺く「フラグメント・オーバーラップ攻撃」は、断片化パケットの中に悪意あるペイロードを隠蔽し、IDSのシグネチャ検知をすり抜ける手法として今も現役です。
—
3. 実務でのデバッグと対策:どう向き合うか
Web API開発やクラウド運用において、フラグメンテーションを検知・回避するための実践的なTipsを紹介します。
経路上のMTUを調べる
ping コマンドで DF (Don’t Fragment) ビットを立てたままサイズを変えて送信し、どこでパケットが落ちるか確認するのが定石です。
# Linux環境で、DFビットを立てて1472バイトのペイロード(合計1500)を送信
# -M do は DF ビットをセットするオプション
ping -M do -s 1472 <ターゲットIP>
# もし応答がなければ、MTUが小さい経路が存在する
# サイズを下げていき、通過できる最大値を探る
ping -M do -s 1450 <ターゲットIP>
Pythonでパケットの断片化をシミュレートする(検証用)
Pythonの scapy を使えば、フラグメントパケットを意図的に作成できます。セキュリティ製品のテスト用として活用してください。
from scapy.all import *
# IPヘッダーを作成し、フラグメントIDを固定
ip_base = IP(dst="192.168.1.1", id=12345)
# 1つ目の断片(MF=1, Offset=0)
frag1 = ip_base / ("A" * 800)
frag1.flags = "MF"
frag1.frag = 0
# 2つ目の断片(MF=0, Offset=100)
frag2 = ip_base / ("B" * 800)
frag2.flags = 0
frag2.frag = 100
send(frag1)
send(frag2)
# 現場のIDSがこれをどう処理するかログを確認する
対策の鉄則:MSSクランプ
インフラ運用においては、TCPの MSS (Maximum Segment Size) を調整し、そもそもフラグメントが発生しないようにするのが最も平和的な解決策です。ロードバランサーやルーターの設定で MSS Clamping を有効にしましょう。
- Juniper/Cisco等の設定例:
ip tcp adjust-mss 1360
(PPPoE環境など、オーバーヘッドを考慮して1400〜1450程度に絞るのが安全)
—
まとめ:監視なきネットワークは盲目である
フラグメンテーションは、ネットワークの性能を最適化しようとする過程で発生する物理的な必然です。しかし、そこにはセキュリティの隙間が存在します。
1. IDS/IPSの再構築能力を疑え: 境界防御に設置している機器が、フラグメントパケットを正しくバッファリングし、再構築後に検査しているか確認してください。
2. MSS Clampingは必須: 不必要な分割を避けることは、パフォーマンス向上とセキュリティリスク低減の両面で有効です。
3. パケットキャプチャを恐れるな: tcpdump で ip[6] & 0x20 != 0 (MFビットが立っているパケット)をフィルタリングし、自社のネットワークで断片化がどれほど発生しているか可視化することから始めてみてください。
ネットワークは「繋がって当たり前」ではありません。パケットがどのように分断され、再構築されているか。その目に見えない挙動を想像できるエンジニアこそが、真のゼロトラストアーキテクチャを設計できるのです。
コメント