做网络运维这些年我碰到过太多“无缘无故掉线”的故障。排查来排查去最后大部分都指向同一个元凶ARP攻击。ARP协议本身是局域网通信的基础它负责把IP地址解析成MAC地址但它从设计之初就没考虑过身份验证这就给内网埋了一颗大雷。这篇内容我会从ARP攻击原理讲起拆解ARP协议的工作流程和常见欺骗手法然后带你在GNS3里搭一个双路由双主机的实验环境抓包看一次完整的IP数据转发过程中ARP报文是怎么穿插其中的最后聊聊现网攻击定位和防御的经验包括怎么用arp -a快速自查、接口下怎么确认IP上线和下线时间。先说清楚下面所有抓包和欺骗实验都限制在GNS3虚拟环境里完成真实网络未经授权做这类测试是违规的咱们只为了搞懂原理、做好防御。1. ARP协议原理IP和MAC之间的“门牌翻译官”1.1 为什么网络不能绕过ARP直接通信计算机网卡在局域网传输数据时最终靠的是MAC地址而不是IP地址。IP地址是网络层的逻辑地址它解决的是“数据该往哪个网段去”的问题但真正发送数据帧时网卡只认MAC地址解决的是“这个帧物理上要交给谁”的问题。所以当一台主机在以太网里发送数据包时它必须知道目的IP对应的硬件MAC地址。这就像你只知道了对方的名字却不知道对方住址门牌号快递根本没法送。ARP就是负责根据IP查MAC的那本“地址簿”。以最常见的同网段通信为例主机A要发报文给主机BA检查自己的ARP缓存表发现没有B的MACA就会在网络上广播一个ARP请求问“谁的IP是192.168.1.2请把你的MAC地址告诉我”。B收到这个请求后发现问的是自己就会单播回复一个ARP应答告诉A自己的MAC地址。A收到后更新ARP缓存接下来的数据帧就能直接封装B的MAC发出去。整个过程看起来很简单但正是这种“谁问就答、不问也信”的机制给后面的ARP攻击留下了巨大漏洞。1.2 ARP报文结构与帧封装要理解攻击原理不能只看现象得知道报文长什么样。一次ARP请求或应答被封装在以太网帧里以太网头部的前14个字节是目的MAC、源MAC和帧类型字段。帧类型置为0x0806表示这是个ARP报文而不是普通的IP数据报0x0800。数据部分则是完整的ARP报文结构关键字段可以归纳成一张表。字段长度说明硬件类型2字节链路层类型以太网为1协议类型2字节网络层协议类型IPv4为0x0800硬件地址长度1字节以太网MAC地址长度值为6协议地址长度1字节IPv4地址长度值为4操作码2字节1表示ARP请求2表示ARP应答发送端MAC地址6字节发起报文的主机MAC发送端IP地址4字节发起报文的主机IP目标MAC地址6字节请求时为空或置0应答时为目标的MAC目标IP地址4字节请求时为目标IP应答时为目标IP这里要注意一个细节ARP请求是广播发出的以太网目的MAC填的是ff:ff:ff:ff:ff:ff广播域内所有主机都会收到ARP应答则是单播直接发给请求者。所以我们在抓包时看到大量目的MAC为全F的ARP报文这不是业务流量而是在做某种查询或者扫描需要警惕。1.3 缓存、老化与免费ARP为了减少广播报文和地址查询带来的开销操作系统和网络设备都会把学习到的ARP条目放进缓存并设置老化时间。Windows系统里ARP老化时间通常是动态计算的一般从15秒到45秒左右会更新一次超过一定时间未使用就会删除思科设备和Linux默认的老化时间一般在120秒到300秒。很多排障时遇到“刚ping通过一会儿就断”的现象其实都和ARP缓存老化后重新学习有关。还有一种特殊的ARP报文叫免费ARP也叫无请求ARP。它比较有意思通常是主机在配置完IP地址后主动广播一个ARP请求查询的还是自己的IP地址。如果网络上有人应答说明IP地址冲突。另外当网卡MAC地址变化或HA切换时也会发免费ARP把自己新的MAC通告给同网段设备。免费的另一个作用是更新二层交换机的MAC地址表让流量重新指向自己。攻击者利用免费ARP做欺骗时根本不需要有人先发起ARP请求直接对外广播“网关IP的MAC现在是攻击者的MAC”就能把整片网段的流量带偏。2. ARP攻击原理与常见攻击手法2.1 攻击的本质无状态、不认证、全信任ARP协议之所以会被攻击者盯上核心原因是它实在太“单纯”了。整个协议设计没有验证机制主机收到ARP应答后不管自己是不是真的发起过询问也不管这个应答是不是权威机构发来的就直接把发送端IP和MAC的映射关系更新进自己的缓存。另外ARP状态机本身是无状态的一台主机可以在没有任何请求的情况下主动发送ARP应答接收方往往默认接受。举个具象的例子。攻击者Z和受害主机A处于同一个局域网Z想告诉A“网关G的MAC地址是我的网卡MAC”Z只需要构造一个ARP应答报文以太网源MAC填自己的网卡ARP发送端IP填网关G的IP发送端MAC填自己的网卡目标IP填A的IP。A收到后如果系统配置允许接收主动的ARP应答绝大多数系统默认允许它的ARP缓存立刻就会把网关IP指向Z的MAC。之后A发给网关的所有数据帧物理上都是发到Z的网卡上。攻击者不用拿到任何密码就能成为整个通信链路里的“二传手”。2.2 欺骗网关让所有出网流量经过攻击者第一种典型场景是欺骗终端主机。攻击者不断给目标主机发送伪造ARP应答告诉它“网关IP对应的MAC是攻击者MAC”这样目标主机发出的所有出网报文都会先到攻击者。攻击者开启IP转发后再把报文原样转给真实网关。从目标主机视角看网络没有断只是延迟变高、页面被篡改或账密被窃取如果攻击者不开启转发目标主机就会体验为间歇性或持续性断网。第二种典型场景是欺骗网关。攻击者把网关设备里的ARP缓存也污染掉伪造出“某台主机的IP对应攻击者MAC”。这样网关发往该主机的所有下行流量都会被攻击者截获。攻击者再把报文原样转给真实主机此时网关和主机都被蒙在鼓里。单独欺骗主机只能看到上行流量单独欺骗网关只能看到下行流量所以成熟的中间人攻击都会做双向欺骗同时给主机和网关发送伪造ARP报文从而完整地拿到整个通信会话。2.3 洪泛攻击与ARP冲突风暴除了精准欺骗还有一类ARP攻击是靠“量”来砸场子常见的有ARP洪泛和IP-MAC冲突风暴。攻击者构造大量伪造的ARP报文把网关和交换机的ARP表、CPU资源全部打满导致设备无法正常处理业务。有些攻击则是故意让局域网内多个IP都对应同一个MAC或者同一个IP频繁在不同MAC之间横跳造成ARP缓存表每几秒就刷新一次全网设备不断处理ARP更新交换机的MAC地址表也在不停翻转最后表现为大量主机丢包、网络时延飙升、AP下终端频繁掉线。这类“肮脏”攻击在现网更让人头疼因为它不像精确欺骗那样目标明确而是让整个广播域一起遭殃。曾见过一个小型办公网络因为有人插了一个伪造MAC的路由器进来导致全网ARP表被刷爆核心交换机CPU一直跑满用命令查ARP表时发现同一个MAC出现在上百个IP条目里花了大半天才把源头拽出来。这也是为什么后面我会强调做防御时除了防伪造还要防“饱和”。3. 实验复现GNS3双路由双主机看正常转发与ARP欺骗3.1 拓扑设计与环境准备光讲原理不够直观我在GNS3里搭了一个最典型的跨网段通信拓扑两台路由器R1、R2分别连接主机PC1和PC2R1和R2之间用直连网段互联。为了后续模拟攻击还得让PC1所在广播域里多一台攻击者Linux所以实际拓扑是PC1和PC3连接同一台二层交换机交换机再上连R1R1与R2直连R2下连PC2。两个路由器分别连接主机正好满足分析跨路由转发时ARP协议行为的场景。设备接口IP地址用途PC1eth0192.168.1.2/24源主机PC3攻击机eth0192.168.1.3/24模拟攻击者R1G0/0192.168.1.1/24PC1网段网关R1G0/110.0.12.1/24连接R2R2G0/010.0.12.2/24连接R1R2G0/1192.168.2.1/24PC2网段网关PC2eth0192.168.2.2/24目标主机GNS3里建议用VPCS来模拟PC1和PC2因为开机快、配置简单只要执行ip 192.168.1.2 192.168.1.1就能完成地址和网关配置。攻击者PC3建议用Kali Linux虚拟机或Docker里的Linux镜像因为它需要运行arpspoof工具VPCS不支持。路由器镜像用思科IOS就可以两个路由器之间用Ethernet接口互联不必引入串口。R1和R2除了要配接口IP外还得写静态路由否则PC1回包时R2不知道192.168.1.0/24往哪发。R1#configure terminal R1(config)#interface GigabitEthernet0/0 R1(config-if)#ip address 192.168.1.1 255.255.255.0 R1(config-if)#no shutdown R1(config-if)#interface GigabitEthernet0/1 R1(config-if)#ip address 10.0.12.1 255.255.255.0 R1(config-if)#no shutdown R1(config-if)#exit R1(config)#ip route 192.168.2.0 255.255.255.0 10.0.12.2R2上做对称配置并写一条回程路由R2#configure terminal R2(config)#interface GigabitEthernet0/0 R2(config-if)#ip address 10.0.12.2 255.255.255.0 R2(config-if)#no shutdown R2(config-if)#interface GigabitEthernet0/1 R2(config-if)#ip address 192.168.2.1 255.255.255.0 R2(config-if)#no shutdown R2(config-if)#exit R2(config)#ip route 192.168.1.0 255.255.255.0 10.0.12.13.2 正常通信抓包拆解IP转发中的每一次ARP拓扑配好后先把PC1、PC2连接通。在GNS3里给R1的G0/0、R1的G0/1、R2的G0/1分别起Wireshark抓包再把R1和R2之间的链路也抓上。然后进PC1执行ping 192.168.2.2只ping一个包看完整过程。第一次抓包会被吓一跳虽然业务网段跨越了两台路由器但跨网段通信总共触发了三次ARP请求。第一次是PC1要发ICMP包到192.168.2.2发现目的IP不在自己网段于是先查默认网关192.168.1.1的MAC。PC1的ARP缓存里没有网关条目就广播请求“谁有192.168.1.1的MAC”。R1的G0/0接口收到后单播应答PC1学到网关MAC封装第一个以太网帧目的MAC是R1 G0/0的MAC源MAC是PC1的MAC帧里承载的IP层报文源IP是192.168.1.2目的IP是192.168.2.2。R1收到这个帧后去掉帧头的MAC地址看到IP目的地址不是自己查路由表发现下一跳是10.0.12.2。接下来R1要重新封装二层帧此时它需要知道10.0.12.2的MAC于是R1在自己的直连网段10.0.12.0/24里广播ARP请求R2的G0/0接口应答。这里就是第二次ARP。R1拿到R2的接口MAC后把ICMP报文封装成新的帧源MAC是R1 G0/1的MAC目的MAC是R2 G0/0的MAC从G0/1口发出去。R2收到帧后再次解封发现目的IP是192.168.2.2不在自己任何接口IP上查路由表得知出接口是G0/1目的网段是192.168.2.0/24。R2接着在自己的G0/1接口广播ARP请求询问192.168.2.2的MAC这是第三次ARP。PC2单播应答后R2才把ICMP报文封装成目的MAC为PC2地址的帧发出去。PC2收到并回复时因为回程路径上的节点都已经学习到ARP条目所以回包四条链路里几乎看不到新的ARP广播只有纯粹的ICMP报文。整个过程很好地说明了ARP在跨网段转发中扮演的“每跳查询”角色三层设备每换一次出接口就可能重新触发一次ARP。3.3 模拟ARP欺骗观察缓存覆盖与中间人效果正常通信没问题后我开始在实验环境里模拟欺骗。我们需要PC3这台Linux攻击机先给它配上192.168.1.3/24确保它能访问局域网其他设备。然后安装arpspoof工具Debian系Linux可以执行apt install dsniff。核心命令是两条一条欺骗受害主机让PC1以为网关的MAC是PC3的MAC另一条欺骗网关让网关以为PC1的MAC是PC3的MAC。arpspoof -i eth0 -t 192.168.1.2 192.168.1.1 arpspoof -i eth0 -t 192.168.1.1 192.168.1.2执行后立刻在PC1上查看ARP表命令是arp -a。正常情况下192.168.1.1对应的应该是R1的G0/0接口MAC但此时会看到网关条目对应的MAC变成了PC3的MAC。这说明PC1的ARP缓存已经被污染。为了保持污染状态arpspoof工具会不停地发送伪造ARP应答防止PC1的缓存自动更新回来。接着在PC3上开启IP转发echo 1 /proc/sys/net/ipv4/ip_forward再去PC1执行ping 192.168.2.2可以发现网络仍然能通。但在PC3网卡上抓包能看到大量ICMP请求和应答报文两个方向的流量都从PC3的网卡上过了一趟。这就是典型的中间人攻击数据看似正常到达目的地中间已经被悄悄“抄送”了一份。如果把IP转发关闭PC1立刻就会发现自己ping不通PC2或网关因为发出去的ICMP报文被PC3直接扔掉了这就是很多内网“单机断网但网关通”的另一个原因。实验结束后要清理环境可以在PC1上执行arp -d清除被污染的表项或者直接重启PC1和网关的ARP缓存。3.4 用ping命令观察ARP触发时机在做上述实验时我习惯先手动删掉一段ARP缓存再用ping命令触发一次查询这样抓包的意图就会非常清晰。比如在PC1上执行arp -d 192.168.1.1然后立刻ping 192.168.1.1在抓包里就能看到第一个报文是ARP请求第二个报文才是ICMP Echo Request。如果缓存未删除直接ping网关那么抓包里只有ICMP因为ARP缓存命中了。排障时我也是这么用的。当怀疑某设备MAC异常先ping一下地址再看ARP表能确认最近一次通信时mac的响应结果。Windows下删除ARP表命令是arp -d *打开管理员命令行执行Linux下是ip neigh flush dev eth0。GNS3里的VPCS比较简版同样支持arp -d。这些操作能帮助你快速重建“认知”配合抓包就能把ARP协议的行为看得明明白白。4. 现网攻击定位与排查从arp -a到接口查询4.1 终端侧快速自查arp -a能否发现异常发生内网故障时第一反应不应是重启而是先看ARP表。Windows、macOS、Linux上都能用arp -a查看当前缓存内容。正常的网关心条目只有一条IP对应的是真实网关MAC。如果发现同一个IP对应的MAC短时间内变来变去或者显示出的网关MAC明显不是网关设备的厂商OUIMAC地址前24位基本可以先判断存在ARP欺骗。举个例子网关设备是华为MAC前24位应该是华为的OUI如果arp -a里网关MAC是VMware的OUI或某块消费级网卡的OUI这就有问题了。更稳妥的方法是找到“白名单基线”。在局域网中预先记录网关IP和真实MAC存到一张表里。故障时执行arp -a把输出的网关MAC和白名单比对。很多企业内部没有建立这个基线导致故障发生时连什么是“正常”都不知道。我建议网络管理员至少把核心网关、服务器、打印机这些固定设备的IP-MAC建立一份台账平时可能觉得多余真出问题时这就是救命的基准线。4.2 路由器/交换机接口下查找IP与MAC关系在终端上看完了现象下一步要去网络设备上定位源头。思科路由器上查看ARP表用show ip arp华为设备用display arp。如果怀疑某台设备伪装成服务器的IP可以在交换机上查该IP对应的MAC再通过MAC地址表找到这个MAC是从哪个端口学习到的。思科命令是show mac address-table address MAC华为是display mac-address MAC。找到接入端口后顺着交换层级一台一台往上或往下查最终定位到攻击者所在的物理口。这里有一个坑攻击者如果频繁改变自己的MAC地址你看到的MAC可能是随机生成的printf—。这时候不要只盯同一个MAC而要看大量ARP请求报文里共同的物理特征比如报文的源MAC虽然变化但网卡速率、或者时隙规律可能一致。更适合的做法是在交换机上开启镜像端口或抓包把ARP报文全量收集下来用Wireshark统计统计看哪些IP-MAC组合不断变换或者哪个源MAC发送了海量ARP请求。针对洪泛型攻击也可以在交换机上执行show cpu utilization看ARP处理进程是不是冲到100%。4.3 接口下怎么查IP地址上线时间和下线时间不少朋友问路由器和交换机接口下怎么查某个IP地址的上线时间和下线时间。这里要澄清一个概念标准ARP表项里的Age字段不是“上线时间”而是“剩余老化时间”很多朋友一上来就搞混了。比如华为交换机上执行display arp结果里会看到Age字段显示数值单位是分钟比如35表示这个条目还能存活35分钟如果一直没有流量时间到了就删除。思科设备show ip arp里的Age用“-”表示端口本身直连路由或者显示分钟数。这些都不是设备上线或下线时刻。真正要查上线/下线时间有几个可行路径。第一开启网络设备的ARP表变更日志例如华为交换机上可以配置ARP anti-attack日志或ARP表项变化日志当表项新增、修改、删除时上送到syslog服务器日志里会带时间戳。第二通过网管平台周期轮询设备ARP表和MAC表用脚本记录每个IP-MAC对首次出现和最后消失的时间这是最通用的办法。第三如果网络里有DHCP优先看DHCP Snooping绑定表或DHCP租约日志能拿到IP分配时间、租期、释放时间基本等价于上线和下线时间。第四使用准入系统如802.1X认证日志用户认证成功即上线认证下线或超时即下线这个最准确。在应急排查时我常写一个快速脚本每隔10秒在核心设备上执行display arp把输出存到文件里再对IP-MAC的出现和消失做比对虽然不是严格意义的下线时间但对于定位“哪台设备哪个时间段在攻击”已经够用。4.4 ARP攻击防御要如何落地排查是救火防御才是防火。很多人的第一反应是配置静态ARP在终端上绑定网关在服务器上绑定所有终端的IP-MAC。静态绑定思路简单但维护成本巨大终端数量一多、换机一勤静态表就成了负担。对个人电脑只说一句话如果你电脑上发现网关MAC被篡改立刻用arp -s临时绑定真实网关MAC可以在紧急情况下保一端安全但不适合大规模部署。在交换机层面有几个更有效的方案。动态ARP检测DAI是常用手段它依赖DHCP Snooping绑定表交换机上记录有效用户的IP-MAC-VLAN-接口对应关系对非法的ARP请求和应答直接丢弃。开启DHCP Snooping和DAI后伪造ARP报文的源MAC和绑定表不一致时报文不会进入交换芯片处理。这需要网络里的终端都老老实实用DHCP如果服务器和网络设备用静态IP要手工把绑定表加全。另一招是端口安全限制一个接口下只能学习到1个或几个MAC地址防止攻击者乱接设备和私改地址。还可以在接入交换机上划分更小的VLAN缩小广播域降低单次ARP欺骗的影响面。5. 常见问题速查与实战心得5.1 典型故障现象与处理步骤为了便于大家排查我把常见的情况做了一个速查表内容和按钮可能因厂商而略有差异但排查思路是大同小异的。故障现象可能原因紧急处理措施全网或部分电脑频繁掉线重启后片刻恢复ARP洪泛或主机被欺骗缓存被反复改在接入交换机抓包找大量ARP报文源端口shutdown端口再启用DAI网关MAC频繁变化arp -a看到多个IP同MAC有人伪装网关做攻击记录异常MAC交换机查MAC端口断开攻击者终端执行arp -d清缓存内网主机之间通信异常但防火墙和路由配置正常二层存在中间人或静态ARP冲突在核心交换机查ARP表项核对IP-MAC确认网关端口收到的ARP报文来源设备CPU飙升ARP进程占用高ARP洪泛报文打满设备开启ACL过滤非必要ARP限速ARP报文启用DAI与端口安全某IP时通时不通且在好几个端口查到了同一MAC有人私改IP或伪造MAC在交换机上阻断该MAC并定位物理端口绑定用户IP-MAC抓包看不到可疑ARP但业务持续掉线攻击为低频间歇式或直接跨越VLAN欺骗在网关上抓包同时看syslog启用ARP表变化日志5.2 我在现网踩过的坑这些年处理过的ARP攻击故障没有一百也有几十个有几个坑特别值得拿出来分享。第一个是“重装系统到底能不能解决ARP攻击”这个误会。内网用户一掉线就抱怨电脑中毒IT部门让重装结果刚装完系统没几个小时故障又回来了。原因很简单攻击源在网络里的其他设备上重装系统只会清掉本地ARP缓存等于把已经被污染的“门牌号”重置一下但攻击者还在不停地发广播。所以遇到疑似ARP攻击第一时间要在接入交换机上找攻击源而不是急着重装终端。第二个坑是抓包过滤条件设置太窄。刚开始排查时我在抓包软件上只过滤arp发现质报文并不多但网络确实不通。后来才反应过来攻击者可能只发了一批伪造应答把受害者的缓存覆盖后就不再发送了。这时候应该同时抓icmp和arp再结合ARP表变化来判断。过滤条件最好写成arp or icmp然后在Wireshark里按protocol排序重点看谁先发起了ARP响应、响应间隔是多少。第三个坑是忽略了防御设备的顺序。我曾在核心交换机和防火墙之间加了安全设备以为二层攻击会被拦下来结果ARP攻击还是照常发生。原因在于ARP攻击发生在广播域内的二层接入层防火墙和安全设备通常部署在三层边界根本看不到接入层里每个ARP报文是谁发的。后来把防护重心移到接入交换机开启DAI和端口安全后故障才算根治。这也是为什么我不推荐一上来就在终端做静态绑定更建议先在接入层做可控的动态校验。第四个坑是关于IP上线时间查询的。有一次排查非法接入我盯着交换机的display arp看了半天始终没有找到用户的上线时刻。后来意识到标准ARP表本来就不记录这个时间需要辅助其他系统。当时我利用已有的DHCP租约日志把IP分配和释放时间拉出来再和监控录像比对才确认是有人偷偷带了个小路由器进来。经过这次之后我建议网络至少部署DHCP Snooping和日志服务器既方便溯源也能给DAI打数据基础。关于ARP攻击原理说到底就是一个“信任惹祸”的经典案例。做网络的都知道越基础的协议出问题影响面越广、排查越难受。所以我个人的建议是平时就打好二层安全基础把MAC地址基线、DHCP绑定表、交换机日志这些“基本功”做扎实别等问题爆发了再靠arp -a一格格翻。如果你正在被内网莫名掉线、卡顿、页面被劫持这类问题困扰不妨先从ARP表查起大概率能少走很多弯路。