IP 实战与排错 — 网际协议
Wireshark IP 过滤式、ip/ping/traceroute/mtr 命令、MTU 黑洞与路由不对称排查 / 网络层 / RFC 791、RFC 8200
Table of Contents
这篇你能学到
- 看一眼 IP 头就能推断四件事:过了几跳、对端是什么操作系统、路径上有没有发生分片、是不是快撞上 MTU 上限了。
- 握住三把最有用的工具:
ip route get(让内核直接告诉你这个包会怎么走)、ping -M do -s(二分法量出真实路径 MTU)、mtr(定位丢包发生在第几跳)。 - 啃得动八类典型故障:MTU 黑洞(小包通大包断)、ping 通但业务不通、traceroute 满屏星号、地址变成 169.254、大量分片、三种 Unreachable 的区分、路由环路、多网卡回包走错。
1. 抓包观察
1.1 Wireshark 显示过滤式
这张表按用途分了几档:地址类用来框范围,TTL 类用来查环路和推 OS,分片/DF 类用来查 MTU 问题,协议号类用来按上层筛。排错起手式建议永远是
ip.addr == <目标>,它同时抓双向,比 src/dst 省事。
| 过滤式 | 作用 |
|---|---|
ip / ipv6 | 所有 IPv4 / IPv6 包 |
ip.addr == 10.0.0.5 | 与该地址相关的双向流量(排错首选,比 src/dst 更省事) |
ip.src == 10.0.0.5 && ip.dst == 8.8.8.8 | 单方向定向过滤 |
ip.addr == 192.168.1.0/24 | 整个网段 |
ip.ttl < 5 | TTL 即将耗尽,怀疑路由环路 |
ip.ttl == 64 || ip.ttl == 128 | 判断是否为直连(未经路由)流量、推断源端 OS |
ip.flags.df == 1 | 设置了 DF 的包(PMTUD 相关) |
ip.flags.mf == 1 || ip.frag_offset > 0 | 所有分片包(排查分片问题的标准式) |
ip.fragment.count > 1 | Wireshark 已重组的多片数据报 |
ip.len > 1500 | 超大包(可能是巨帧或 TSO/LRO 卸载导致的抓包假象) |
ip.proto == 6 / == 17 / == 1 / == 47 | 按上层协议筛:TCP / UDP / ICMP / GRE |
ip.dsfield.dscp == 46 | EF(语音)流量,QoS 验证 |
ip.dsfield.ecn == 3 | ECN CE 置位,路径出现拥塞 |
ip.checksum.status == "Bad" | 头部校验错误(注意:网卡校验卸载会产生大量误报,需在首选项中关闭校验验证) |
ip.hdr_len > 20 | 携带 IP Options 的包 |
icmp.type == 3 && icmp.code == 4 | Fragmentation Needed,MTU 问题的铁证 |
ipv6.nxt == 44 | IPv6 分片扩展头 |
ipv6.flow != 0 | 带流标签的 IPv6 包 |
捕获过滤式(BPF):host 10.0.0.5、net 192.168.1.0/24、ip proto 47、ip[6:2] & 0x3fff != 0(抓所有分片)。这些在抓包时就把无关流量丢掉,适合长时间挂机采集。
1.2 典型字段判读
下面这段是 Wireshark 展开一个 IPv4 头部的样子,右边的注释就是排错时该盯的位置——照着这几行看,一个包能告诉你的信息比想象中多得多:
| |
看 IP 头能得到的四条关键信息:
- TTL 推跳数与 OS:64→Linux/macOS,128→Windows,255→网络设备;
初值 − 实测值 = 跳数。 - DF + Total Length 接近 MTU → 排查 PMTUD/MTU 黑洞的信号。
- MF=1 或 Offset>0 → 路径上发生了分片,需评估丢包放大风险。
- 同一会话 TTL 忽高忽低 → 存在多路径(ECMP)或路由震荡。
2. 常用命令 / 配置
2.1 地址与接口(Linux,iproute2)
这组命令能干什么:看清"这台机器上有哪些地址、挂在哪块网卡、MTU 多大、有没有收发错误"。排 MTU 问题时改 MTU 那一行是关键操作;最后一条的 errors/dropped 计数则常常是物理层/驱动层问题的第一个线索。
| |
2.2 路由(排错核心)
这组命令能干什么:回答"这个包到底会往哪走"。重点是 ip route get——show 只是把规则列给你,还得自己脑补最长前缀匹配和策略路由;get 则直接让内核给出实际结论:选了哪个源 IP、下一跳是谁、从哪个口出去。多网卡、多路由表环境下,这一条能顶十条。
| |
2.3 连通性与路径探测
这组命令能干什么:分三件事。ping 测通不通;带 -M do -s 的 ping 是用二分法量出这条路最多能过多大的包(负载 + 28 就是 MTU);traceroute / mtr 则回答"路径长什么样、丢包丢在第几跳"。实战中优先用 traceroute -T -p 443,因为它走 TCP,最贴近真实业务路径,不容易被针对 UDP/ICMP 的限速误导。
| |
traceroute 结果判读要点:中间跳显示
* * *不一定是故障——很多路由器限速或禁用 ICMP Time Exceeded 回复。只有最后一跳不通才算真故障;中间某跳丢包但后续跳正常,也属正常现象(该跳只是控制平面响应慢,转发平面正常)。
2.4 抓包
这组命令能干什么:按不同维度把包捞出来。前两条按地址/网段捞;第三条 ip[6:2] & 0x3fff != 0 是抓所有分片包的标准写法(它直接看 Flags+Offset 那两个字节);第四条抓所有不可达报文,MTU 通知就藏在里面;最后一条按 TTL 小于 5 捞,专门用来查环路。
| |
2.5 Windows
这组命令能干什么:Windows 上做同样的三件事——看地址与路由、探测路径、处理 MTU。其中 pathping 相当于 tracert 加丢包统计(近似 mtr);ping -f -l 的 -f 就是 DF 位,等价于 Linux 的 -M do;最后两条用来查看和永久修改接口 MTU。
| |
3. 常见故障与排错
3.1 现象:小包能通,大包卡死(网页转圈、SSH 登录后一敲 ls 就挂)
先记住结论:“小包通、大包断"这八个字直接指向 MTU 黑洞,不要再怀疑"网络不稳定”。 根因是路径上有小 MTU 链路,而"你的包太大了"这条 ICMP 通知被防火墙吃掉了,发送方蒙在鼓里一直发大包。
这是 MTU 黑洞的典型特征,也是最容易被误判为"网络不稳定"的故障。
原因:路径中存在小 MTU 链路(VPN/GRE/PPPoE),而中间防火墙把 ICMP Type 3 Code 4 全部丢弃,发送方无法感知,持续发送超大包被静默丢弃。
排查:
三步走:先用二分法量出这条路真实能过多大的包,再抓包确认"包太大"的通知是不是根本没回来,最后从 TCP 重传特征上交叉验证。
| |
处置:调小接口 MTU(ip link set eth0 mtu 1400);在网关上做 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(根治手段,切勿一刀切丢弃 ICMP)。
3.2 现象:ping 得通但业务不通 / 单向能通
先记住结论:ping 通只证明"去程通、且对方愿意回 ICMP",什么都不能证明。 这类故障的头号原因是回程路由缺失——去得了回不来。所以排查要点是"双向各查一次",而不是盯着去程反复测。
| 可能原因 | 排查方法 |
|---|---|
| 回程路由缺失(最常见) | 在目标端 ip route get <客户端IP> 看回程走向;traceroute 双向各做一次对比 |
| 防火墙只放行了 ICMP | iptables -L -n -v、nft list ruleset、安全组规则 |
| 服务未监听或监听在 127.0.0.1 | ss -lntp 看 Local Address 是否为 0.0.0.0/:: |
| rp_filter 反向路径过滤丢包 | 多网卡不对称路由时被内核丢弃。sysctl net.ipv4.conf.all.rp_filter,改为 2(松散模式)或 0 |
| NAT/负载均衡改写地址导致回程走错 | 抓包对比进出包的源目地址是否符合预期 |
3.3 现象:traceroute 中间某跳开始全是 * * *,但业务正常
先记住结论:星号不等于故障,“转发"和"报到"是两回事。 路由器可以正常转发你的包,同时拒绝或限速回复 ICMP Time Exceeded——它只是不吭声,不是不干活。唯一的判断标准是最终目的通不通。
多数情况不是故障。路由器可能限速 ICMP、禁用 Time Exceeded 回复、或不响应 UDP 高端口探测。判断标准:最终目的是否可达。可换 traceroute -I(ICMP)或 traceroute -T -p 443(TCP)复测,TCP 模式最贴近真实业务路径。
3.4 现象:接口地址变成 169.254.x.x
先记住结论:看到 169.254 就等于"根本没拿到地址”。 这是 DHCP 失败后系统自己给自己编的一个临时链路本地地址(APIPA),不是网络配错了地址段。排查方向应全部集中在"DHCP 为什么没成功"。
原因:DHCP 获取失败,系统启用 APIPA(RFC 3927)链路本地地址。
排查:journalctl -u NetworkManager / dhclient -v eth0 看 DHCP 交互;抓包 tcpdump -i eth0 port 67 or port 68 确认 Discover 是否发出、有无 Offer;检查交换机端口 VLAN、DHCP 中继(ip helper-address)、地址池是否耗尽;若为 802.1X 环境,先确认端口已授权。
3.5 现象:出现大量 IP 分片,业务时快时慢
先记住结论:分片会把丢包影响放大好几倍——任何一片丢了,整个原始数据报都得重来。所以"时快时慢"的背后往往不是链路质量差,而是分片把本来能忍受的低丢包率放大成了严重问题。方向是消灭分片,而不是优化重传。
排查:tcpdump -v 'ip[6:2] & 0x3fff != 0' 统计分片量;Wireshark 过滤 ip.flags.mf==1。
危害:任一分片丢失整包作废,丢包率被放大数倍;重组占用内存;防火墙无法读取后续分片的端口信息。
处置:查明为何超 MTU(常见于 UDP 大包应用、DNS over UDP 大响应、VXLAN/GRE 隧道叠加开销、NFS 大 rsize/wsize);调小应用层报文或接口 MTU;TCP 场景做 MSS Clamping;DNS 场景启用 EDNS0 尺寸限制或回退 TCP。
3.6 现象:Destination Host Unreachable vs Destination Net Unreachable vs Request timed out
先记住结论:这几句报错各自指向完全不同的层次,看懂了就等于直接定位了故障范围——Host Unreachable 是本机二层没解析出来,Net Unreachable 是路由器没路可走,Port Unreachable 说明 IP 层其实已经通了,Time Exceeded 则是在绕圈。
| 报错 | 含义 | 定位方向 |
|---|---|---|
Destination Host Unreachable(本机发出) | 本机 ARP 解析不到下一跳 | 同网段 → 目标不在线/不同 VLAN;查 ip neigh |
Destination Net Unreachable(路由器回) | 路由器无到达该网段的路由 | 补路由或查路由协议邻居状态 |
Destination Port Unreachable(ICMP 3/3) | IP 层通了,但对端该 UDP 端口无监听 | 检查服务是否启动、端口是否正确 |
Request timed out / 无响应 | 包发出去了但无回应 | 防火墙静默丢弃、回程路由缺失、目标禁 ICMP |
Time to live exceeded | TTL 归零 | 路由环路或跳数确实超过 TTL 初值 |
3.7 现象:TTL 异常小 / traceroute 出现地址来回跳动
先记住结论:两个地址交替出现 = 路由环路,几乎没有别的解释。 包在两台设备之间来回推诿,直到 TTL 耗尽。根因在配置,不在链路。
原因:路由环路(静态路由配错、动态路由收敛异常、双向重分发未做防环)。
排查:mtr 看是否有两跳交替出现;各跳 ip route get <目的IP> 逐台确认下一跳指向;检查路由重分发与路由过滤策略。
3.8 现象:多网卡服务器回包走错网卡
先记住结论:根因是"回包只看目的地址查同一张全局路由表",它压根不知道请求是从哪块网卡进来的。 想让"从哪进就从哪出",必须用策略路由给每张网卡配一张独立路由表。
原因:Linux 弱主机模型 + 单一路由表,回包按目的地址查全局路由表,可能选到另一张网卡。
处置:用策略路由为每张网卡建独立路由表:
4. 与其他协议对比
| 维度 | IP | ARP | ICMP | TCP | UDP |
|---|---|---|---|---|---|
| 所属层 | 网络层 | 数据链路层 | 网络层(依附 IP) | 传输层 | 传输层 |
| 职责 | 寻址 + 路由转发 | IP→MAC 解析 | 差错与控制报告 | 可靠有序字节流 | 无连接数据报 |
| 是否有端口 | 否(用 Protocol 号) | 否 | 否(用 Type/Code) | 是(16 位) | 是(16 位) |
| 可靠性 | 不可靠、尽力而为 | 不可靠 | 不可靠 | 可靠(确认+重传) | 不可靠 |
| 连接状态 | 无连接无状态 | 无连接 | 无连接 | 面向连接(三次握手) | 无连接 |
| 头部大小 | IPv4 20–60 / IPv6 40 | 28(报文体) | 8 + 数据 | 20–60 | 8 |
| 关键字段 | TTL / Protocol / 分片 | OPER / SHA / SPA | Type / Code | 序号 / 确认号 / 窗口 | 长度 / 校验和 |
| 对应 RFC | 791 / 8200 | 826 | 792 / 4443 | 9293 | 768 |
IPv4 与 IPv6 关键差异(排错视角):IPv6 无广播(ping ff02::1%eth0 代替广播 ping)、无中间分片、地址解析看 ip -6 neigh、必须放行 ICMPv6(禁 ICMPv6 会直接导致 IPv6 网络瘫痪,因为 NDP、PMTUD、MLD 全靠它)。
5. 速查表 / 常见面试题
5.1 速查
| 记忆点 | 值 |
|---|---|
| IPv4 头部长度 | 20–60 字节(IHL×4) |
| IPv6 头部长度 | 固定 40 字节 |
| Total Length 上限 | 65535 |
| 以太网 MTU / MSS | 1500 / 1460 |
| IPv6 最小 MTU | 1280 |
| Protocol 号 | 1 ICMP,2 IGMP,6 TCP,17 UDP,47 GRE,50 ESP,51 AH,58 ICMPv6,89 OSPF |
| TTL 初值 | Linux/macOS 64,Windows 128,网络设备 255 |
| 分片偏移单位 | 8 字节 |
| 私有地址 | 10/8、172.16/12、192.168/16 |
| APIPA | 169.254.0.0/16 |
| 最有用的一条命令 | ip route get <目的IP> |
| MTU 探测 | ping -M do -s <负载>(负载 + 28 = MTU) |
5.2 常见面试题
Q1:数据包从 A 到 B 的过程中,源/目的 IP 和 MAC 分别怎么变化? IP 端到端不变(NAT 除外),MAC 逐跳改写。每一跳路由器解封装、查路由、用 ARP 解析新的下一跳 MAC 后重新封装。
Q2:路由器如何选路?多条路由都匹配时怎么办? 按最长前缀匹配:掩码最长者优先。前缀相同时再比管理距离(直连 0 < 静态 1 < OSPF 110 < RIP 120),再比 metric,仍相同则 ECMP 负载分担。
Q3:TTL 的作用?为什么 traceroute 能画出路径? TTL 防环,每跳减 1,归零丢弃并回 ICMP Time Exceeded。traceroute 依次发 TTL=1,2,3… 的包,让沿途每台路由器依次"报到",从而逐跳还原路径。
Q4:DF 位是什么?置 1 时包过大会发生什么? Don’t Fragment。置 1 时路由器不得分片,遇到 MTU 不足直接丢弃并回 ICMP Type 3 Code 4(携带下一跳 MTU),发送方据此执行 PMTUD 调小报文。若该 ICMP 被防火墙拦截,就形成 MTU 黑洞。
Q5:为什么分片偏移以 8 字节为单位? Fragment Offset 只有 13 位,而 Total Length 有 16 位。13 位无法直接表达 65535 的偏移范围,故以 8 字节(2³)为粒度:13+3=16 位,恰好覆盖。代价是除最后一片外各片长度必须是 8 的倍数。
Q6:分片重组在哪里做?为什么不在中间路由器做? 只在目的主机做。中间路由器若重组需维护大量状态、缓存分片、等待超时,严重影响转发性能与可扩展性;且各分片可能走不同路径,中间节点未必能收齐。
Q7:IPv6 为什么取消头部校验和? 链路层 FCS 已做错检、传输层校验和覆盖端到端数据(含伪首部),头部校验和属于冗余,且每跳都要因 Hop Limit 变化而重算,是纯粹的性能负担。副作用是 IPv6 下 UDP 校验和变为强制。
Q8:/24 网段有多少可用主机?/30 呢?为什么减 2?
/24:2⁸−2 = 254;/30:2²−2 = 2(点对点链路)。减去的是网络地址(主机位全 0)与广播地址(主机位全 1)。特例:/31(RFC 3021)用于点对点链路时可用 2 个地址,/32 用于主机路由。
Q9:看到 169.254.x.x 说明什么?
DHCP 获取地址失败,系统回落到 APIPA 链路本地地址。排查方向:DHCP 服务/地址池、VLAN 配置、DHCP 中继、802.1X 是否已授权。
Q10:IP 是不可靠的,为什么互联网还能可靠传输文件? 端到端原则:IP 保持简单(无状态、尽力而为)以获得极致的可扩展性与异构兼容性,把可靠性(确认、重传、排序、去重)与拥塞控制交给端系统的 TCP。网络核心简单、智能在边缘,这正是互联网成功的架构基石。
Q11:为什么不能把 ICMP 全部禁掉? 会破坏 PMTUD(Type 3 Code 4)造成 MTU 黑洞,破坏路径诊断能力;在 IPv6 下更严重——ICMPv6 承载 NDP、MLD、PMTUD,全禁会直接导致 IPv6 网络不可用。正确做法是按 Type/Code 精细放行,并对速率做限制。
Q12:ip route get 8.8.8.8 比 ip route show 好在哪?
show 只是列出规则,需要人脑做最长前缀匹配和策略路由推演;get 直接让内核给出实际决策结果——选中的源 IP、下一跳、出接口,在多网卡、多路由表、策略路由环境下能一步锁定问题。