ARP 实战与排错 — 地址解析协议

Wireshark 抓包过滤、ip neigh / arping / tcpdump 命令实操、IP 冲突与 ARP 欺骗排查 / 数据链路层 / 无端口 / RFC 826

这篇你能学到

  • 看得懂:用 Wireshark / tcpdump 把 ARP 报文抓下来,一眼分辨出普通请求、普通应答、免费 ARP、ARP Probe,以及"同一个 IP 冒出两个 MAC"的异常。
  • 动得了手:用 ip neigharping、Windows netsh 查表、清表、静态绑定、主动探测,并会调 arp_ignore / gc_thresh 等内核参数和交换机 DHCP Snooping + DAI 防护。
  • 排得了错:面对"同网段 ping 不通"“全网间歇断网"“IP 冲突告警"“VIP 切换不生效"等典型现象,按结论先行的顺序快速定位。

1. 抓包观察

1.1 Wireshark 显示过滤式

这张表的用法:先用 arp 把范围框住,再按"查欺骗 / 查冲突 / 查某台机器"的目的挑一条更精确的过滤式往下钻。

过滤式作用
arp所有 ARP 报文(最常用起手式)
arp.opcode == 1仅 ARP 请求
arp.opcode == 2仅 ARP 应答
arp.src.proto_ipv4 == 192.168.1.1声称自己是网关的报文(查欺骗第一刀)
arp.dst.proto_ipv4 == 192.168.1.100谁在找这台主机
arp.src.hw_mac == aa:bb:cc:dd:ee:ff追踪某网卡发出的所有 ARP
arp.isgratuitous == 1免费 ARP(Wireshark 自动识别 SPA==TPA)
arp.duplicate-address-detectedWireshark 内置的 IP 冲突检测告警,排 IP 冲突直接用它
arp.duplicate-address-frame关联到冲突的前一帧编号
arp.src.proto_ipv4 == 0.0.0.0ARP Probe(RFC 5227 地址探测)
arp && eth.dst == ff:ff:ff:ff:ff:ff仅广播 ARP,评估广播风暴
arp.opcode == 2 && !arp.isgratuitous排查"无请求的应答”(欺骗常见形态,需结合请求帧比对)

捕获过滤式(BPF,抓包前生效)arparp host 192.168.1.1ether proto 0x0806。这类过滤式在抓包时就丢弃无关流量,适合长时间挂机抓包、避免文件过大;上面的显示过滤式则是抓完之后再筛。

1.2 典型字段判读

下面这段是 Wireshark 展开一个正常 ARP 请求时看到的样子,用它来对照实际抓包,确认"是请求还是应答"“问的是谁"“末尾那串 0 是什么”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Ethernet II, Src: aa:aa:aa:aa:aa:aa, Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Type: ARP (0x0806)
Address Resolution Protocol (request)
    Hardware type: Ethernet (1)
    Protocol type: IPv4 (0x0800)
    Hardware size: 6
    Protocol size: 4
    Opcode: request (1)
    Sender MAC address: aa:aa:aa:aa:aa:aa
    Sender IP address: 192.168.1.10
    Target MAC address: 00:00:00:00:00:00
    Target IP address: 192.168.1.20
    [Padding: 000000000000000000000000000000000000]

四种报文的快速识别表

现象OPERSPATPA判定
广播、THA 全 01本机 IP他人 IP普通 ARP 请求
单播回源2本机 IP请求方 IP普通 ARP 应答
广播1 或 2X= SPA免费 ARP(上线通告 / VIP 漂移 / 冲突检测)
广播10.0.0.0待用 IPARP Probe(RFC 5227 ACD)
同一 IP 出现两个不同 SHAIP 冲突或 ARP 欺骗

2. 常用命令 / 配置

2.1 查看与操作邻居表(Linux,推荐 iproute2)

这组命令能干什么:查看本机"记了哪些 IP↔MAC 映射、每条处于什么状态”,以及在怀疑缓存脏了的时候把它删掉逼系统重新解析,或者把网关映射钉死防篡改。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 查看 ARP/邻居表(含状态,比 arp -n 信息更全)
ip neigh show
ip -4 neigh show dev eth0
ip neigh show nud reachable # 只看可达项
ip neigh show nud failed # 只看解析失败项(排错高频)

# 删除单条 / 清空整表(强制重新解析,验证故障是否为缓存脏数据)
ip neigh del 192.168.1.20 dev eth0
ip -s -s neigh flush all

# 静态绑定网关,防 ARP 欺骗
sudo ip neigh replace 192.168.1.1 lladdr 00:11:22:33:44:55 dev eth0 nud permanent

