ICMP とは — ping / traceroute の仕組みとメッセージ種別 のサムネイル

ICMP とは — ping / traceroute の仕組みとメッセージ種別

⏱ 約 10 分 view 182 like 0 LOG_DATE:2026-05-09
目次 / TOC

ICMP (Internet Control Message Protocol) は、IP ネットワーク上で発生したエラーや経路状態を通知するための制御プロトコル。データ自体を運ぶのではなく、「届かなかった」「TTL が切れた」「ポートが閉じている」といった情報を送信元に返すことで、ホストとルータが状況を判断できるようにする。pingtraceroute はすべてこの上で動く。RFC 792 (IPv4) で定義され、IPv6 では ICMPv6 (RFC 4443) として再設計された。

01

ICMP メッセージの読み方 #

ICMP は IP の上位プロトコル (IPv4 で Protocol Number 1、IPv6 で 58) として動く。TCP / UDP のような ポート番号は持たない ので、ssnetstat のコネクション一覧には現れない。

ヘッダは非常にシンプル。

フィールド サイズ 役割
Type 1 byte メッセージ種別 (Echo Request / Destination Unreachable など)
Code 1 byte Type ごとのサブ種別 (例: Type 3 Code 1 = Host Unreachable)
Checksum 2 byte ICMP メッセージ全体の検証用
Rest of Header 4 byte Type ごとに用途が異なる (Echo の Identifier+Sequence など)
Data 可変 エラー通知系は「失敗した IP パケットの IP ヘッダ + 先頭 8 byte」を返す
▸ Data 部の「失敗した元パケット」が原因切り分けの鍵

エラー通知系メッセージが 失敗した元パケットの一部 を返してくれるおかげで、送信元は「どの送信パケットがどう失敗したか」を識別できる。tcpdump で ICMP を見るときは Type/Code に加えて、内側に挟まっている元 IP ヘッダ (Source/Dest IP, TCP/UDP ポート) を読むと原因がわかる。

02

ping と traceroute は何をしているのか #

ping = Echo Request (Type 8) / Echo Reply (Type 0) #

pingType 8 を送って Type 0 が返ってくるまでの時間を測る。Identifier + Sequence Number で複数の ping を区別するため、同じホストから同時に複数の ping を打っても正しく対応付けられる。

応答が来ない場合、考えられる切り分け:

  • 何も返らない → 経路上のどこか、または宛先 FW で ICMP がドロップされている
  • Destination Unreachable (Type 3) が返る → 経路上のどこかが「届けられない」と明示。Code で理由が分かる
  • TTL exceeded (Type 11) が返る → 経路ループまたは TTL を異常に低く送ってしまった
▸ 「ping が通らない = 死んでいる」とは限らない

Web サーバが ICMP だけブロックしている運用は普通にある。Echo Reply が無くても TCP 443 は生きていることが多い。

traceroute は TTL を 1 ずつ上げて Time Exceeded を集める #

tracerouteTTL=1, 2, 3, ... と上げながらプローブを送り、各中継ルータが返す Time Exceeded (Type 11) を集計して経路を描く。最終ホストでは Type 11 が返らないので、別の合図でゴール判定する。

1. TTL=1 でプローブ送出
最初のルータが TTL を 1 → 0 にデクリメントし、Time Exceeded (Type 11) を返す。送信元はその IP を 1 ホップ目として記録。
2. TTL=2,3,4... と繰り返し
各ホップが順に Time Exceeded を返すので、経路上のルータが 1 台ずつ可視化される。
3. 最終ホストの判定
UDP 高ポート版 (Linux/macOS デフォルト): 最終ホストが Port Unreachable (Type 3 Code 3) を返したら到着。Echo 版 (Windows tracert / Linux -I): Echo Reply (Type 0) で到着。TCP SYN 版 (-T / tcptraceroute): 80/443 で FW を抜けて経路追跡。

自分で動かして確かめる — TTL を 1 ずつ上げると、経路上のルータが 1 ホップずつ Time Exceeded を返して可視化される様子を 1 ステップずつ追える。

