【入門編】 IPv4フラグメンテーションと再構築のメカニズム – ネットワーク基礎とWebセキュリティ実践ガイド

皆さん、こんにちは!ネットワークの深淵を覗き込む旅へようこそ。このメディアの主筆ライターを務める私が、今回皆さんと一緒に紐解いていくのは、一見地味ながらもネットワークの安定稼働とセキュリティに深く関わる、とても大切なテーマです。

私たちがインターネットを使っているとき、裏側では膨大なデータが小さな「パケット」という箱に詰められ、まるで郵便配達のように世界中を駆け巡っています。でも、この「箱」が、ある日突然、通る道の「道幅」よりも大きかったらどうなると思いますか?

そう、困りますよね!そんな時、ネットワークはどのようにこの問題を解決しているのでしょうか?そして、その解決策の裏側には、どんな落とし穴が潜んでいるのでしょうか?

今回は、そんな疑問に答えるべく、「IPv4フラグメンテーション(断片化)と再構築のメカニズム」について、郵便配達の例え話を交えながら、優しく、そして深掘りして解説していきます。ネットワークに初めて触れる方も、一歩ずつ理解していけるように、丁寧に紐解いていきますのでご安心ください!

—

ネットワークの「箱詰め便」事情を覗いてみよう!

皆さんがWebサイトを見たり、ファイルをダウンロードしたりする時、そのデータは一気に塊で送られてくるわけではありません。実は、データは細かく分割され、「パケット」と呼ばれる小さなデジタルな箱に詰められて送られます。このパケット一つ一つが、送信元から宛先へと旅をするんです。

例えるなら、大きな荷物を送る時に、一つの巨大なダンボール箱に入れるのではなく、小さなたくさんのダンボール箱に分けて送るようなイメージです。

OSI参照モデルとTCP/IPモデル、そして「道幅」の話

ネットワークの仕組みを理解する上で欠かせないのが、「OSI参照モデル」や「TCP/IP階層モデル」といった、通信の役割分担を整理した考え方です。これらは、データがアプリケーションから物理的なケーブルへと流れていく過程を、複数の「層(レイヤー)」に分けて説明してくれます。

今回のお話で特に注目するのは、IP(Internet Protocol)が活躍する「ネットワーク層(レイヤー3)」です。ここでは、データに「どこからどこへ送るか」という住所(IPアドレス)が付与され、ルーターと呼ばれる機器がその住所を見て適切な経路へデータを送り出します。

さて、ここで重要なのが「道幅」です。ネットワークの世界では、この「道幅」にあたるのが「MTU (Maximum Transmission Unit)」という考え方です。MTUとは、「一度に送れるパケットの最大サイズ」のこと。まるで、道路のトンネルや橋に「高さ制限」や「幅制限」があるように、ネットワークにもこのMTUという制限があるんです。

ほとんどのイーサネットネットワークでは、このMTUは1500バイトに設定されています。つまり、1500バイトを超えるパケットは、そのままではその道を通れない、ということになります。

「荷物が大きすぎる!」そんな時どうする? IPv4フラグメンテーションの登場

もし、アプリケーションが送りたいデータが、このMTUの1500バイトを超えてしまったらどうなるでしょうか? 例えば、2000バイトの大きなパケットを送ろうとしたら?

そこで活躍するのが、「IPv4フラグメンテーション(断片化)」という仕組みです。これは、大きすぎるパケットを、MTUに合わせて小さなパケット(これを「フラグメント」と呼びます)に分割して送る、という機能です。

先ほどの郵便配達の例で考えてみましょう。あなたは友人に大きな絵画を送りたいとします。でも、郵便局で扱っている一番大きなダンボール箱は、絵画全体が入るほど大きくありません。さあ、どうしますか?

そう、絵画をいくつかの部分に分解して、それぞれを小さなダンボール箱に入れて送る、という方法が考えられますよね。そして、友人の手元で、それらの箱の中身をまた元の絵画に組み立て直してもらう、というわけです。

IPv4フラグメンテーションは、まさにこの作業をネットワークの世界で行っているんです。

フラグメンテーションの舞台裏:魔法の3つの情報

分割されたパケット(フラグメント)が、最終的に受信側で元の大きなパケットにきちんと組み立て直されるためには、いくつかの「目印」が必要になります。バラバラになった荷物が、どれが同じ荷物の一部で、どの部分なのか、そしてまだ続きがあるのか、といった情報です。

IPv4ヘッダーの中には、この再構築のために欠かせない、3つの重要な情報が含まれています。

1. Identification (識別子):これは同じ荷物だよ!

「Identification」は、郵便配達でいうところの「荷物の伝票番号」のようなものです。

