首页/网络/协议速查/ICMP 协议总览

ICMP 协议总览

IP 的「信使协议」:报告网络差错(不可达、超时)与执行诊断(ping),本身不传输用户数据,封装在 IP 内部(协议号 1)。

协议速查网络更新于 2026-10-13

ICMP 是什么

ICMP 是 IP 层的配套控制协议,负责报告网络差错(目标不可达、超时、需分片)与执行诊断(Echo 请求与应答),本身不承载用户数据,而是封装在 IP 包里,协议号 1。IPv6 对应的是 ICMPv6(协议号 58),职责更重:它同时承担了邻居发现与组播管理,禁用 ICMPv6 会让 IPv6 直接不可用。

基本信息

封装IP 协议号 1;ICMPv6 为 58
报文结构类型(8bit) + 代码(8bit) + 校验和(16bit) + 内容
大类差错报文 + 查询报文
规范RFC 792(ICMP)、RFC 4443(ICMPv6)、RFC 1122 §3.2.2
权限ping/traceroute 普通用户可用,原始套接字抓包需要 root

常用类型代码

类型名称典型场景
0Echo Replyping 的应答
3Destination Unreachablecode 0 网络不可达、code 3 端口不可达、code 4 需分片
5Redirect同链路存在更优网关
8Echo Requestping 的请求
11Time ExceededTTL 减到 0,也是 traceroute 逐跳探测的依据

观察 ICMP

观察 ICMP
tcpdump -nn -v 'icmp' -c 10                            # 抓 10 个包并显示类型与代码
tcpdump -nn 'icmp[0]==3 and icmp[1]==3' -c 5           # 只看端口不可达
ping -c 2 1.1.1.1 | tail -2                            # 顺手看丢包率与 RTT
iptables -L INPUT -v -n | grep -i icmp                 # 看本机对 ICMP 的过滤与计数

为什么不能全禁

  • PMTUD 依赖「需分片」差错报文,禁掉后大包静默丢失,表现为小包通、大包卡死
  • traceroute 依赖 TTL 超时报文,全禁后只能看到星号,无法定位路径断点
  • ping 是判断「主机是否在线」的最快手段,全禁会让排查只能靠 TCP 探测
  • ICMPv6 承载邻居发现,禁用后 IPv6 地址无法解析,链路直接不可用
ICMP 不是 TCP/UDP 的替代品:它属于网络层的控制机制,正确做法是按类型限速,而不是按协议整体封禁。

抓包怎么看

  • 先看 icmp[0] 类型:3 是差错、8/0 是 ping、11 是超时
  • 再看 icmp[1] 代码细分原因,例如代码 3 表示端口不可达
  • 差错报文会带上原始 IP 头与部分载荷,可据此判断是哪个包引发的
  • 加 -e 显示链路层地址,确认回复来自预期的下一跳而不是被劫持

策略建议

  • 允许 Echo 但按源地址限速,避免成为放大攻击的反射面
  • 务必放行「需分片」与「超时」两类差错,否则 PMTUD 与 traceroute 直接失效
  • 禁止 Redirect 类型,防止同链路设备改写本机路由
  • IPv6 侧必须放行 ICMPv6 的 NS/NA/RS/RA,否则地址无法生效

易错点

  • ICMP 差错报文自身出错时不再回复 ICMP(防环规则),链路上有多个故障点时只会看到最靠前的一个
  • 安全策略一刀切禁 ping,会导致 PMTUD 失效,出现「网页打不开但 ping 正常」这类难以解释的现象
  • 把路由器的 ICMP 限速当成链路故障:丢包率虚高,实际业务流量一切正常
  • 在 IPv6 环境里禁用全部 ICMPv6,邻居发现瘫痪,地址配好了也上不了网

数据来源与参考

  • RFC 792(ICMP)
  • RFC 1122 §3.2.2

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