IP 协议栈排障与攻击防御
分层排查法:从物理到应用
网络故障像看病,不能头痛医头。按 OSI 模型逐层排查,效率最高:
第 1 层 物理层:网线插了吗?光猫亮灯了吗?Wi-Fi 信号有吗?
第 2 层 链路层:MAC 地址正常?ARP 能解析到网关吗?交换机 VLAN 对吗?
第 3 层 网络层:IP 地址/掩码/网关正确?路由表有路吗?NAT 转换了吗?ACL 拦了吗?
第 4 层 传输层:端口通吗?TCP 握手成功吗?防火墙放行了吗?MSS 协商对了吗?
第 5~7 层 应用层:DNS 解析对吗?HTTP 返回什么码?TLS 证书过期了吗?
排障口诀:"物理先看灯,链路看 MAC,网络看路由,传输看端口,应用看日志。"
分层排查法的核心原则是从下到上、逐层验证。不要跳过层级直接怀疑应用层问题——如果 ARP 都解析不到网关,再完美的 HTTP 代码也发不出去。每一层验证通过后,再向上推进,直到定位故障点。
常见错误信息对应层级
| 错误信息 | 含义 | 排查层级 | 可能原因 |
|---|---|---|---|
| "Destination host unreachable" | 无法到达目标主机 | 网络/链路 | 网关问题、ARP 失败、子网掩码错误 |
| "Request timed out" | 请求超时 | 网络/传输 | 中间路由丢弃、防火墙拦截、路由环路 |
| "TTL expired in transit" | 传输中 TTL 耗尽 | 网络 | 路由环路、路径过长 |
| "Fragmentation required" | 需要分片 | 网络 | MTU 不匹配且 DF=1 |
| "Connection refused" | 连接被拒绝 | 传输 | 端口未监听、服务未启动 |
| "No route to host" | 没有到主机的路由 | 网络 | 路由表缺失、ACL 丢弃 |
| "DNS_PROBE_FINISHED_NXDOMAIN" | 域名不存在 | 应用 | DNS 解析失败、域名拼写错误 |
案例 1:错误子网掩码
PC A: 192.168.1.10/24(正确)
PC B: 192.168.1.20/16(错误,应为 /24)
PC B 认为 192.168.1.10 在同一子网(因为 /16 覆盖 192.168.0.0~192.168.255.255)
→ PC B 直接发 ARP 请求找 192.168.1.10
→ 如果中间有路由器隔离,ARP 广播过不去
→ PC B 收不到 ARP 响应 → "Destination host unreachable"
案例 2:错误网关
PC: 192.168.1.10/24,网关配成 192.168.1.254(实际网关是 192.168.1.1)
→ 访问外网时,包发给 192.168.1.254
→ 该 IP 不存在或不是路由器
→ ARP 失败 → "Destination host unreachable"
案例 3:ACL 阻断 ICMP
防火墙规则:deny icmp any any
→ ping 外网显示 "Request timed out"
→ 但 TCP 80 端口可能通(网页能打开)
→ 结论:网络层通,只是 ICMP 被过滤
案例 4:MTU 不匹配 + DF=1
VPN 隧道:内网 MTU 1500,VPN 封装后变成 1540,出接口 MTU 1500
→ 大包需要分片,但 DF=1
→ 路由器丢弃,返回 ICMP "需要分片"
→ 如果 ICMP 被防火墙拦截(ICMP 黑洞)
→ TCP 连接建立后,大包一直丢,小 ACK 能通 → 连接"半死不活"
→ 症状:能打开小网页,下载大文件卡住;SSH 能登录,ls 大量文件时卡住
解决:调整 VPN 接口 MTU 或启用 TCP MSS Clamping(修改 SYN 包中的 MSS 选项)。
案例 5:不对称路由
去程:A → R1 → R2 → B(经过状态防火墙 F1)
回程:B → R3 → R1 → A(不经过 F1)
F1 记录了 A→B 的会话表
但回程 B→A 没经过 F1,F1 没有这条会话
如果 F1 是严格状态检测,可能丢弃回程包
→ 现象:A 能发请求,但收不到回复(或部分回复)
IP 层攻击面与防御
1. IP 欺骗(IP Spoofing)
原理:伪造源 IP 地址发送数据包,隐藏真实身份或冒充他人。
防御:
- uRPF(Unicast Reverse Path Forwarding):严格模式下,路由器检查源 IP 是否应该从该接口进来。如果不是,丢弃。
- ACL:入口过滤,丢弃源地址明显非法的包(如公网接口收到 192.168.x.x 源地址)
2. Smurf 攻击
原理:向定向广播地址(如 192.168.1.255)发送 ICMP Echo Request,源地址伪造为受害者。子网内所有主机回复 Echo Reply,受害者被淹没。
防御:
- 路由器禁用定向广播:
no ip directed-broadcast - 入口过滤防止伪造源地址
3. Ping of Death / Teardrop
原理:
- Ping of Death:发送超过 65535 字节的畸形 IP 包(利用分片重组漏洞)
- Teardrop:发送重叠的分片偏移,导致重组时内存错误
防御:
- 补丁更新(现代系统已免疫)
- 防火墙丢弃异常分片
- 禁用分片或边界重组后检测
4. ICMP Redirect 劫持
原理:伪造 ICMP Redirect(Type 5)报文,告诉主机"下次走另一条路",把流量引向攻击者。
防御:
- 主机禁用 ICMP Redirect 接收:
sysctl -w net.ipv4.conf.all.accept_redirects=0 - 路由器禁用 ICMP Redirect 发送:
no ip redirects
5. 分片攻击(Tiny / Overlapping Fragments)
原理:
- 极小分片:第一个分片只含 IP 首部 + 少量数据,TCP/UDP 端口信息在第二个分片,绕过只检查首片的 ACL
- 重叠分片:后发的分片覆盖前发分片的偏移,导致重组结果异常,可能绕过 IDS 签名检测
防御:
- 现代防火墙重组所有分片后再检测
- 丢弃异常小的首片(首片至少包含完整传输层首部)
- 丢弃重叠分片
6. DHCP 欺骗 / 非法 RA
原理:
- DHCP 欺骗:私接 DHCP 服务器,分配错误网关/DNS
- 非法 RA:伪造 IPv6 路由器通告,下发虚假前缀,劫持流量
防御:
- DHCP Snooping:交换机信任端口允许 DHCP Offer,非信任端口丢弃
- RA Guard:交换机过滤非法 RA,只允许信任端口发送
- 发送频率限制:限制 RA 发送速率,防止 RA Flood
IP 层攻击的防御策略可以归纳为边界过滤 + 状态检测 + 端口安全。uRPF 和 ACL 在路由器入口防止伪造;DHCP Snooping 和 RA Guard 在交换机层面防止非法地址分配;现代防火墙通过分片重组和异常检测抵御分片攻击。这些措施组合使用,构成网络层纵深防御体系。
排障思维模型:从现象到根因
模型 1:二分法
通了吗?
├─ 不通 → 物理层?链路层?(看指示灯、ping 网关)
│ ├─ 网关不通 → 本地问题(IP/掩码/ARP/网线)
│ └─ 网关通 → 路由问题(tracert 看断在哪一跳)
└─ 通但慢/卡 → MTU?丢包?不对称路由?(ping -s 大包、MTR 测丢包)
模型 2:对比法
同一网络,A 能通,B 不能 → 对比 A 和 B 的 ipconfig、路由表、ARP 缓存
同一设备,昨天能通,今天不能 → 对比配置变更、补丁更新、DHCP 租约
模型 3:最小化法
怀疑防火墙?→ 临时关闭防火墙测试
怀疑 NAT?→ 内网直连测试
怀疑应用?→ 换协议测试(HTTP 不通试 ping,ping 不通试 ARP)
本篇小结
- 分层排查:物理 → 链路 → 网络 → 传输 → 应用
- "Destination host unreachable" 通常是本地/网关/ARP 问题
- "Request timed out" 通常是中间路由/防火墙/丢包问题
- MTU 不匹配 + ICMP 黑洞导致 TCP"半死不活"
- 不对称路由导致状态防火墙会话表不匹配
- 防御:uRPF 防 IP 欺骗、禁用定向广播防 Smurf、DHCP Snooping 防非法分配、RA Guard 防非法前缀
动手实践
故意修改错误子网掩码(如把 /24 改成 /16),观察对本地通信和跨网段通信的影响
用
ping -f -l 1473 8.8.8.8(Win)测试 MTU,然后逐步减小到通为止,计算路径 MTU用
mtr 8.8.8.8(Linux)或pathping 8.8.8.8(Win)观察每跳的丢包率和延迟在 Packet Tracer 中配置 ACL
deny icmp any any,测试 ping 和网页访问的差异查看本机是否接受 ICMP Redirect:
# Linux sysctl net.ipv4.conf.all.accept_redirects # 建议设为 0 sudo sysctl -w net.ipv4.conf.all.accept_redirects=0思考:为什么 "TTL expired in transit" 通常意味着路由环路?如果 traceroute 显示某一跳反复出现,如何确认是环路还是负载均衡导致的不同路径?