# 传统命令(net-tools,仍广泛存在)
arp -a # 列出缓存(-n 不做反解,更快)
arp -d 192.168.1.20 # 删除条目
arp -s 192.168.1.1 00:11:22:33:44:55 # 静态绑定

2.2 主动探测:arping

这组命令能干什么:不靠 ping,而是直接在二层"点名”——用来确认某台机器是不是活着、某个 IP 是不是已经被别人占了,或者在 VIP 漂移后手工吼一嗓子让全网更新缓存。

1
2
3
4
5
6
7
8
9
# 探测目标是否在线(二层探测,即使对方防火墙禁 ICMP 也常有效)
arping -I eth0 -c 3 192.168.1.20

# 检测 IP 冲突:若有多个不同 MAC 应答,即为冲突
arping -I eth0 -c 5 -D 192.168.1.100 # -D 即 DAD 模式(SPA=0.0.0.0 探测)

# 发送免费 ARP,强制刷新全网缓存(VIP 漂移后手工补发)
arping -I eth0 -c 3 -U 192.168.1.100 # -U: unsolicited/gratuitous ARP
arping -I eth0 -c 3 -A 192.168.1.100 # -A: ARP REPLY 形态的免费 ARP

2.3 抓包

这组命令能干什么:把线上真实的 ARP 报文录下来看。重点是 -e(打印以太网头,否则分不清广播还是单播)和最后那条 tshark 统计——它能一口气告诉你"到底有几个 MAC 自称是网关”,是判定 ARP 欺骗最快的一招。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 抓本机所有 ARP
sudo tcpdump -i eth0 -nn -e arp

# 只抓与网关相关的 ARP(-e 打印以太网头,判断广播/单播必需)
sudo tcpdump -i eth0 -nn -e 'arp host 192.168.1.1'

# 抓包存盘供 Wireshark 分析
sudo tcpdump -i eth0 -w arp.pcap arp

# 用 tshark 直接统计"哪些 MAC 声称自己是网关"(查欺骗)
tshark -i eth0 -Y 'arp.src.proto_ipv4==192.168.1.1' -T fields -e arp.src.hw_mac | sort -u

2.4 Windows

这组命令能干什么:Windows 上做和 Linux 一样的四件事——查缓存、清缓存、看邻居状态、给网关做静态绑定。老的 arp 命令和新的 netsh / PowerShell 三套并存,会一套即可。

1
2
3
4
5
6
arp -a # 查看缓存
arp -d * # 清空缓存(需管理员)
netsh interface ipv4 show neighbors # 查看邻居表(含状态)
netsh interface ipv4 delete neighbors "以太网"
netsh interface ipv4 add neighbors "以太网" 192.168.1.1 00-11-22-33-44-55 # 静态绑定
Get-NetNeighbor -AddressFamily IPv4 # PowerShell 方式

2.5 内核参数与交换机侧防护

这组参数能干什么:管两件事——一是约束本机"什么样的 ARP 请求才应答、通告时用哪个源 IP"(多网卡同网段、LVS DR 场景必调);二是把邻居表容量水位调大,避免大二层环境下表被撑爆。

1
2
3
4
5
6
7
8
9
# LVS DR 模式 / 多网卡同网段场景必调
sysctl -w net.ipv4.conf.all.arp_ignore=1 # 只应答目标 IP 配置在收包网卡上的请求
sysctl -w net.ipv4.conf.all.arp_announce=2 # 通告时优先选用本网段的源 IP
sysctl -w net.ipv4.conf.eth0.proxy_arp=0 # 关闭代理 ARP(默认关闭)

# 大二层环境 ARP 表溢出(dmesg 出现 neighbour table overflow)时扩容
sysctl -w net.ipv4.neigh.default.gc_thresh1=1024
sysctl -w net.ipv4.neigh.default.gc_thresh2=4096
sysctl -w net.ipv4.neigh.default.gc_thresh3=8192

这段交换机配置能干什么:让交换机替主机把关。先用 DHCP Snooping 记下"哪个端口、哪个 MAC、拿了哪个 IP",再用 DAI 逐个检查经过的 ARP 报文对不对得上——对不上直接丢弃。这是防 ARP 欺骗最有效的手段,主机侧任何做法都只是缓解。

1
2
3
4
5
6
7
8
9
! Cisco 交换机:DHCP Snooping + 动态 ARP 检测(DAI)—— 防 ARP 欺骗最有效手段
ip dhcp snooping
ip dhcp snooping vlan 10
ip arp inspection vlan 10
interface GigabitEthernet0/1
 ip dhcp snooping trust ! 上联口设为信任
 ip arp inspection trust
interface range GigabitEthernet0/2 - 24
 ip arp inspection limit rate 15 ! 接入口限速,抑制 ARP 泛洪

3. 常见故障与排错

3.1 现象:同网段 ping 不通,ping 报 Destination Host Unreachable

