3、ARP协议排错:从请求到欺骗,再到缓存超时

ARP协议,说白了就是IP地址和MAC地址之间的翻译官。没有它,数据包在局域网里根本找不到路。我刚开始做网络运维那会儿,觉得ARP就是个自动完成的小透明,直到有一次整个办公区断网半小时……嗯,从那以后我再也不敢小看它了。

这一章,我们就把ARP协议从头到尾拆一遍。包括请求应答怎么走、ARP表怎么看、欺骗攻击怎么查、缓存超时怎么调。全是实战里高频踩坑的点。

3.1 ARP请求与应答过程

先看一个最简单的场景:主机A(192.168.1.10)想和主机B(192.168.1.20)通信。A知道B的IP,但不知道B的MAC地址。这时候ARP就上场了。

流程其实就四步:

  1. A构造ARP请求:目标MAC填全F(FF:FF:FF:FF:FF:FF),广播出去。
  2. 交换机转发广播:所有端口都收到这个请求。
  3. B回应ARP应答:B发现问的是自己,就单播回复自己的MAC地址。
  4. A更新ARP表:把B的IP和MAC对应关系缓存起来。

关键点:ARP请求是广播,ARP应答是单播。这个区别很多人搞混。我在一次排障中遇到过,抓包发现只有请求没有应答,结果是因为B的防火墙把ARP应答过滤了。

下面这张图把整个过程画清楚了:

ARP请求与应答流程 主机A 192.168.1.10 交换机 广播转发 主机B 192.168.1.20 ① ARP请求(广播) ② 广播到B ③ ARP应答(单播) 抓包要点: • ARP请求:Opcode=1,目标MAC全F • ARP应答:Opcode=2,目标MAC为请求方MAC • 正常情况:请求→应答间隔通常小于1ms

3.2 ARP表查看与分析

ARP表是排错的第一手资料。你想想看,如果通信不通,第一件事就是查ARP表里有没有对方的记录。

不同系统的查看命令:

系统 命令 说明
Windows arp -a 显示所有ARP条目
Linux ip neigh 或 arp -n 推荐用 ip neigh,更现代
macOS arp -a 和Windows类似
华为交换机 display arp 查看设备ARP表
Cisco交换机 show ip arp 查看设备ARP表

举个例子,我在Linux上执行 ip neigh 的输出:

192.168.1.1 dev eth0 lladdr 00:11:22:33:44:55 REACHABLE
192.168.1.20 dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE
192.168.1.100 dev eth0 lladdr 11:22:33:44:55:66 DELAY

这里有几个状态需要关注:

  • REACHABLE:正常可达,刚通信过。
  • STALE:条目过期了,但还没删除。下次通信会先发单播探测。
  • DELAY:正在等待确认,如果没回应就变PROBE。
  • FAILED:解析失败,对方不可达。

我的习惯:排错时先看目标IP在不在ARP表里。如果在且状态是REACHABLE,那问题大概率不在二层。如果不在或状态是FAILED,那就从ARP层面往下查。

3.3 ARP欺骗攻击排查

ARP欺骗,说白了就是有人冒充网关。攻击者发送伪造的ARP应答,告诉所有主机“网关的MAC地址是我”。然后所有流量都经过攻击者,他就能抓包、篡改、甚至劫持。

我曾经处理过一个真实案例:某公司财务部反映网银页面偶尔弹出证书错误。查了半天,发现是内网有人用ARP欺骗做了中间人攻击。最后定位到一台中了病毒的员工电脑。

排查方法我总结成三步:

  1. 对比ARP表:在多个主机上查网关的MAC地址,看是否一致。
  2. 抓包分析:用Wireshark过滤 arp,看有没有大量重复的ARP应答。
  3. 静态绑定:临时在网关和关键主机上做静态ARP绑定,验证是否恢复。

抓包时重点关注这些特征:

特征 正常情况 欺骗攻击
ARP应答频率 偶尔,有请求才应答 每秒几十甚至上百个
源MAC一致性 与发送方真实MAC一致 伪造的MAC地址
IP-MAC映射 稳定不变 同一个IP对应多个MAC

注意:不要在生产环境随意做静态ARP绑定,除非你确认没有DHCP和动态环境。我曾经见过有人把整网段的ARP都静态绑了,结果新加一台设备死活不通……

3.4 ARP缓存超时问题

ARP缓存不是永久有效的。每个条目都有生存时间(TTL),超时后会被删除或标记为STALE。这个机制本身没问题,但超时时间设置不合理就会引发故障。

常见场景:

  • 超时太短:频繁触发ARP请求,增加网络开销,甚至导致丢包。
  • 超时太长:设备更换网卡后,其他主机长时间无法通信。

各系统的默认超时时间:

系统 默认超时 可调参数
Windows 15-45秒(动态) 注册表 ArpCacheLife
Linux 30秒(REACHABLE) /proc/sys/net/ipv4/neigh/default/gc_stale_time
Cisco交换机 14400秒(4小时) arp timeout 命令

举个例子,Linux下调整超时时间:

# 查看当前值
cat /proc/sys/net/ipv4/neigh/default/gc_stale_time

# 临时修改为60秒
echo 60 > /proc/sys/net/ipv4/neigh/default/gc_stale_time

# 永久修改(写入sysctl.conf)
echo "net.ipv4.neigh.default.gc_stale_time = 60" >> /etc/sysctl.conf
sysctl -p

避坑指南:我曾经遇到一个案例,服务器迁移后改了IP,但客户端一直连不上旧IP。查了半天,发现客户端的ARP缓存里还是旧MAC。手动清一下ARP缓存就好了——arp -d 旧IP 或者 ip neigh flush all。

清ARP缓存的命令:

系统 清缓存命令
Windows netsh interface ip delete arpcache
Linux ip neigh flush all
macOS sudo arp -a -d