ICMP 实战与排错 — 互联网控制报文协议
Wireshark ICMP 过滤式、ping/traceroute/mtr/hping3 实操、ping 不通与 MTU 黑洞排查 / 网络层 / Protocol=1 / RFC 792
Table of Contents
这篇你能学到
- 怎么用 Wireshark / tcpdump 的过滤式,一眼揪出 Type/Code,把"报错回执"翻译成故障原因;
ping/traceroute/mtr/hping3各在什么场景用、输出该怎么读(尤其是"中间跳丢包≠故障"这个坑);- “ping 不通"“能 ping 不能连"“小包通大包不通"等八类故障的排查套路,以及 ICMP/ICMPv6 该放行还是该禁。
1. 抓包观察
1.1 Wireshark 显示过滤式
| 过滤式 | 作用 |
|---|---|
icmp / icmpv6 | 所有 ICMP / ICMPv6 报文 |
icmp.type == 8 | Echo Request(谁在 ping 谁) |
icmp.type == 0 | Echo Reply |
icmp.type == 8 || icmp.type == 0 | 完整 ping 会话 |
icmp.type == 3 | 所有目的不可达(排错第一刀) |
icmp.type == 3 && icmp.code == 1 | 主机不可达(下一跳 ARP 失败) |
icmp.type == 3 && icmp.code == 3 | 端口不可达(UDP 无监听 / traceroute 终点) |
icmp.type == 3 && icmp.code == 4 | 需分片但 DF 置位 → MTU 问题铁证 |
icmp.type == 3 && icmp.code == 13 | 被防火墙/ACL 明确拒绝 |
icmp.type == 11 | Time Exceeded(traceroute 或路由环路) |
icmp.type == 5 | ICMP 重定向(可能是攻击) |
icmp.mtu | 直接显示 Next-Hop MTU 字段值 |
icmp.ident == 0x1234 | 按 Identifier 追踪某个 ping 进程 |
icmp.seq > 100 | 长时间 ping 的后段 |
icmp.resp_not_found | 有请求无应答——Wireshark 自动标记,找丢包极快 |
icmp.resptime > 100 | RTT 超过 100 ms 的应答,定位高延迟 |
data.len > 1000 | 异常大载荷的 ICMP,怀疑 ICMP 隧道 |
icmpv6.type == 2 | IPv6 Packet Too Big(IPv6 的 MTU 问题) |
icmpv6.type == 135 || icmpv6.type == 136 | NDP 邻居请求/通告(IPv6 版 ARP) |
icmpv6.type == 134 | 路由器通告 RA(SLAAC 排错) |
捕获过滤式(BPF):icmp、icmp[icmptype] == 8、icmp[icmptype] == 3、icmp6。
1.2 典型字段判读
成功的 ping:
| |
一条差错报文(信息量远大于 ping 成功):
| |
判读三要点:
- 外层源 IP = 谁在报错,直接锁定故障设备;
- 内层原始 IP 头 + 端口 = 哪条连接出的问题,能精确对应到业务;
- Type/Code 组合 = 原因,见速查表。
2. 常用命令 / 配置
2.1 ping
这组命令能干什么:回答"目标到底通不通、RTT 多少、走过了几跳、能不能扛大包”。-c 限定个数(Linux 默认无限,必加)、-s 调载荷大小、-M do 强制 DF=1 用来探 MTU、-t 指定 TTL 看第几跳、-I 指定出接口或源地址。
| |
输出判读:
ttl=113→ 初值大概率 128(Windows 系)或 120(部分设备),128−113 = 经过 15 跳;icmp_seq跳号 → 丢包;乱序 → 多路径或链路抖动;time波动剧烈 → 拥塞、无线干扰或 CPU 处理慢(网络设备对 ICMP 常是低优先级软件转发,RTT 高不一定代表转发平面差)。
2.2 traceroute / mtr
这组命令能干什么:traceroute 回答"数据包到你家要经过哪几跳、卡在哪一跳”;mtr 则是 traceroute + 持续丢包统计,专门用来定位"丢包到底发生在哪一跳”。-I 走 ICMP、-T -p 走 TCP 最贴近真实业务、-n 不反解 DNS 更快。
| |
mtr 结果判读的关键陷阱:某中间跳显示 30% 丢包、但后续跳都是 0%,说明该跳只是对 ICMP 限速(控制平面),转发平面完全正常,不是故障。只有从某跳开始丢包一路持续到最后一跳,才说明问题出在那里。
2.3 抓包
这组命令能干什么:在网卡层面"听诊"真实流量,确认你发的 ICMP 到底有没有、收到的是哪类差错、有没有被中途吃掉。tcpdump 的 icmp[icmptype] 表达式能精准只抓某类报文;tshark 那行用来统计各类 ICMP 的数量分布。
| |
2.4 构造与压测:hping3 / nping
这组命令能干什么:当你需要"自己造"一个特定 ICMP 包(比如指定 Type、指定载荷长度)来测防火墙策略,或当 ICMP 被禁时改用 TCP SYN 探活,hping3 / nping 就派上用场了。
| |
2.5 系统与防火墙配置
这份配置能干什么:查看/调整 Linux 对 ICMP 的响应行为(禁不禁 ping、接不接重定向、开不开 PMTUD、PMTU 下限防伪造),以及用 iptables 做"精细放行"——放行诊断必需的 Type,丢弃危险的 Type 5/13/17,而不是一刀切 DROP。
| |
Cisco 侧对应的放行配置能干什么:在路由器/交换机上把 ICMPv4 必要的几类放行(echo-reply、packet-too-big 等价 Type3 Code4、time-exceeded、unreachable),关掉重定向和定向广播以堵安全洞;注意 no ip unreachables 要慎用——它会让 traceroute 失效。
| |
2.6 Windows
Windows 上的对应命令能干什么:和 Linux 同款思路——-f 即 DF、-l 指载荷,用来探 MTU;tracert/pathping 看路径与丢包;Test-NetConnection 做综合连通性测试;netsh 那行在 Windows 防火墙放行 ICMPv4 Echo。
| |
3. 常见故障与排错
3.1 现象:ping 不通
先记住结论:排查 ping 不通,第一步永远是看输出里有没有 From <IP> 前缀——有前缀说明收到了明确的 ICMP 差错报文、可直接定位到报错设备;没有前缀就是纯静默丢弃,排查面大得多。这一步决定后续所有方向。
| ping 输出 | 含义 | 下一步 |
|---|---|---|
From 192.168.1.1 Destination Net Unreachable | 该路由器无路由 | 在该设备上 ip route get <目的IP>,补路由或查路由协议邻居 |
From 10.0.0.1 Destination Host Unreachable | 最后一跳ARP 不到目标 | 目标是否开机、是否同 VLAN、ip neigh 查邻居表 |
Destination Host Unreachable(无 From) | 本机ARP 不到下一跳 | 检查网关配置、本机 ip neigh show <网关> |
From x.x.x.x Communication prohibited | 被 ACL 明确拒绝 | 定位该设备的防火墙/ACL 规则 |
Request timed out / 100% packet loss | 静默丢弃 | ① 目标禁 ping(icmp_echo_ignore_all=1)② 防火墙 DROP ③ 回程路由缺失 |
ping: unknown host | DNS 解析失败 | 与 ICMP 无关,查 /etc/resolv.conf、dig |
“ping 不通但业务正常"很常见——大量服务器与云安全组默认禁 ICMP。此时应改用 TCP 探活验证:
3.2 现象:ping 通但业务连不上
先记住结论:ICMP 走通只证明三层可达,一丁点都不能说明四层端口可用——业务连不上几乎都是目标端口没监听、或被防火墙只放行了 ICMP 而拦了业务端口。
排查顺序:nc -zv <IP> <端口> 测端口 → 目标端 ss -lntp 确认服务在监听且不是只绑 127.0.0.1 → 检查防火墙/安全组是否只放行了 ICMP → 抓包看 TCP SYN 是否有 SYN-ACK 或 RST 回应。
3.3 现象:小包通、大包不通(MTU 黑洞)——最经典的疑难杂症
先记住结论:“小包通、大包不通"这八个字,直接指向 MTU 黑洞——根因几乎都是 ICMP Type 3 Code 4 被防火墙丢了,发送方永远收不到"包太大、请分片"的通知,于是死循环地发大包、被丢、再发。
| |
处置:调小接口 MTU;网关做 MSS Clamping(iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu);根治是放行 ICMP Type 3 Code 4。
3.4 现象:traceroute 中间跳全是 * * *
先记住结论:中间跳全是 * * * 绝大多数不是故障——通常是路由器禁了/限速了 ICMP Time Exceeded 回复,或不响应 UDP 高端口探测。判定标准只有一个:最后一跳能否到达。
判定标准:最后一跳能否到达。可换探测方式复测:traceroute -I(ICMP)、traceroute -T -p 443(TCP,最贴近业务)。若三种方式最后一跳都不通,才是真故障。
3.5 现象:收到大量 ICMP Type 11(TTL 超时)
先记住结论:大量 Type 11 是路由环路的典型信号——包在两台(或多台)设备之间被互相当作下一跳,永远到不了目的地,直到 TTL 归零不断产生 Time Exceeded。
排查:mtr 观察是否有两个 IP 交替出现;在环路涉及的每台设备上执行 ip route get <目的IP> 逐跳确认下一跳;检查静态路由配置错误、动态路由双向重分发未做防环(tag 过滤)、路由收敛中的瞬时环路。
3.6 现象:主机路由表莫名多出条目 / 流量被劫持
先记住结论:主机路由表莫名多出条目、或流量被引向陌生网关,多半是收到了 ICMP 重定向(Type 5)——可能是网络在"好心"优化路径,也可能是中间人攻击在劫持流量。
排查与处置:tcpdump -i eth0 'icmp[icmptype]==5' 看谁发的;ip route show cache 查看重定向产生的缓存路由;关闭接受:sysctl -w net.ipv4.conf.all.accept_redirects=0。
3.7 现象:RTT 很高但业务不慢
先记住结论:ping 延迟高、业务却不慢,通常是因为网络设备把 ICMP 交给 CPU 软件转发(控制平面),优先级低于硬件转发的数据流量——CPU 一忙 ping 就飙高,但实际数据转发毫无影响。
验证:用 TCP 层面的延迟做对照,如 curl -w '%{time_connect}\n'、mtr -T -P 443,若 TCP 延迟正常则可排除真实性能问题。
3.8 现象:IPv6 完全不通,ping6 无响应,邻居状态 FAILED
先记住结论:IPv6 完全不通、邻居状态 FAILED,首要怀疑 ICMPv6 被防火墙全量拦截——因为 NDP(地址解析)、RA(地址自动配置)、MLD(组播)、PMTUD 全部依赖 ICMPv6,全禁等于直接拔网线。
4. 与其他协议对比
| 维度 | ICMP | IP | ARP | IGMP | TCP/UDP |
|---|---|---|---|---|---|
| 所属层 | 网络层(封装于 IP) | 网络层 | 数据链路层 | 网络层(封装于 IP) | 传输层 |
| 职责 | 差错报告 + 诊断 | 寻址与转发 | IP→MAC | 组播成员管理 | 端到端数据传输 |
| 标识方式 | Type + Code | Protocol 号 | Operation 码 | Type | 端口号 |
| Protocol 号 | 1(v6 为 58) | — | — | 2 | 6 / 17 |
| 可靠性 | 不可靠,无重传 | 不可靠 | 不可靠 | 不可靠 | TCP 可靠 / UDP 不可靠 |
| 是否有连接 | 无 | 无 | 无 | 无 | TCP 有 / UDP 无 |
| RFC | 792 / 4443 | 791 / 8200 | 826 | 1112 / 2236 / 3376 | 9293 / 768 |
ICMPv4 与 ICMPv6 的核心差异:
| 维度 | ICMPv4 | ICMPv6 |
|---|---|---|
| Protocol / Next Header | 1 | 58 |
| Type 划分 | 无规律 | 0–127 差错,128–255 信息 |
| 校验和 | 不含伪首部 | 包含 IPv6 伪首部 |
| 承担职责 | 仅差错与诊断 | 差错诊断 + NDP + MLD + PMTUD |
| 能否全禁 | 可以(代价是失去 PMTUD) | 绝对不能,会导致网络瘫痪 |
| 分片相关 | Type 3 Code 4 | Type 2 Packet Too Big |
5. 速查表 / 常见面试题
5.1 速查
| 记忆点 | 值 |
|---|---|
| IP Protocol 号 | 1(ICMPv6 = 58) |
| Echo Request / Reply | Type 8 / 0 |
| 目的不可达 | Type 3 |
| TTL 超时 | Type 11 Code 0 |
| MTU 不足 | Type 3 Code 4(含 Next-Hop MTU) |
| UDP 端口无监听 | Type 3 Code 3 |
| 防火墙拒绝 | Type 3 Code 13 |
| 差错报文携带 | 原始 IP 头 + 前 8 字节数据 |
| IPv6 Packet Too Big | ICMPv6 Type 2 |
| IPv6 NDP | ICMPv6 Type 135/136(NS/NA) |
| MTU 探测 | ping -M do -s <载荷>,载荷 + 28 = MTU |
| 必须放行 | Type 3 Code 4,否则 MTU 黑洞 |
5.2 常见面试题
Q1:ping 用的是什么协议?工作在哪一层? ICMP,网络层。ICMP 报文封装在 IP 数据报中(Protocol=1),不使用端口——ping 的"端口"是不存在的概念。
Q2:traceroute 的原理是什么?为什么中间跳会显示 * * *?
依次发送 TTL=1,2,3… 的探测包,每台路由器在 TTL 归零时回 ICMP Type 11,从而逐跳还原路径。* * * 通常是该路由器禁用或限速了 ICMP Time Exceeded 回复,不代表链路故障——只要最终目的可达即可。
Q3:Linux traceroute 默认用 UDP,怎么知道到达终点了?
探测目标的高端口(33434 起,通常无人监听),目标主机回 ICMP Type 3 Code 3(Port Unreachable),即判定到达。Windows tracert 用 ICMP Echo,收到 Echo Reply 判定终点;TCP 模式则看 SYN-ACK/RST。
Q4:为什么 ICMP 差错报文要带原始 IP 头 + 8 字节数据? 让源主机能定位是哪条连接出的错。前 8 字节包含 TCP/UDP 的源端口与目的端口,加上 IP 头的源目地址与协议号,恰好构成五元组,内核据此把错误投递给正确的套接字。
Q5:Destination Host Unreachable 和 Request timed out 有什么区别?
前者收到了明确的 ICMP 差错报文,说明路径上某设备主动告知无法投递(可据 From 后的 IP 直接定位故障点);后者什么都没收到,说明包被静默丢弃或回程不通,排查面更大。
Q6:为什么不能把 ICMP 全部禁掉? ① 破坏 PMTUD(Type 3 Code 4 被丢 → MTU 黑洞,小包通大包死);② 失去 ping/traceroute 诊断能力;③ IPv6 下更致命——ICMPv6 承载 NDP/MLD/PMTUD,全禁直接导致网络不可用。正确做法:按 Type/Code 精细放行 + 限速。
Q7:Type 3 Code 4 的作用?为什么它这么重要? “需要分片但 DF 置位”。它携带 Next-Hop MTU 字段,是 IPv4 PMTUD 的唯一信息来源。被拦截即形成 MTU 黑洞——生产环境最难查的故障之一。
Q8:ICMP 重定向是做什么的?为什么通常关闭?
路由器发现主机选的下一跳不是最优(且最优下一跳与主机同网段)时发出提示。因为攻击者可伪造 Redirect 把主机流量引向自己实现中间人,所以现代系统普遍 accept_redirects=0。
Q9:ping 通了能说明业务正常吗?
不能。ping 只验证三层可达,不能说明目标端口有服务在监听、四层策略是否放行、应用是否健康。应用 nc -zv、curl、telnet 等做四层/七层验证。
Q10:mtr 显示中间某跳丢包 30%,是不是那台设备有问题? 不一定。如果后续跳丢包为 0,说明该跳只是对 ICMP 响应限速(控制平面低优先级),转发平面正常。只有从某跳起丢包一路持续到最后一跳,才指向真实故障。
Q11:为什么 ICMPv6 的重要性远高于 ICMPv4? ICMPv6 不只报错,还吸收了 IPv4 中 ARP(→NDP Type 135/136)与 IGMP(→MLD Type 130-132/143)的全部职责,并且是 IPv6 PMTUD(Type 2)的唯一途径。禁掉 ICMPv6 等于同时禁掉了地址解析、地址自动配置和组播。
Q12:为什么 ICMP 不对 ICMP 差错报文再产生差错报文? 防止无限循环与放大风暴:若 A 的差错报文触发 B 回一个差错报文,B 的又触发 A…… 网络会被瞬间淹没。RFC 1122 同时禁止对广播/组播包、非首片、非单播源产生差错报文,都是出于同样的防放大考虑。