先记住结论:这句报错的真正含义是"ARP 没解析出来"——包根本没发出去,问题在二层,不在 IP 或应用层。所以先别查防火墙、别查路由,先看邻居表状态。

可能原因排查方法
目标主机关机 / 网卡 downarping -I eth0 <目标IP>,无应答基本可确认
目标防火墙丢弃 ARP(少见)或交换机端口隔离抓包看请求是否发出、是否有应答;查交换机端口隔离/PVLAN 配置
双方不在同一 VLAN,但 IP 配成同网段交换机 show vlanshow interface switchport 核对
掩码配错,误判为同网段ip addr show 核对前缀长度
ARP 表溢出`dmesg

排查顺序ip neigh show <IP> → 若为 FAILED/INCOMPLETE 说明 ARP 层就没通 → tcpdump -e arp 确认请求是否发出、有无应答 → 请求发出但无应答则问题在目标侧或二层路径。

3.2 现象:全网间歇性断网 / 网速时快时慢

先记住结论“时好时坏"是 ARP 类故障的典型指纹——因为双方在反复抢着改写你的缓存,谁最后一次写入你就听谁的。基本可以锁定 ARP 欺骗或 IP 冲突,从"网关的 MAC 是不是在变"查起最快。

原因:ARP 欺骗或 IP 冲突。

排查

下面四步是从"最快确认"到"长期监控"的顺序:第 1 步盯网关 MAC 有没有跳变,第 2 步抓包数一数有几个 MAC 自称网关,第 3 步用 Wireshark 内置告警直接定位冲突帧,第 4 步上 arpwatch 做长期留证。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 1. 看网关 MAC 是否变化(最直接的信号)
watch -n 1 'ip neigh show 192.168.1.1'

# 2. 抓包统计声称是网关的 MAC 有几个
sudo tcpdump -i eth0 -nn -e 'arp and host 192.168.1.1'
# 若出现两个不同的 SHA 都说自己是 192.168.1.1 → 确认欺骗

# 3. Wireshark 打开 → 过滤 arp.duplicate-address-detected → 直接定位冲突帧
# 4. 部署监控
sudo arpwatch -i eth0 # IP-MAC 变更时记录 syslog / 发邮件

处置:临时用 ip neigh replace ... nud permanent 固定网关;根治靠交换机 DHCP Snooping + DAI,并按 MAC 定位攻击端口关停。

3.3 现象:日志出现 IPv4 address conflict detected / Windows 弹出"IP 地址冲突”

先记住结论同一个 IP 上出现了两个不同的 MAC。系统是通过收到"别人也声称拥有这个 IP"的 ARP 报文才察觉的,所以只要抓到那两个 MAC,按 OUI 查厂商就能顺藤摸瓜找到设备。

原因排查
两台设备手工配了同一个静态 IParping -D -I eth0 <IP> 看有几个 MAC 应答;据 MAC OUI 前 3 字节查厂商定位设备
静态 IP 落在 DHCP 地址池范围内核对 DHCP 服务器 pool 与 exclude 配置
高可用双主(脑裂),两节点同时持有 VIP检查 keepalived/VRRP 状态、优先级、VRID 冲突及心跳链路
虚拟机克隆导致 MAC/IP 重复核对虚拟机网卡 MAC 是否重新生成

3.4 现象:VIP 切换后客户端仍访问旧节点,需等几十秒才恢复

先记住结论新主起来了,但没把消息广播出去——客户端和交换机的缓存还指着旧 MAC,只能干等缓存自然老化,所以才是"几十秒"这个量级。核心是查免费 ARP 有没有发、发够没有。

原因:新主节点未发或未发够免费 ARP,客户端/交换机缓存仍指向旧 MAC。

排查与处置:切换瞬间抓 arp.isgratuitous == 1 确认 GARP 是否发出;keepalived 检查 garp_master_delaygarp_master_refresh 配置;应急用 arping -U -I eth0 <VIP> 手工补发。

3.5 现象:跨网段 ping 不通,但 ARP 表里没有目的主机

先记住结论ARP 表里本来就不该有它,别在这上面浪费时间。跨网段只解析网关的 MAC,远端主机永远不会进你的 ARP 表——排查方向应该转到路由和网关。

这不是故障——跨网段本就只解析网关 MAC。应改查:ip route get <目的IP> 确认下一跳,再看 ip neigh show <网关IP> 是否 REACHABLE,最后排查网关侧路由与回程路由。

3.6 现象:Linux 服务器多网卡同网段,回包走错网卡

先记住结论这是 Linux 的默认行为,不是 bug——它采用"弱主机模型",任何一块网卡都乐意替本机所有 IP 应答 ARP。想要"哪个 IP 配在哪块卡上就只由哪块卡应答",必须手工收紧内核参数。

原因:Linux 默认"弱主机模型",任一网卡都会应答本机所有 IP 的 ARP 请求,导致 IP 与网卡绑定混乱(LVS DR 模式的经典坑)。

处置:设置 arp_ignore=1arp_announce=2;LVS RS 上把 VIP 配在 lo 并做上述收紧。

4. 与其他协议对比

维度ARPNDP(IPv6)RARPDHCP
解决问题IPv4 → MACIPv6 → MAC + 路由器发现 + 前缀通告MAC → IP(历史)自动获取 IP/掩码/网关/DNS
所属层数据链路层(EtherType 0x0806)网络层(承载于 ICMPv6)数据链路层(0x8035)应用层(UDP 67/68)
RFCRFC 826RFC 4861RFC 903(废弃)RFC 2131
寻址方式二层广播组播(被请求节点组播地址 ff02::1:ff00/104),不打扰无关主机广播广播/中继
关键报文Request / ReplyNS / NA / RS / RA / RedirectRequest / ReplyDiscover / Offer / Request / Ack
冲突检测免费 ARP、ARP Probe(RFC 5227)DAD(内建于协议,用 NS)依赖 ARP Probe
安全能力,靠 DAI 等外部手段可选 SEND(RFC 3971)+ RA GuardDHCP Snooping

5. 速查表 / 常见面试题

5.1 速查

记忆点
EtherType0x0806
ARP 报文体长度(以太网+IPv4)28 字节(帧内会被填充至 60 字节)
操作码1=Request,2=Reply,3=RARP Req,4=RARP Rep
请求目的 MACFF:FF:FF:FF:FF:FF
免费 ARP 判据SPA == TPA
ARP Probe 判据SPA == 0.0.0.0
Linux 查表ip neigh show
Wireshark 起手式arp / arp.duplicate-address-detected
最有效防欺骗交换机 DHCP Snooping + DAI

5.2 常见面试题

Q1:主机 A ping 不同网段的主机 B,A 的 ARP 请求问的是谁的 MAC? 问的是默认网关的 MAC,不是 B 的。跨网段传输中 IP 端到端不变、MAC 逐跳改写。

Q2:ARP 请求是广播还是单播?应答呢? 请求是广播(目的 MAC 全 F);应答是单播回请求方。但缓存进入 STALE 后的刷新探测可能是单播请求。

Q3:ARP 属于哪一层? 存在争议但主流答法:数据链路层(直接封装在以太网帧中,不经 IP 头),功能上是链路层与网络层之间的"胶水"。RFC 826 本身称其为一个"地址解析"协议,不属于某个具体层。

Q4:免费 ARP 有什么用?怎么识别? 识别看 SPA == TPA。三大用途:IP 冲突检测、刷新其他设备的 ARP 缓存、VRRP/keepalived 主备切换后通告 VIP 新归属。

Q5:ARP Probe 为什么把发送方 IP 填 0.0.0.0? 避免在冲突尚未确认前污染其他主机的 ARP 缓存——若该 IP 最终不可用,网络中不应残留任何指向自己的错误映射(RFC 5227)。

Q6:ARP 欺骗的根本原因是什么?如何防? 根因是 ARP 无任何认证机制,且主机会无条件接受甚至是未请求的应答。防护由弱到强:静态绑定 → arpwatch 监控 → 端口安全 → DHCP Snooping + DAI(最有效) → 私有 VLAN 隔离。

Q7:IPv6 为什么不用 ARP? IPv6 用 NDP(RFC 4861),基于 ICMPv6 的 NS/NA。优势:用组播(被请求节点组播地址)而非广播,只惊扰目标主机而非全网段;内建 DAD 做重复地址检测;可叠加 SEND 提供加密认证;并顺带完成路由器发现与前缀通告。

Q8:ARP 缓存条目为什么有的显示 STALE 却仍能正常通信? Linux 采用延迟验证:STALE 表示"未在近期确认可达",但条目仍可用;只有在真正发包时才进入 DELAY,若上层(如 TCP ACK)能提供可达性证据就直接回到 REACHABLE,无需额外 ARP 报文,从而减少广播开销。

Q9:neighbour table overflow 报错怎么处理? 邻居表超过 gc_thresh3 水位。常见于大二层/容器/云网关场景。调大 net.ipv4.neigh.default.gc_thresh1/2/3,并检查是否存在异常 ARP 扫描导致表被灌满。

Q10:交换机需要 ARP 表吗? 普通二层交换机不需要——它只维护 MAC 地址表(MAC ↔ 端口),ARP 报文对它而言只是需要泛洪的广播帧。三层交换机/路由器因为要做 IP 转发,才需要维护 ARP 表。