1. 先说清楚ARP到底是什么
如果你去问一个刚入行的网络工程师,ARP是什么,十有八九会得到一句标准答案:Address Resolution Protocol,地址解析协议。但你要是再追问一句,它到底在解析什么,为什么解析会导致整栋楼的电脑都上不了网,可能就有人开始支支吾吾了。
我最早接触ARP攻击是在一个不到二十台电脑的小型办公网里。行政说打印机连不上了,财务说报销系统打不开,研发说代码推不上去,整个办公室此起彼伏地喊断网。当时我还在用最原始的办法挨台电脑查ARP缓存,后来才意识到,这个藏在IP和MAC之间的协议,一旦被人盯上,就是局域网里最脆弱的那个环节。
要理解ARP攻击,先得理解ARP到底干什么。咱们平时上网,嘴里说的都是IP地址,比如网关是192.168.1.1,服务器是10.0.0.5。但实际在以太网这种局域网环境里,数据帧在链路上传输时,靠的并不是IP地址,而是MAC地址。这就好比你要寄快递,写的是收件人姓名和手机号,但快递员真正认的是门牌号。IP地址就是姓名,MAC地址才是门牌号。
问题来了:一台主机知道对方的IP地址,但不知道对方的MAC地址,怎么办?这就需要ARP协议出马。
我把这个过程拆成最直白的四步,第一次接触ARP的人也能看明白:
- 主机A想给主机B发数据,先查自己的ARP缓存表,看有没有主机B的IP对应的MAC记录。
- 如果没有,主机A就会在局域网里广播一条ARP请求报文,内容是:谁是192.168.1.2?请告诉192.168.1.1(也就是主机A自己)。
- 局域网里所有主机都会收到这条广播,但只有IP地址匹配的那台主机会回复一条ARP应答:我是192.168.1.2,我的MAC是AA:BB:CC:DD:EE:FF。
- 主机A收到应答后,把这条IP和MAC的映射关系写进自己的ARP缓存表,然后开始正常通信。
整个流程看起来毫无破绽,局域网里也确实靠这个机制运行了几十年。但注意我刚才描述的第3步——只有目标主机能应答,这只是理想情况。如果有人不按规矩来呢?
这就是ARP攻击的全部根基:ARP协议在设计的时候,从来没有想过要验证“你声称自己是谁”这件事。
2. ARP攻击的核心原理:两张表的信任危机
2.1 攻击者如何改写他人在线状态
先说一个最经典的场景,ARP欺骗(ARP Spoofing)。
假设一栋办公楼里有三台设备:主机A是财务电脑,IP是192.168.1.10;网关G是路由器,IP是192.168.1.1,MAC是GG:GG:GG:GG:GG:GG;攻击者C是某台被植入木马的电脑,IP是192.168.1.66,MAC是CC:CC:CC:CC:CC:CC。
正常情况下,主机A要和网关G通信,ARP缓存表里应该写着:192.168.1.1对应的MAC是GG:GG:GG:GG:GG:GG。数据包发给网关,网关转发到互联网。
但攻击者C现在做了一件非常简单的事:向主机A发送一条伪造的ARP应答报文,内容是“我是192.168.1.1,我的MAC是CC:CC:CC:CC:CC:CC”。
主机A收到这条报文后,会怎么处理?前文说过,ARP协议的缺陷就在这里——它不验证报文的真实性。主机A会毫不犹豫地用这条新记录覆盖掉原本正确的ARP缓存,从此以为网关的MAC是CC:CC:CC:CC:CC:CC。
从这一刻起,主机A发出的所有数据包,都会交给攻击者C的网卡。攻击者C可以选择把这些包丢弃,让主机A彻底断网;也可以开启IP转发,把包原封不动地转给真正的网关,然后神不知鬼不觉地监听所有流量,这就是中间人攻击(Man-in-the-Middle)。
站在主机A的角度,它觉得自己一直在正常上网,完全感知不到自己的流量已经被别人过了一遍手。
反过来,如果攻击者C也对网关G做了同样的欺骗——告诉网关“我是192.168.1.10,我的MAC是CC:CC:CC:CC:CC:CC”——那么网关发给主机A的响应包也会先经过攻击者C。
这就完成了双向欺骗。攻击者C就像在你家门口装了一个透明的邮件分拣站,你的所有来往信件都先经过他的手。
2.2 ARP洪泛攻击为什么能把整楼打瘫
ARP欺骗针对的是某个特定主机,而ARP洪泛(ARP Flooding)则是无差别的资源消耗战。
原理也不复杂。交换机在转发二层帧时,MAC地址表是有限度的。正常情况下,一台交换机维护几十几百个MAC地址条目毫无压力。但攻击者连续不断地发送源MAC地址随机、目的MAC地址随机的ARP报文时,交换机的MAC地址表会被瞬间填满。表满了之后,交换机为了不丢包,只好把后续收到的广播报文转发到除接收端口外的所有端口。原本应该是点对点通信的局域网,瞬间变成了一台巨型集线器。
所有主机的流量都在网络上裸奔,谁都可以抓到谁的包。这种情况下,断网反而是最轻的症状。
ARP洪泛还有一种变体,是向局域网内大量发送伪造的ARP应答,声称“我是网关,我的MAC是XXX”。网段里所有主机都把这个假网关录入自己的ARP缓存。结果就是整个网段内所有对外流量全部发到了攻击者那里,全网集体掉线。
我记得有一次处理这类问题,排查到最后,发现罪魁祸首是一台中了蠕虫的服务器,不停向外发送ARP包。一台机器,几千行脚本,把整个公司三百多台电脑的网给断了。所以别小看ARP攻击,它的破坏力不取决于攻击者的技术水平,只取决于攻击者的意图。
2.3 一个关键误区:ARP转发和ARP代理不是一回事
在讲GNS3实验之前,必须澄清一个容易混淆的概念:ARP代理。
有些路由器默认开启了代理ARP功能,意思是当路由器收到一个ARP请求,发现目标IP不属于自己,但自己知道去哪能找到这个目标时,它会代替目标主机回复一个ARP应答,声称“我就是那个IP”。这种机制本来是为了解决不同物理网络互通的问题——比如客户端配了错误的子网掩码,还能通过代理ARP访问外部网络。
但这恰恰是排查时的坑。如果你在两台路由器上做GNS3实验,不关闭代理ARP,你可能会看到一些匪夷所思的现象:主机A ping主机B,抓包看到的是路由器R1在回复ARP请求,而不是主机B在回复。你以为自己配置错了,其实只是代理ARP在“帮忙”。
排查ARP相关问题时,一定要把代理ARP、本地ARP、ARP欺骗这三者区分开,否则很容易被现象带偏。
3. 实战复现:用GNS3搭一个ARP欺骗环境
3.1 拓扑设计与准备工作
纸上谈兵说再多,不如动手搭一个环境。GNS3是我做网络实验最常用的工具,用它可以完整复现ARP攻击的整个生命周期,而且零风险——你不会把公司网络弄瘫。
准备环境如下:
- GNS3版本:2.2.x以上,内置了VPCS虚拟PC。
- 三台VPCS,分别模拟主机A(目标)、主机B(正常通信方)、攻击者C。
- 一台交换机,GNS3自带的Ethernet switch即可。
- 一台Wireshark,用于抓包分析。
网络规划:
| 设备 | IP地址 | MAC地址(自动生成) | 角色 |
|---|---|---|---|
| 主机A | 192.168.1.10/24 | 0c:xx:xx:xx:xx:01 | 目标主机 |
| 主机B | 192.168.1.20/24 | 0c:xx:xx:xx:xx:02 | 正常通信方 |
| 攻击者C | 192.168.1.66/24 | 0c:xx:xx:xx:xx:03 | 攻击者 |
拓扑连接很简单:三台VPCS各自用一根网线接在同一台交换机上,相当于它们在同一个二层广播域里。在GNS3里拖拽设备,连线,启动,然后给每台VPCS配好IP地址。
在VPCS命令行里,配置IP的方式非常直白:
ip 192.168.1.10 255.255.255.0三台都配好之后,先验证一下基本连通性。从主机A ping主机B,能通,说明二层链路没有大问题。
3.2 构建攻击脚本:伪造ARP应答
攻击者C要做的第一件事,是给主机A发送一条伪造的ARP应答,告诉它“网关是192.168.1.1,MAC是CC:CC:CC:CC:CC:CC”。
真实的攻击工具五花八门,但在GNS3的VPCS里没有现成的发包工具,最简单的方式是直接在攻击者C上手动构造ARP应答帧,或者用一台安装了Linux的GNS3设备来跑脚本。
用Linux设备的话,可以用一条极为经典的命令来发送伪造ARP报文。我用的是arping,几乎所有发行版里都有这个工具,它的作用就是向指定IP发送ARP请求或应答。
先确认一下目标主机的当前ARP缓存,在主机A上执行:
arp -a正常情况下会看到类似这样的输出(Windows下格式略有不同,但信息一致):
192.168.1.20 0c:xx:xx:xx:xx:02 dynamic接下来,攻击者C执行一条伪造应答命令:
arping -U -c 5 -I eth0 -s 192.168.1.1 192.168.1.10参数解释一下:
- -U:发送无请求(Unsolicited)ARP应答,也就是不需要有人问,直接主动告诉对方。这是欺骗的关键——不需要目标主机发起请求,你就可以单方面改写它的ARP缓存。
- -c 5:发送5个包,实际欺骗中通常是持续发送。
- -I eth0:指定网卡。
- -s 192.168.1.1:伪造的源IP,声称自己是网关。
- 192.168.1.10:目标主机,也就是告诉它“我是网关”。
执行完这条命令之后,回到主机A再看ARP缓存:
arp -a你大概率会看到网关的MAC已经变成了攻击者C的MAC。这时候,主机A依然能上网吗?如果攻击者C没有开启IP转发,那主机A所有的出网流量都会被发给攻击者C,而攻击者C收到之后直接丢弃,主机A立刻断网。
这在实验环境里已经足够了:主机A的ARP缓存被成功污染。
3.3 抓包验证:从Wireshark看攻击痕迹
光看ARP缓存还不够,要真正理解攻击原理,必须看报文。
在GNS3里打开Wireshark,选择连接攻击者C的那个交换机端口,抓包。然后重复执行一次攻击者C的arping命令。
在Wireshark的过滤栏里输入:
arp这样只会显示ARP协议相关的报文。你会看到如下关键信息:
- 源MAC是攻击者C的真实MAC。
- 源IP是192.168.1.1(伪造的网关IP)。
- 目标MAC是主机A的MAC。
- 操作码(Opcode)是2,代表这是ARP应答报文(reply)。
这几项信息一组合,整个欺骗逻辑就跃然纸上:一封署名写着“发件人:网关”,但实际邮戳盖着“攻击者C”的信,被投递到了主机A的信箱里。主机A完全不设防,直接更新了自己的ARP表。
我在实验里还做过一个有趣的对照:故意在Wireshark里同时抓交换机端口的双向流量,可以看到主机A在ARP缓存被污染后,主动发起了对192.168.1.1的新ARP请求——因为它发现已有表项快过期了——但每次请求都被攻击者C抢先应答。这就像有人在你每天查收的信箱前守株待兔,你每次问“谁的快递”,他都说“我的”,虽然你寄件的时候填的收件人根本不是他。
3.4 用真实的抓包表格复盘攻击过程
为了方便留存,我把一次完整ARP欺骗攻击的抓包结果整理成表格。这张表建议你自己在Wireshark里复现一遍再对照看,印象会深很多。
| 序号 | 时间 | 源MAC | 目的MAC | 源IP | 目的IP | 操作码 | 说明 |
|---|---|---|---|---|---|---|---|
| 1 | 0.000000 | CC:CC:CC:CC:CC:CC | AA:AA:AA:AA:AA:01 | 192.168.1.1 | 192.168.1.10 | 2(应答) | 攻击者C伪造网关,欺骗主机A |
| 2 | 0.001203 | AA:AA:AA:AA:AA:01 | CC:CC:CC:CC:CC:CC | 192.168.1.10 | 192.168.1.1 | 1(请求) | 主机A请求网关MAC,发给已被污染的缓存 |
| 3 | 0.001311 | CC:CC:CC:CC:CC:CC | AA:AA:AA:AA:AA:01 | 192.168.1.1 | 192.168.1.10 | 2(应答) | 攻击者C再次应答,维持欺骗 |
| 4 | 0.002008 | AA:AA:AA:AA:AA:01 | CC:CC:CC:CC:CC:CC | 192.168.1.10 | 192.168.1.1 | ICMP | 主机A开始向假网关发数据 |
| 5 | 0.002134 | CC:CC:CC:CC:CC:CC | AA:AA:AA:AA:AA:01 | 192.168.1.1 | 192.168.1.10 | 2(应答) | 攻击者持续更新欺骗报文 |
第4步的ICMP就是主机A发出的真实业务流量,它没有发给真网关,而是发给了攻击者C。到这里,欺骗已经生效。
4. 真实环境里的排查套路:从arp -a到交换机日志
4.1 快速判断:先看本机缓存有没有被污染
真实生产环境里没有GNS3那种“上帝视角”,你得靠命令行和日志去定位问题。排查ARP攻击最常用的命令依然是arp -a,但关键不是看它有没有显示,而是看显示的内容对不对。
在Windows上,网关通常是192.168.1.1或192.168.0.1这种地址。如果你执行arp -a,看到网关IP对应了一个不认识的MAC,或者一个MAC对应了两个不同的IP,基本可以怀疑有人在搞ARP欺骗。
在Linux下,命令是ip neigh show,或者老牌命令arp -n。输出格式更清晰,会明确标出状态,如果看到FAILED或INCOMPLETE,说明这台机器发出去的ARP请求一直得不到有效应答。
在华为交换机上,命令是display arp;在思科设备上是show ip arp。三层设备上查看ARP表还有个额外的好处:可以看到MAC地址对应的是哪个接口、哪个VLAN。这样就能快速把攻击者定位到具体端口。这一点在生产环境里尤其重要,因为你需要快速找到“物理位置”去处理。
排查的思路并不复杂:先确认是不是真的发生了ARP欺骗,再用交换机的表项把攻击源缩小到具体端口,最后去物理上处理那台设备。
4.2 实例:华为设备上如何查看主机在线时间和下线时间
很多运维朋友问过我:接口下怎么看一台主机具体的上线和下线时间?华为设备上有个很方便的命令:
display arp vlan xxx verboseverbose模式会显示更详细的信息,包括这个IP对应的MAC、所属VLAN、接口、以及学习到这条ARP项的时间。但要注意,这个时间是报文的“最新学习时间”,不完全是“首次上线时间”。如果主机一直持续发包,这个时间会不断刷新。
华为交换机还有一种方式,利用的是MAC表项:
display mac-address xxx-xxx-xxx这条命令可以看到该MAC地址在交换机里的老化时间以及出接口。如果某个MAC长时间没有流量,交换机就会把这条表项删掉,下次有流量时重新学习。所以如果你反复查询这个MAC,但在某一刻它从交换机表里“消失”了,就说明这台主机在那个时间点下线了。
更精确的上线/下线时间,需要开日志功能。在华为交换机上:
display logbuffer可以看到诸如MAC地址学习、接口状态变化等日志记录。再配合系统时间,就能反推出主机上线和下线的大致时刻。这个方法在做攻击溯源时非常有用——你发现某个MAC在凌晨3点开始疯狂发ARP包,就可以顺着时间线确认感染或攻击发生的时间点。
4.3 定位攻击源的三个实用技巧
排查ARP攻击最怕的是一头雾水。这里分享三个我实测有效的定位思路。
第一招:抓包看请求频率。
正常主机的ARP请求是间歇性的——只有在和某个IP通信又没有缓存记录时才会发送。如果你看到某台设备以每秒几十上百条的频率发送ARP请求或应答,那基本可以判定这要么是中毒主机,要么就是攻击工具。
第二招:对比网关的真实MAC。
找一个非常可靠的信息源,比如登录交换机查看网关IP对应的MAC,然后把内网某几台电脑的arp -a结果和它对比。如果电脑上显示的网关MAC和交换机查到的MAC不一致,说明最近一次ARP应答是伪造的。
第三招:用静态ARP表做排查方向的锚点。
先把网关的IP-MAC绑定写成静态,让ARS缓存不再被刷新。然后清空故障主机上的ARP缓存,强制它重新学习。如果重启缓存后,网关MAC依然错误,说明攻击者还在持续发包——顺着MAC查交换机端口就能锁定位置。如果重启后网关MAC恢复正常,说明攻击是间歇性的,得用持续抓包来捕捉。
5. 防御方案怎么选:静态绑定、DAI、端口安全,各有什么取舍
5.1 小环境首选静态绑定:两台设备上手就能配
如果网络规模小,比如家里、小型工作室、咖啡馆,最简单有效的方案就是静态ARP绑定。
Windows主机上绑定网关的IP和MAC,一条命令:
arp -s 192.168.1.1 GG-GG-GG-GG-GG-GG注意Windows下MAC地址用的是短横线分隔。Linux下用arp或ip neigh命令:
ip neigh add 192.168.1.1 lladdr GG:GG:GG:GG:GG:GG dev eth0 nud permanentLinux下的nud permanent是永久有效的意思,重启后需要重新配置。
网关侧也要同步绑定各主机的IP和MAC。家用路由器一般在“静态DHCP”或“IP与MAC绑定”界面里弄,原理是一样的——路由器只认绑定表里IP对应的MAC,其他MAC发来的包直接丢弃。
但静态绑定的局限性也很明显:每台设备都要绑定,新设备要手动添加,IP地址一变就要重新绑定。超过三四十台设备的网络,维护量就已经很大了。它适合小环境,不适合中型以上规模。
5.2 中大型网络必须上DAI:交换机拦截才是根治
中型以上网络,交换机要有动态ARP检测(DAI,Dynamic ARP Inspection)功能。它的原理是拦截所有ARP报文,检查其中的IP-MAC绑定关系是否符合DHCP Snooping绑定表。如果不符合,直接丢弃,并可以同时触发告警。
这意味着攻击者发来的伪造ARP应答根本过不了交换机这一关。在思科设备上配置方式大致如下:
ip dhcp snooping vlan 100 ip dhcp snooping ip arp inspection vlan 100 ip arp inspection validate src-mac dst-mac ip华为设备上叫Dynamic ARP Inspection,配置思路类似:
arp anti-attack check user-bind enableDAI的硬件前提是交换机得支持DHCP Snooping和ACL功能。这里有个重要提醒:DAI只在配置了trust的端口上放行信任的ARP报文,连接路由器、防火墙的上联口必须设置为trust,否则网关的合法ARP应答也会被拦截,导致全网断网。
我在实际项目里就遇到过这种情况:上了DAI之后,全网正常,但跨网段访问彻底不通。查了半天,发现是上联口没配trust,网关的ARP应答被交换机丢掉了。这是个非常典型的配置坑,一定要小心。
5.3 端口安全负责兜底:防的还是MAC地址伪造
端口安全(Port Security)是另一道防线,它的作用是限制每个交换机端口上可以学习的MAC地址数量。如果某个端口出现超过N个MAC地址,交换机就把这个端口关掉或丢弃后续数据帧。这主要是防MAC洪泛攻击的——也就是那种不断变换源MAC地址来填满交换机MAC表的手段。
同时,结合端口安全的一个典型应用,是指定某个端口只能连接某一台特定设备(绑定固定的MAC)。比如连接打印机的口子,只有打印机的MAC能从这里走流量,其他MAC一律丢弃。这就把一个物理端口“锁死”给了特定设备,伪造ARP报文的源头被直接掐断。
配置也很简单,在思科设备上:
interface GigabitEthernet0/1 switchport port-security switchport port-security maximum 1 switchport port-security mac-address stickysticky的作用是自动学习当前设备的MAC并绑定。如果这个端口突然出现第二台设备的MAC,交换机会触发安全策略,将端口置为err-disable状态,物理断掉该端口的通信。
5.4 三层架构的终极解法:直接削减ARP的作用范围
从网络设计的角度,还有一招是最釜底抽薪的——让ARP协议的适用范围尽可能小。
把用户划分到不同的VLAN,每个VLAN单独配置三层网关,这样ARP请求被广播域限制在了一个小范围内,攻击者想大规模欺骗就要跨VLAN,而跨VLAN转发完全依赖网关设备,二层可疑报文根本传不到其他VLAN。再加上DAI和端口安全,三层防御互相配合,攻击者就算在内网,想搞事也得先过这几道关卡。
这个方案成本高一点,架构设计也要重做,但在安全性要求较高的场景,比如企业办公网、金融行业的终端区,是必须考虑的。
6. 常见问题速查与个人心得
| 现象 | 可能原因 | 排查手段 |
|---|---|---|
| 全公司集体断网,重启交换机恢复几分钟后又断 | ARP洪泛或网关ARP欺骗 | 登录交换机看MAC表是否被填满,抓包确认是否有大量异常ARP报文 |
| 只有部分主机上不了网,且集中在同一网段 | 针对网关的双向ARP欺骗 | 在受影响主机上执行arp -a,对比网关真实MAC |
| 网速变慢,但ping延迟不高 | 中间人攻击正在监听转发 | 关键业务全用HTTPS,同时在交换机上开DAI和端口安全 |
| Windows上执行arp -s报“拒绝访问” | 当前账号权限不足或已有动态表项 | 用管理员权限执行,先删除旧动态项再绑定 |
| 交换机显示ARP表里一个IP对应多个MAC | 正在被ARP欺骗或主机网卡更换 | 找到最新MAC对应的端口,物理排查 |
| GNS3实验里两台路由器间看不到ARP请求 | 路由器开启了代理ARP,网段间互通经路由器代答 | 检查接口下是否开启代理ARP,必要时关闭 |
个人经验小结:
- 排查ARP攻击,永远先确认“网关的MAC到底是什么”,再谈其他。信息源越权威越好,最好直接登录交换机看。
- 防御不要一上来就上大而全的方案。小网络静态绑定足够,中大型网络DAI是首选,端口安全作为补充,三层划分作为兜底。
- 学习ARP攻击,强烈推荐自己在GNS3里用VPCS搭一次环境,亲手伪造一条ARP应答。整个过程半小时不到,但比看十篇原理文章都管用。
最后再说一个容易被忽略的细节:很多所谓的“ARP攻击”其实不是有人在故意攻击,而是有设备中了ARP病毒或木马程序,在后台持续向外发包。这种情况下的处理思路纯粹是“查毒隔离”,而不是跟攻击者对抗。所以遇到ARP异常,先别急着斗智斗勇,找一台中毒主机隔离掉,往往就天下太平了。