途中の * * * は、そのホップのルータが Time Exceeded を返さない (またはレート制限している) ことを意味する。多くのルータは ICMP 生成をレート制限しているので、ホップが消えること自体は珍しくない。

03

現場で読むメッセージ #

Destination Unreachable (Type 3) — Code で読む #

Code 意味 現場での解釈
0 Network Unreachable ルーティングテーブルにそのネットへの経路がない
1 Host Unreachable 経路上の最後のルータが ARP で MAC を引けない
3 Port Unreachable UDP で当該ポートが開いていない / UDP traceroute の終端合図
4 Fragmentation Needed and DF Set PMTUD で必須 (次節)
9 Network Administratively Prohibited ACL で網単位拒否
10 Host Administratively Prohibited ACL でホスト単位拒否
13 Communication Administratively Prohibited FW で遮断

Code 3 (Port Unreachable) は UDP プローブの応答としてよく見る。dig で名前解決失敗のハマりの原因にもなる。Code 13 は明示的に FW で蹴られた合図なので、ネットワーク側の設定責任者に確認が必要。

Time Exceeded (Type 11) #

Code 意味
0 TTL Exceeded in Transit (中継で TTL=0 になった)
1 Fragment Reassembly Time Exceeded (フラグメント再構成タイムアウト)

Code 0 は traceroute の合図でもあるが、運用で連発する場合は経路ループを疑う

Redirect (Type 5) #

ルータがホストに「もっと良い経路がある」と通知する。偽装されると中間者攻撃に使えるため、現代の OS は既定で受け入れない (後述)。

▸ 廃止・無視してよいもの
  • Source Quench (Type 4) — RFC 6633 (2012) で廃止。輻輳制御は TCP ECN に任せる
  • Timestamp (Type 13/14) — NTP に置き換わった。uptime fingerprinting に悪用されるので外向きはドロップが定石
  • Address Mask Request (Type 17/18) — DHCP で代替済み
04

PMTUD ブラックホール — ICMP を全部止めると壊れる代表例 #