元の大きなパケットから分割されたすべてのフラグメントは、同じIdentificationの番号を持っています。受信ホストは、この番号を見て「ああ、これらは同じ元のパケットの一部なんだな」と判断し、それらをまとめて再構築の準備をするわけです。

例えば、絵画を3つの箱に分けて送ったとして、それぞれの箱の伝票番号がすべて「XYZ12345」だったら、友人は「この3つの箱は、全部同じ絵画の一部だな」と分かりますよね。それと同じです。

2. Flags (フラグ):大事な目印!「分割しないで」「まだ続きがあるよ」

「Flags」は、いくつかの特別な「目印」を示すビットです。特に重要なのは、以下の2つです。

DF (Don't Fragment) フラグ:「この荷物は絶対に分割しないで!」

このDFフラグが1に設定されていると、「このパケットはどんなことがあっても分割してはいけない!」という強い指示になります。

もし、このDFフラグが1のパケットが、途中でMTUを超える小さな道幅に遭遇した場合、ルーターはそのパケットを分割せず、そのまま破棄してしまいます。そして、送信元に対して「Path MTU Discovery (PMTUD)」と呼ばれる仕組みの一部として、「Packet Too Big」というICMPメッセージを送り返し、「あなたのパケットは大きすぎて通れませんでしたよ」と教えてあげます。

これは、郵便局で「この絵画は分解してほしくないから、もし入る箱がなければ送らなくていいよ」とお願いするようなものです。

MF (More Fragments) フラグ:「この荷物の他にも続きがあるよ!」

このMFフラグが1に設定されていると、「このフラグメントの他にも、まだ続きのフラグメントが存在するよ」ということを示します。

つまり、元のパケットが複数に分割された場合、最後のフラグメント以外のすべてのフラグメントにはMF=1が設定されます。そして、最後のフラグメントだけがMF=0となり、「これで終わりだよ!」と教えてくれるわけです。

これで受信ホストは、「MF=0のフラグメントが届くまでは、まだ全部揃っていないから待っていよう」と判断することができます。

3. Fragment Offset (フラグメントオフセット):荷物のどの部分かを示す番号

「Fragment Offset」は、「このフラグメントが、元のパケットのどこから始まる部分なのか」を示す番号です。これは、分割されたパケットを正しい順番に並べ替えるために使われます。

例えば、絵画を3つに分けたとして、それぞれの箱に「全体のうちの1番目の部分」「2番目の部分」「3番目の部分」という番号を振るようなイメージです。

このFragment Offsetは、8バイト単位でカウントされます。ちょっと細かい話ですが、これによってパケットのどの位置が欠けることなく正確に組み立てられるようになっているんです。

実際にパケットが分割され、組み立て直されるまで

では、これらの情報を使って、パケットはどのように旅をし、再構築されるのでしょうか。

1. 送信元でのフラグメンテーション

  • アプリケーションが大きなデータを送信しようとします。
  • OSのネットワークスタックは、送信元のネットワークインターフェースのMTUを確認します。
  • もしデータがMTUより大きければ、OSはデータを複数のフラグメントに分割します。
  • それぞれのフラグメントには、上記で説明したIdentification、Flags (MF)、Fragment Offsetが設定されます。

2. 途中のルーターでのフラグメンテーション

  • 送信元から送られたパケットが、途中のルーターに到着します。
  • ルーターは、そのパケットを次に送り出すネットワークのMTUがいくつであるかを確認します。
  • もしパケットのサイズが次のネットワークのMTUを超えていて、かつDFフラグが0(分割を許可)であれば、ルーターはそのパケットをさらに小さなフラグメントに分割します。
  • この場合も、新しいFragment OffsetとMFフラグが適切に設定されます。
  • もしDFフラグが1であれば、ルーターはパケットを破棄し、「Packet Too Big」というICMPエラーを送信元に返します。

3. 受信ホストでの再構築

  • 受信ホストは、ネットワークから届くフラグメントを受け取ります。
  • すべてのフラグメントは、Identificationフィールドを見て、同じ元のパケットに属するかどうかを判断されます。
  • 受信ホストは、同じIdentificationを持つすべてのフラグメントを、一時的なバッファに保管します。
  • Fragment Offsetフィールドを使って、フラグメントを正しい順番に並べ替えます。
  • MFフラグが0の最後のフラグメントが届き、すべてのフラグメントが揃ったら、それらを結合して元の大きなパケットに再構築します。
  • 再構築されたパケットは、上位の層(TCP層やUDP層)へと渡され、アプリケーションによって処理されます。

この一連のプロセスがあるおかげで、私たちは意識することなく、どんなサイズのデータでもインターネット経由でやり取りできるわけです。すごいですよね!

IPv4フラグメンテーションがもたらす光と影(セキュリティリスク)

IPv4フラグメンテーションは、ネットワーク通信の柔軟性を高めるために非常に重要な機能です。しかし、その特性を悪用しようとする攻撃者にとって、格好のターゲットとなることもあります。まさに「光と影」ですね。

影の部分:セキュリティリスク

1. DoS攻撃 (Denial of Service)

  • フラグメント再構築バッファ枯渇攻撃: 攻撃者は、大量の「不完全な」フラグメントを送りつけます。つまり、MF=0の最後のフラグメントを送らなかったり、一部のフラグメントだけを大量に送ったりします。
  • 受信ホストは、これらの不完全なフラグメントを再構築しようと、一時的なメモリ(バッファ)を消費し続けます。最終的には、メモリが枯渇し、正当な通信のためのパケット処理ができなくなり、サービス停止(DoS)に陥る可能性があります。

2. オーバーラップフラグメント攻撃

  • これはより巧妙な攻撃です。攻撃者は、Fragment Offsetを操作し、異なるフラグメント間でデータが「重複」するようにパケットを送りつけます。
  • 受信ホストがこれらの重複するフラグメントをどのように処理するか(どちらのデータを優先するか)は、OSや実装によって異なります。この差異を悪用することで、ファイアウォールのルールをバイパスしたり、不正なペイロード(攻撃コードなど)をパケットに挿入したりする可能性があります。
  • 例えば、ファイアウォールは最初のフラグメントを見て安全と判断しても、後のフラグメントで危険な内容が上書きされる、といったシナリオが考えられます。

光の部分と対策:賢く付き合おう!

これらのリスクがあるからといって、フラグメンテーションを完全に禁止するわけにはいきません。大切なのは、その仕組みを理解し、適切に対策を講じることです。

Path MTU Discovery (PMTUD) の活用

最も有効な対策の一つが、「Path MTU Discovery (PMTUD)」です。これは、「事前に道幅を調べておく」ことで、そもそもフラグメンテーションが発生しないようにする仕組みです。

1. 送信元は、まずDFフラグを1に設定したパケットを送ります(「分割しないでね」と指示)。
2. 途中のルーターで、次のネットワークのMTUよりパケットが大きかった場合、ルーターはそのパケットを破棄し、「Packet Too Big」というICMPメッセージを送信元に返します。このメッセージには、そのルーターが通過できるMTUサイズが記載されています。
3. 送信元は、このICMPメッセージを受け取ると、次回からはそのMTUサイズに合わせて小さなパケットを作成して送るようになります。

このプロセスによって、送信元と宛先間の「パス(経路)」上で、最も小さなMTU(これを「Path MTU」と呼びます)が特定され、不要なフラグメンテーションを避けることができます。フラグメンテーションを避けることで、ルーターや受信ホストの処理負荷が減り、前述のような攻撃のリスクも軽減されるため、PMTUDは非常に重要な機能なんです。

【重要】ファイアウォールでICMPをブロックしないこと!
PMTUDが正しく機能するためには、ICMPの「Packet Too Big」メッセージが送信元に届く必要があります。もしファイアウォールでICMPをすべてブロックしてしまうと、このメッセージが届かず、PMTUDが機能しなくなってしまいます。その結果、通信が遅延したり、一部のWebサイトが表示されなかったりする原因になることもあります。

ファイアウォール・IDS/IPSでの対策

現代のファイアウォールやIDS/IPS (Intrusion Detection/Prevention System)は、フラグメント攻撃に対する対策機能を持っています。

  • 不審なフラグメントの検出と破棄: 不完全なフラグメントや、不正なオフセットを持つフラグメントを検出し、破棄する機能です。
  • フラグメント再構築タイマー: フラグメントがすべて揃うまで待つ時間を設定し、一定時間内に揃わなければ破棄することで、バッファ枯渇攻撃を防ぎます。
  • オーバーラップフラグメントの厳密な処理: オーバーラップしたフラグメントを検出した場合に、特定の方法(例えば、常に最初のデータを優先するなど)で処理を統一することで、攻撃者が意図しない挙動を防ぎます。

実践してみよう!PMTUDの確認と設定のヒント

PMTUDがどのように機能しているか、簡単なコマンドで確認してみましょう。

pingコマンドでDFフラグとMTUをテストする

pingコマンドを使うと、DFフラグを設定して特定のサイズのパケットを送信し、PMTUDの動作をシミュレートできます。

Windowsの場合:

# DFフラグ (-f) を設定し、ペイロードサイズ 1472バイトでpingを送信
# MTU 1500の場合、IPヘッダー(20B)とICMPヘッダー(8B)を除くとペイロードは1472Bが最大
ping -f -l 1472 google.com

# 結果例:
# 1472バイトのパケットをgoogle.com に送信しています。
# 要求がタイムアウトしました。
# 要求がタイムアウトしました。
# ...

# 試しにサイズを1473バイトに上げてみる(MTU 1500を超過するため、通常は失敗)
ping -f -l 1473 google.com

# 結果例:
# 1473バイトのパケットをgoogle.com に送信しています。
# パケットのサイズが大きすぎます。
# ...
# → これが「Packet Too Big」に相当するメッセージです。
#    この場合、pingコマンド自身がMTUを超過したことを教えてくれます。

Linuxの場合:

# DFフラグ (-M do: Don't Fragment) を設定し、ペイロードサイズ 1472バイトでpingを送信
# -s はペイロードサイズを指定します
ping -M do -s 1472 google.com

# 結果例:
# PING google.com (142.250.199.142) 1472(1500) bytes of data.
# 1480 bytes from 142.250.199.142: icmp_seq=1 ttl=115 time=10.1 ms
# ...

# 試しにサイズを1473バイトに上げてみる(MTU 1500を超過するため、通常は失敗)
ping -M do -s 1473 google.com

# 結果例:
# PING google.com (142.250.199.142) 1473(1501) bytes of data.
# From 192.168.1.1 icmp_seq=1 Frag needed and DF set (mtu = 1500)
# From 192.168.1.1 icmp_seq=1 Frag needed and DF set (mtu = 1500)
# ...
# → これがルーターから返される「Frag needed and DF set」メッセージです。
#    これはICMP "Packet Too Big" メッセージを受信したことを示します。

このpingコマンドの結果から、あなたの環境のPath MTUがどのくらいなのかをある程度推測することができます。

LinuxでのPMTUD関連設定の確認

Linuxシステムでは、PMTUDに関する設定をsysctlコマンドで確認できます。

# PMTUDが無効化されていないか確認します (0は有効、1は無効)
# 通常はデフォルトで有効 (0) になっています
sysctl net.ipv4.ip_no_pmtu_disc

# 出力例:
# net.ipv4.ip_no_pmtu_disc = 0
# → 0なので、PMTUDは有効になっています。

# もし何らかの理由で無効になっていた場合、有効にするには以下のように設定します (恒久化には設定ファイルを編集)
# sysctl -w net.ipv4.ip_no_pmtu_disc=0

ファイアウォールでのICMP許可の重要性

PMTUDを正しく機能させるために、ファイアウォールでICMPタイプ「fragmentation-needed (Type 3, Code 4)」を許可することが非常に重要です。

iptablesの例:

# 特定のインターフェース (例: eth0) からのICMP "Packet Too Big" を許可するルール
# これにより、PMTUDが正しく機能し、MTU超過による通信問題を回避できます。
# 環境に合わせてインターフェース名やルール位置を調整してください。
sudo iptables -A INPUT -i eth0 -p icmp --icmp-type fragmentation-needed -j ACCEPT

# または、より広範にICMPを許可する (セキュリティポリシーと相談しながら)
# sudo iptables -A INPUT -p icmp -j ACCEPT

# 設定を保存するコマンド (ディストリビューションによって異なります)
# Debian/Ubuntu系: sudo netfilter-persistent save
# CentOS/RHEL系: sudo service iptables save (または firewall-cmd --runtime-to-permanent)

注意点: ICMPは攻撃に悪用されることもあるため、闇雲にすべてを許可するのではなく、必要なタイプのみを許可するなど、セキュリティポリシーに基づいた適切な設定が求められます。

まとめ:フラグメンテーションと賢く付き合おう!

今回は、ネットワークにおける「大きすぎる荷物」の問題を解決するIPv4フラグメンテーションの仕組みと、その再構築プロセス、そして潜むセキュリティリスクについて詳しく見てきました。

  • MTUという「道幅」に合わせてパケットを分割する「フラグメンテーション」。
  • Identification、Flags (DF/MF)、Fragment Offsetという3つの魔法の目印で、バラバラになったパケットを「再構築」する。
  • 便利な機能の裏側には、DoS攻撃やオーバーラップフラグメント攻撃といった「セキュリティリスク」がある。
  • PMTUDの活用や、ファイアウォールでの適切なICMP許可が、これらのリスクを軽減するための重要な「対策」となる。

パケットがネットワークを駆け巡るリアルな挙動を想像していただけたでしょうか?普段は意識しないような、こんな細かな仕組みの上に、私たちが当たり前のように使っているインターネットは成り立っています。

ネットワークの世界は、知れば知るほど奥深く、まるで生きてるかのように動いています。今回の記事が、皆さんがネットワークの基礎を理解し、さらに深い知識へと進むための一歩となれば幸いです。

これからも、一緒にネットワークの謎を解き明かしていきましょう!
それでは、また次回の記事でお会いしましょう!

コメント

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