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就上场了。
流程其实就四步:
- A构造ARP请求:目标MAC填全F(FF:FF:FF:FF:FF:FF),广播出去。
- 交换机转发广播:所有端口都收到这个请求。
- B回应ARP应答:B发现问的是自己,就单播回复自己的MAC地址。
- A更新ARP表:把B的IP和MAC对应关系缓存起来。
关键点:ARP请求是广播,ARP应答是单播。这个区别很多人搞混。我在一次排障中遇到过,抓包发现只有请求没有应答,结果是因为B的防火墙把ARP应答过滤了。
下面这张图把整个过程画清楚了:
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欺骗做了中间人攻击。最后定位到一台中了病毒的员工电脑。
排查方法我总结成三步:
- 对比ARP表:在多个主机上查网关的MAC地址,看是否一致。
- 抓包分析:用Wireshark过滤
arp,看有没有大量重复的ARP应答。 - 静态绑定:临时在网关和关键主机上做静态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 |