経路上に MTU が小さい区間があると、DF (Don't Fragment) ビット付き IP パケットを送ったルータは Destination Unreachable Code 4 (Fragmentation Needed) を返す。送信元はこれを受けて TCP MSS を下げる — これが Path MTU Discovery (PMTUD) の仕組み。

ファイアウォールが「ICMP は全部ブロック」にしていると、Code 4 も届かなくなり、大きい TCP セグメントだけ静かに消える現象が起きる。

  • 小さい HTTP リクエストは通る
  • 大きい POST やレスポンスで突然ハング
  • 通常の ping (小さいエコー) は通るので一見正常に見える

これが PMTUD ブラックホール で、「VPN 越しの一部通信だけ詰まる」「特定の API レスポンスだけタイムアウトする」といった 最も再現性が悪い障害 の典型的な原因。

▸ Type 3 Code 4 は必ず通すこと

「ICMP は全部止めれば安全」という設定が、最も嫌な障害を生む。Type 3 Code 4 (Fragmentation Needed) は inbound / outbound 両方で必ず通すのが鉄則。回避策として TCP MSS Clamping (ルータ側で SYN の MSS を強制的に下げる) を入れる手もある。VPN や PPPoE 環境ではほぼ必須の設定。

05

ICMPv6 — IPv6 では止めると動かない #

IPv6 では ICMP の役割が大幅に拡張され、IPv6 の動作そのものに不可欠になっている。ARP・IGMP・Router Discovery などが ICMPv6 に統合された。

機能 Type 役割
Neighbor Solicitation 135 IPv4 の ARP 相当 — 隣接ノードの MAC を引く
Neighbor Advertisement 136 上記への応答
Router Solicitation 133 ホストが「ルータは?」と問い合わせ
Router Advertisement 134 ルータの存在告知 + プレフィックス通知 (SLAAC の核)
MLD 130-132, 143 IPv4 IGMP 相当のマルチキャスト管理
▸ IPv6 で ICMPv6 を全面ブロックすると通信が成立しない

NDP も RA も動かなくなる。フィルタリング設計は RFC 4890 が必読 — どの Type を落としていいか・絶対に通すべきかが整理されている。ブラックリスト方式 (落とすものを明示) で運用するのが安全。

06

セキュリティで押さえる点 #

歴史的に Smurf や Ping of Death が話題になったが、現代の OS とルータでは対策済み。今意識すべきは以下の 4 点。

ICMP Redirect の偽装 #

ローカルセグメント上の攻撃者が 偽の ICMP Redirect を送って「私を経由しろ」と誘導する MITM。Linux なら確実に塞ぐ:

Redirect 受信・送信を無効化
$ sysctl -w net.ipv4.conf.all.accept_redirects=0 $ sysctl -w net.ipv4.conf.all.send_redirects=0 $ sysctl -w net.ipv6.conf.all.accept_redirects=0

ICMP tunneling (covert channel) #

Echo Request / Reply のペイロードに任意データを詰めて、TCP/UDP の通信を ICMP に偽装して FW を抜ける 手法。icmpshptunnel が代表例で、APT 攻撃で C2 通信に使われた事例もある。

検知のポイント:

  • 異常に大きい / 連続する Echo パケット (普通の ping は 64 byte 程度)
  • 応答のない一方向 Echo (内部→外部だけが大量)
  • サーバから外向き ICMP の流量を Egress firewall で監視

OS フィンガープリンティング #

ICMP 応答の細部 (TTL 初期値、Code の選択、応答可否) に OS 固有の癖 が出るため、nmap -O の手がかりになる。インターネットに直接面するホストでは、Timestamp (Type 13/14) を落とすだけでも偵察情報を減らせる。

Ping flood / rate limiting #

ICMP Echo を大量に送りつける単純な DoS。Linux カーネル / ルータ側で icmp_ratelimit を設定し、FW で Echo Request を limit モジュール経由にしておくのが定石。

07

フィルタリング戦略 — 全許可も全拒否も両方危険 #

「ICMP は全部止めれば安全」は誤り。PMTUD が壊れ、診断もできなくなる。選択的に許可するのが正しい。

Type 通す/落とす 理由
Destination Unreachable Code 4 必ず通す (in/out) PMTUD 必須
Destination Unreachable 他 Code 通すと運用が楽 切り分けに有用
Time Exceeded (Type 11) 通す traceroute / 診断
Echo Request (Type 8) rate-limit して許可 完全拒否は診断不能
Echo Reply (Type 0) 通す 自分が打った ping の返答
Redirect (Type 5) 落とす MITM のリスク
Timestamp (Type 13/14) 落とす 偵察に悪用される
Address Mask Request (Type 17/18) 落とす 用途なし
Source Quench (Type 4) 落とす 廃止済み
iptables — Echo を rate-limit + 必須メッセージは許可
# Echo Request は 1 秒あたり 5 個までに制限 $ iptables -A INPUT -p icmp --icmp-type echo-request \ -m limit --limit 5/sec -j ACCEPT $ iptables -A INPUT -p icmp --icmp-type echo-request -j DROP # Destination Unreachable と Time Exceeded は全許可 $ iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT $ iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT # Redirect / Timestamp はドロップ $ iptables -A INPUT -p icmp --icmp-type redirect -j DROP $ iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
▸ まとめ — Type 3 Code 4 と Time Exceeded は絶対に通す

ICMP は地味だが、通信が壊れた瞬間に最初の情報を運んでくれるプロトコル。トラブル切り分けで ping / traceroute / mtr を打つときに「返ってきたのが Type 3 か 11 か、Code は何か」まで見るだけで、原因への距離が一気に縮まる。「とりあえず ICMP ブロック」をやめて、Code 4 (PMTUD) と Time Exceeded だけは絶対に通す設計に変えるのが、運用とセキュリティの両立への第一歩。

𝕏 ポスト B! はてブ