ARP 实战与排错 — 地址解析协议
Wireshark 抓包过滤、ip neigh / arping / tcpdump 命令实操、IP 冲突与 ARP 欺骗排查 / 数据链路层 / 无端口 / RFC 826
Table of Contents
这篇你能学到
- 看得懂:用 Wireshark /
tcpdump把 ARP 报文抓下来,一眼分辨出普通请求、普通应答、免费 ARP、ARP Probe,以及"同一个 IP 冒出两个 MAC"的异常。 - 动得了手:用
ip neigh、arping、Windowsnetsh查表、清表、静态绑定、主动探测,并会调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-detected | Wireshark 内置的 IP 冲突检测告警,排 IP 冲突直接用它 |
arp.duplicate-address-frame | 关联到冲突的前一帧编号 |
arp.src.proto_ipv4 == 0.0.0.0 | ARP Probe(RFC 5227 地址探测) |
arp && eth.dst == ff:ff:ff:ff:ff:ff | 仅广播 ARP,评估广播风暴 |
arp.opcode == 2 && !arp.isgratuitous | 排查"无请求的应答”(欺骗常见形态,需结合请求帧比对) |
捕获过滤式(BPF,抓包前生效):arp、arp host 192.168.1.1、ether proto 0x0806。这类过滤式在抓包时就丢弃无关流量,适合长时间挂机抓包、避免文件过大;上面的显示过滤式则是抓完之后再筛。
1.2 典型字段判读
下面这段是 Wireshark 展开一个正常 ARP 请求时看到的样子,用它来对照实际抓包,确认"是请求还是应答"“问的是谁"“末尾那串 0 是什么”:
| |
四种报文的快速识别表:
| 现象 | OPER | SPA | TPA | 判定 |
|---|---|---|---|---|
| 广播、THA 全 0 | 1 | 本机 IP | 他人 IP | 普通 ARP 请求 |
| 单播回源 | 2 | 本机 IP | 请求方 IP | 普通 ARP 应答 |
| 广播 | 1 或 2 | X | = SPA | 免费 ARP(上线通告 / VIP 漂移 / 冲突检测) |
| 广播 | 1 | 0.0.0.0 | 待用 IP | ARP Probe(RFC 5227 ACD) |
| 同一 IP 出现两个不同 SHA | — | — | — | IP 冲突或 ARP 欺骗 |
2. 常用命令 / 配置
2.1 查看与操作邻居表(Linux,推荐 iproute2)
这组命令能干什么:查看本机"记了哪些 IP↔MAC 映射、每条处于什么状态”,以及在怀疑缓存脏了的时候把它删掉逼系统重新解析,或者把网关映射钉死防篡改。
| |
2.2 主动探测:arping
这组命令能干什么:不靠 ping,而是直接在二层"点名”——用来确认某台机器是不是活着、某个 IP 是不是已经被别人占了,或者在 VIP 漂移后手工吼一嗓子让全网更新缓存。
| |
2.3 抓包
这组命令能干什么:把线上真实的 ARP 报文录下来看。重点是 -e(打印以太网头,否则分不清广播还是单播)和最后那条 tshark 统计——它能一口气告诉你"到底有几个 MAC 自称是网关”,是判定 ARP 欺骗最快的一招。
| |
2.4 Windows
这组命令能干什么:Windows 上做和 Linux 一样的四件事——查缓存、清缓存、看邻居状态、给网关做静态绑定。老的 arp 命令和新的 netsh / PowerShell 三套并存,会一套即可。
2.5 内核参数与交换机侧防护
这组参数能干什么:管两件事——一是约束本机"什么样的 ARP 请求才应答、通告时用哪个源 IP"(多网卡同网段、LVS DR 场景必调);二是把邻居表容量水位调大,避免大二层环境下表被撑爆。
| |
这段交换机配置能干什么:让交换机替主机把关。先用 DHCP Snooping 记下"哪个端口、哪个 MAC、拿了哪个 IP",再用 DAI 逐个检查经过的 ARP 报文对不对得上——对不上直接丢弃。这是防 ARP 欺骗最有效的手段,主机侧任何做法都只是缓解。
| |
3. 常见故障与排错
3.1 现象:同网段 ping 不通,ping 报 Destination Host Unreachable
先记住结论:这句报错的真正含义是"ARP 没解析出来"——包根本没发出去,问题在二层,不在 IP 或应用层。所以先别查防火墙、别查路由,先看邻居表状态。
| 可能原因 | 排查方法 |
|---|---|
| 目标主机关机 / 网卡 down | arping -I eth0 <目标IP>,无应答基本可确认 |
| 目标防火墙丢弃 ARP(少见)或交换机端口隔离 | 抓包看请求是否发出、是否有应答;查交换机端口隔离/PVLAN 配置 |
| 双方不在同一 VLAN,但 IP 配成同网段 | 交换机 show vlan、show 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 做长期留证。
| |
处置:临时用 ip neigh replace ... nud permanent 固定网关;根治靠交换机 DHCP Snooping + DAI,并按 MAC 定位攻击端口关停。
3.3 现象:日志出现 IPv4 address conflict detected / Windows 弹出"IP 地址冲突”
先记住结论:同一个 IP 上出现了两个不同的 MAC。系统是通过收到"别人也声称拥有这个 IP"的 ARP 报文才察觉的,所以只要抓到那两个 MAC,按 OUI 查厂商就能顺藤摸瓜找到设备。
| 原因 | 排查 |
|---|---|
| 两台设备手工配了同一个静态 IP | arping -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_delay、garp_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=1、arp_announce=2;LVS RS 上把 VIP 配在 lo 并做上述收紧。
4. 与其他协议对比
| 维度 | ARP | NDP(IPv6) | RARP | DHCP |
|---|---|---|---|---|
| 解决问题 | IPv4 → MAC | IPv6 → MAC + 路由器发现 + 前缀通告 | MAC → IP(历史) | 自动获取 IP/掩码/网关/DNS |
| 所属层 | 数据链路层(EtherType 0x0806) | 网络层(承载于 ICMPv6) | 数据链路层(0x8035) | 应用层(UDP 67/68) |
| RFC | RFC 826 | RFC 4861 | RFC 903(废弃) | RFC 2131 |
| 寻址方式 | 二层广播 | 组播(被请求节点组播地址 ff02::1:ff00/104),不打扰无关主机 | 广播 | 广播/中继 |
| 关键报文 | Request / Reply | NS / NA / RS / RA / Redirect | Request / Reply | Discover / Offer / Request / Ack |
| 冲突检测 | 免费 ARP、ARP Probe(RFC 5227) | DAD(内建于协议,用 NS) | 无 | 依赖 ARP Probe |
| 安全能力 | 无,靠 DAI 等外部手段 | 可选 SEND(RFC 3971)+ RA Guard | 无 | DHCP Snooping |
5. 速查表 / 常见面试题
5.1 速查
| 记忆点 | 值 |
|---|---|
| EtherType | 0x0806 |
| ARP 报文体长度(以太网+IPv4) | 28 字节(帧内会被填充至 60 字节) |
| 操作码 | 1=Request,2=Reply,3=RARP Req,4=RARP Rep |
| 请求目的 MAC | FF: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 表。