ICMP(Internet Control Message Protocol)

IP の「制御・診断用」メッセージ。エラー通知や疎通確認に使う。 ping / traceroute / Path MTU Discovery の動作原理まで。

役割

IP が「ベストエフォート」で動く以上、エラーが起きたときに何かを伝える仕組みが要る。 ICMP はその役割を担う「診断・通知」プロトコル。

IPv4 のプロトコル番号は 1、IPv6 は 58 (ICMPv6)

ICMP メッセージの形式

+--------+--------+----------+
| Type   | Code   | Checksum |
+--------+--------+----------+
| Type 固有のデータ            |
+----------------------------+
      

主要な Type 一覧(IPv4)

Type名称意味
0Echo Replyping の応答
3Destination Unreachable到達不能(Code で詳細)
4Source Quench輻輳通知(廃止)
5Redirectもっと良い経路あり
8Echo Requestping の問合せ
9Router Advertisement古典的なルータ広告
10Router Solicitationルータ要求
11Time ExceededTTL 切れ / 再構成タイマー切れ
12Parameter Problemヘッダ不正
13Timestamp Request時刻取得
14Timestamp Reply時刻応答
17Address Mask Requestマスク取得(廃止)
18Address Mask Reply同上

Destination Unreachable(Type 3)の Code

Code意味
0Network Unreachable — そのネットワークに経路がない
1Host Unreachable — そのホストに到達不能
2Protocol Unreachable — そのプロトコル未対応
3Port Unreachable — そのポートに LISTEN なし
4Fragmentation Needed but DF set — PMTUD で重要
5Source Route Failed
9Communication Administratively Prohibited(FW)
13Communication Administratively Prohibited

Time Exceeded(Type 11)の Code

ping の中身

仕組み

  1. 送信側が ICMP Echo Request (Type 8) を作成
  2. Identifier / Sequence Number を載せて送信
  3. 受信側が同じデータを Echo Reply (Type 0) で返す
  4. 送信側が RTT を計算

パケット例(hex)

ICMP Header
08          ← Type (8 = Echo Request)
00          ← Code
xx xx       ← Checksum
xx xx       ← Identifier (PID 等)
xx xx       ← Sequence Number
[payload]   ← 任意のデータ(時刻情報など)
      

確認コマンド

ping -c 5 example.com         # 5 回送信
ping -i 0.2 example.com       # 200ms 間隔(root)
ping -s 1472 example.com      # MTU 試験用サイズ
ping -M do -s 1472 example.com  # DF を立てて分割不可
ping -W 2 example.com         # 待機 2 秒
ping -t 1 example.com         # TTL を 1 に(traceroute 風)

# IPv6
ping6 ipv6.google.com

traceroute の中身

仕組み

  1. TTL=1 のパケットを送る → 1 番目のルータが受け取って TTL=0 にしてICMP Time Exceeded を返す
  2. 送信元はこの ICMP の送信元 IPを見て、1 番目のルータの IP を知る
  3. TTL=2, 3, 4... と増やしていき各ホップを順に発見
  4. 最終的に宛先が応答(プロトコル次第で Echo Reply / Port Unreachable / 等)

UDP / TCP / ICMP のどれを使う?

「* * *」の意味

Path MTU Discovery(PMTUD)

経路上の最小 MTU を学習するための仕組み(RFC 1191)。

動作

  1. 送信元が大きいパケット + DF (Don't Fragment) フラグで送る
  2. MTU 不足のリンクで弾かれ、ルータが ICMP Type 3 Code 4 (Fragmentation Needed) を返す
  3. その ICMP に「次のホップ MTU」が記載されている
  4. 送信元はこれに合わせてパケットサイズを縮小して再送
  5. 同じ宛先への将来の送信もこの値を使用

PMTUD ブラックホール問題

Redirect(Type 5)

ルータが「自分よりもっと近いルータがある」と送信元に教える

ICMPv6

IPv6 では ICMPv6(Protocol 58)が大幅に拡張されている。 ARP / IGMP / Router Discovery を統合。

主要 Type

Type名称
1Destination Unreachable
2Packet Too Big(PMTUD)
3Time Exceeded
4Parameter Problem
128Echo Request
129Echo Reply
130Multicast Listener Query
131Multicast Listener Report
133Router Solicitation (RS)
134Router Advertisement (RA)
135Neighbor Solicitation (NS)
136Neighbor Advertisement (NA)
137Redirect

NDP / MLD

IPv6 ではICMPv6 を絶対にブロックしてはいけない(NDP / PMTUD が壊れる)。

セキュリティ

ICMP を悪用した攻撃

FW の方針

ICMP のレート制限

多くの OS / ルータは ICMP の生成・転送にレート制限をかける(DDoS 対策)。 traceroute で「* * *」が出る原因の 1 つ。

具体例: ping を Wireshark で見る

Frame 1: 98 bytes on wire
Ethernet II
   Src: aa:bb:cc:dd:ee:ff
   Dst: 11:22:33:44:55:66
Internet Protocol Version 4
   Src: 192.168.1.10
   Dst: 8.8.8.8
   Protocol: ICMP (1)
   TTL: 64
Internet Control Message Protocol
   Type: 8 (Echo Request)
   Code: 0
   Checksum: 0x4d34
   Identifier: 0x1234
   Sequence: 1
   Data: ...timestamp...
      

確認コマンド

# PMTUD テスト
ping -M do -s 1500 example.com

# ICMP だけキャプチャ
sudo tcpdump -i any -n icmp
sudo tcpdump -i any -n icmp6

# ICMP のカウンタ
ss -s
nstat | grep -i icmp        # Linux
netstat -s -p icmp          # Linux
netstat -s | grep -A 30 -i icmp   # macOS / BSD

Linux で ICMP を扱う設定

# ICMP Redirect を受けない
sysctl -w net.ipv4.conf.all.accept_redirects=0

# ping に応答しない(非推奨)
sysctl -w net.ipv4.icmp_echo_ignore_all=1

# ブロードキャスト ping を無視(推奨デフォルト)
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1

# ICMP のレート制限
sysctl -w net.ipv4.icmp_ratelimit=1000

よくあるトラブル

症状原因
ping は通るが HTTP は通らないL7 / FW / アプリ層の問題(ICMP は L3 まで)
ping が通らないが HTTP は OKサーバが ICMP を拒否しているだけ。実害なし
HTTPS の特定サイトで巨大ファイルが固まるPMTUD ブラックホール
traceroute が途中で止まるICMP レート制限 / FW で TTL Exceeded ブロック
IPv6 の通信が不安定ICMPv6 を無闇にブロックしている
大原則

「ICMP = ping」だけではない。インターネットの正常動作に不可欠な制御プロトコル。 ブロックしすぎると現代の通信は壊れる。RFC 4890 / 8504 を読むのが吉。