4、ICMP与网络诊断:报文类型、Ping与Traceroute原理、重定向与超时、实战故障排查
ICMP,全称 Internet Control Message Protocol,互联网控制报文协议。说白了,它是 TCP/IP 协议栈里的“信使”。IP 协议本身只管尽力送,不负责反馈。路不通了、包丢了、超时了,谁来告诉你?就是 ICMP。
我刚开始做网络运维时,总觉得 ICMP 就是 Ping 一下,没什么技术含量。直到有一次线上故障,Ping 通但业务连不上,排查了三天才发现是 ICMP 重定向搞的鬼。从那以后,我再也不敢小看这个“小协议”了。
4.1 ICMP 报文类型与格式
ICMP 报文分为两大类:差错报告报文和查询报文。差错报文用来报告网络问题,查询报文用来获取网络状态。
先看报文格式。所有 ICMP 报文都有一个统一的头部:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Rest of Header (取决于类型) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type 和 Code 共同决定报文的具体含义。Checksum 校验整个 ICMP 报文。Rest of Header 则根据类型不同而不同。
下面这张表是我工作中最常用的几个 ICMP 类型,建议你记下来:
| Type | Code | 含义 | 典型场景 |
|---|---|---|---|
| 0 | 0 | Echo Reply | Ping 响应 |
| 3 | 0-15 | Destination Unreachable | 目标不可达(网络、主机、端口、协议等) |
| 5 | 0-3 | Redirect | 重定向(改变路由) |
| 8 | 0 | Echo Request | Ping 请求 |
| 11 | 0-1 | Time Exceeded | TTL 超时(Traceroute 核心) |
4.2 Ping 与 Traceroute 原理
Ping 和 Traceroute 是网络工程师的两把瑞士军刀。它们都基于 ICMP,但原理完全不同。
Ping:连通性测试
Ping 的原理很简单:发送 ICMP Echo Request(Type 8),等待 ICMP Echo Reply(Type 0)。如果收到回复,说明目标可达;如果收不到,说明中间出了问题。
Ping 还能测量 RTT(往返时延)。发送时记录时间戳,收到回复时计算差值。我经常用这个来判断链路质量。
# 基本 Ping 测试
ping 8.8.8.8
# 指定次数和间隔(Linux)
ping -c 5 -i 0.5 8.8.8.8
# 指定数据包大小(测试 MTU 问题)
ping -M do -s 1472 8.8.8.8
Traceroute:路径追踪
Traceroute 的原理更巧妙。它利用 ICMP Time Exceeded(Type 11)报文来探测路径上的每一跳。
具体做法是:
- 发送一个 TTL=1 的 UDP 包(或 ICMP Echo Request)到目标。
- 第一跳路由器收到后,TTL 减为 0,丢弃包,并回复 ICMP Time Exceeded。
- 发送方从回复中拿到第一跳的 IP 地址。
- 然后发送 TTL=2 的包,拿到第二跳。
- 以此类推,直到到达目标。
Windows 的 tracert 默认用 ICMP Echo Request,Linux 的 traceroute 默认用 UDP。我个人习惯用 Linux 的 traceroute,因为它能显示更多细节。
# Linux 下追踪路径
traceroute -n 8.8.8.8
# 使用 ICMP 模式(绕过某些防火墙)
traceroute -I 8.8.8.8
# Windows 下追踪路径
tracert -d 8.8.8.8
4.3 ICMP 重定向与超时
这两个机制在实际网络中非常常见,但很多人容易忽略。
ICMP 重定向(Type 5)
当主机把包发给了错误的网关,正确的网关会发一个 ICMP Redirect 报文,告诉主机:“你应该把包发给另一个网关。”
举个例子:主机 A 的默认网关是 R1,但目标网络的最佳下一跳是 R2。A 把包发给 R1,R1 查路由表发现应该走 R2,于是 R1 转发包的同时,给 A 发一个 Redirect,告诉 A 以后直接发给 R2。
net.ipv4.conf.all.accept_redirects = 0。生产环境建议关闭这个功能,防止被恶意利用。
ICMP 超时(Type 11)
超时分两种:
- Code 0:TTL 超时 —— 路由器转发时 TTL 减为 0,丢弃并通知源端。
- Code 1:分片重组超时 —— 接收端等待分片超时,无法重组完整包。
TTL 超时是 Traceroute 的基础。分片重组超时则常见于 MTU 不匹配的场景。我遇到过几次,大包传输时某些链路 MTU 太小,分片后重组超时,导致连接中断。
4.4 实战:网络故障排查
理论讲完了,咱们来点实战。下面是我总结的一套 ICMP 故障排查流程,用一张图来展示:
下面是一个真实案例,我把它拆解成步骤:
场景: 用户反馈无法访问公司内网服务器 10.0.0.100。
- 第一步:Ping 目标 —— 超时,无回复。
- 第二步:Ping 网关 —— 网关 10.0.0.1 正常回复。
- 第三步:Traceroute —— 发现到 10.0.0.100 的路径在第三跳后中断。
- 第四步:抓包分析 —— 在第三跳路由器上抓包,发现它发出了 ICMP Destination Unreachable(Type 3, Code 1,主机不可达)。
- 结论: 第三跳路由器没有到 10.0.0.100 的路由,或者目标主机宕机。
tcpdump -i eth0 icmp -nn
嗯,ICMP 这部分就讲到这里。记住,ICMP 是网络诊断的基石。Ping 和 Traceroute 只是它的两个应用。真正的高手,会直接看 ICMP 报文里的 Type 和 Code,结合路由表和防火墙策略,快速定位问题。