问题背景—MAC地址漂移
- 同一个MAC地址在交换机的某个接口上被学习到之后,又在相同VLAN的另一个接口上学习到,这种现象被称为MAC地址迁移。
- 少数的几次MAC地址迁移往往并不被认为是MAC地址漂移,比如运行了VRRP ( Virtual Router Redundancy Protocol,虚拟路由器冗余协议)的路由器在发生主备切换时,会引发MAC地址迁移,而这被视为正常的现象。
- 只有在短时间内发生大量的MAC地址迁移时,才被认为是MAC地址漂移。
- 在实际组网环境中,引发MAC地址漂移现象的可能性有多个:可能网络中存在二层环路,或者存在攻击行为等。
MAC地址漂移原因示例
二层环路
- 在下图所示的网络拓扑中,网络管理员错误地在SW2及SW3之间连接了一条线缆,而SW1、SW2、SW3所有接口都加入了相同的VLAN,于是三台交换机就构成了一个三角形的二层环路。
- 假设PC1要发送数据给网络中的某个设备时,初始情况下它会以广播的方式发送一个ARP Request报文以请求对方的MAC地址,可以分析一下由这个广播报文引发的问题。
问题现象
(1)PC1发送的广播ARP Request报文到达了SW1:
- SW1首先读取数据帧头部,发现其目的MAC地址为ffff-ffff-ffff,意识到这是一个广播数据帧,它将对其进行泛洪。
- SW1将该数据帧从GE0/0/2及GE0/0/3接口转发出去,
- 与此同时SW1还会学习该数据帧的源MAC地址5489-986e-29ad,并在MAC地址表中创建一个表项,该MAC地址被关联到GE0/0/1
接口。
(2)SW2在GE0/0/2接口收到SW1泛洪的ARP Request后:
- 读取数据帧头部,知道是广播数据帧,会同样对其进行泛洪,
- SW2将该数据帧从GE0/0/4接口发送出去,
- 与此同时SW2还会在MAC地址表中创建一个表项,记录该帧的源MAC地址5489-986e-29ad与接口GE0/0/2关联。
(3)SW3的报文处理流程(从GE0/0/3接口收到SW1泛洪的ARP Request、从GE0/0/4接口收到SW2泛洪的ARP Request)
- 假设SW3先在GE0/0/3接口收到SW1泛洪的ARP Request后,它将该帧从GE0/0/4接口发送出去,并学习该数据帧的源MAC地址5489-986e-29ad,该地址与接口GE0/0/3关联。
- 之后SW3在GE0/0/4接口收到SW2泛洪的ARP Request后,会将该帧从GE0/0/3接口发送出去,并学习该帧的源MAC地址,该地址与接口GE0/0/4关联(最近学习到的MAC地址表项覆盖原先的MAC地址表项)。
- 因为源MAC地址5489-986e-29ad先在GE0/0/3接口上出现,随后转而在接口GE0/0/4接口上出现,此时MAC地址迁移现象已经在SW3上出现。
如下图所示,描述了上述过程。
(4)SW2在GE0/0/4接口上收到SW3发送的ARP Request数据帧:
- SW2解析数据帧的源、目的MAC地址,由于数据帧的目的MAC地址是ffff-ffff-ffff,因此SW2对该数据帧进行泛洪(从接口GE0/0/2发出),
- 并刷新MAC地址表项,将该数据帧的源MAC地址5489-986e-29ad与接口GE0/0/4进行关联(最近学习到的MAC地址表项覆盖原先的MAC
地址表项)。 - 因为源MAC地址5489-986e-29ad先在GE0/0/2接口上出现,随后转而在接口GE0/0/4接口上出现,此时MAC地址迁移现象也在SW2上出现。
(5)SW1的报文处理流程(从GE0/0/2接口收到SW2泛洪的ARP Request、从GE0/0/3接口收到SW3泛洪的ARP Request)
- 假设SW1首先在GE0/0/2接口上收到广播数据帧,那么它会把该帧进行泛洪,从 GE0/0/1、GE0/0/3接口发出,并刷新自己的MAC地址表,把MAC地址5489-986e-29ad与接口GE0/0/2进行关联。
- 然后,SW1又在接口GE0/0/3收到了ARP Request,于是它泛洪该广播帧,将其从GE0/0/1及GE0/0/2接口发出,并刷新自己的MAC地址表,把MAC地址5489-986e-29ad与接口GEO/0/3进行关联。
- 显而易见,5489-986e-29ad这个MAC地址已经在GE0/0/1, GE0/0/2及GE0/0/3接口之间发生了迁移。
通过上述描述可知,这个ARP Request广播数据帧将不停地在SW1、SW2及SW3所构成的这个三角形二层环路中泛洪,这就形成了广播风暴。
广播风暴的产生会对整个交换网络带来极其恶劣的影响,大量的数据帧将瞬间消耗掉链路带宽,并将占用大量的设备资源,降低设备的处理性能,甚至导致网络瘫痪。
当现网中因为二层环路造成广播风暴时,可以通过如下现象进行初步判断:
- 交换机的显示灯会齐刷刷的闪烁
- 下联的PC会非常卡顿(PC收到大量的广播报文、CPU的占用率非常高,可以通过wirshark抓包查看)
- 交换机console、Telnet有对应的告警信息(HW)
网络攻击
- 某交换机的GE0/0/1接口连接着合法终端A,那么在网络正常情况下,交换机会从GE0/0/1接口收到A所发送的数据帧,并学习该数据帧的源MAC地址,从而形成正确的MAC地址转发表项。
- 假设现在一个攻击者连接到交换机的GE0/0/2接口,它伪造A的MAC地址并以该MAC地址为源发送数据帧,如此一来交换机将在GE0/0/1及GE0/0/2接口上不断收到源MAC地址相同的数据帧,MAC地址漂移现象便会发生,当然此时A的通信将极有可能出现问题。
MAC地址漂移应对方法
- 二层环路以及网络攻击行为均有可能引发MAC地址漂移。
- 对应二层环路这个诱因,我们可以部署生成树协议(STP、RSTP、MSTP)或者环网保护协议(RRPP、ERPS)进行规避,从而避免引起MAC地址漂移问题。
- 也可以利用交换机的端口安全特性,也可以解决MAC地址漂移问题。
利用端口安全应对MAC地址漂移
配置端口MAC地址学习优先级
- 在交换机端口上配置MAC地址学习优先级,可以防止出现MAC地址漂移。
- 当MAC地址在交换机的两个接口之间发生漂移时,可以将其中一个端口的MAC地址学习优先级调高,而高优先级的端口学习到的MAC地址表项将覆盖低优先级端口学习到的表项,因此便可以规避MAC地址漂移问题。
- 缺省时,所有端口的MAC地址学习优先级为0,使用mac-learning priority命令(HW)可以调节端口的MAC地址学习优先级,优先级的值越大,则优先级越高。
示例
- 如下图所示,交换机SW的GE0/0/1接口连接着一台PC,它的MAC地址为5489-98cb-2bf2。
- 假设现在一个攻击者控制了PC2,并且伪造PC1的MAC地址开始向交换机发送数据帧,从而导致5489-98cb-2bf2这个MAC地址将在交
换机的GE0/0/1及GE0/0/2之间发生漂移。 - 此时交换机的MAC地址表是动荡的,在这种情况下,发往PC1的数据帧很可能无法正确到达PC1,因为交换机上5489-98cb-2bf2的MAC地址表项可能会被PC2发送的数据帧刷新。
- 通过在GE0/0/1接口上配置mac-learning priority命令提高该接口的MAC地址学习优先级(比如设置成5),那么该接口的优先级便比GE0/0/2更大(缺省优先级为0)。
- 通过部署学习MAC地址优先级的配置后,即使交换机在GE0/0/2收到PC2以MAC地址5489-98cb-2bf2为源发送的数据帧,也不会覆盖掉GE0/0/1接口的表项。
配置不允许相同优先级接口MAC地址漂移
- 缺省时,交换机接口的MAC地址学习优先级均为0,
- 优先级更高的接口学习到的MAC地址表项不会被优先级低的接口学习到的表项覆盖,
- 相同优先级的接口之间,还是能够会相互覆盖相同的MAC地址,从而产生MAC地址漂移现象。
- 使用undo mac-learning priority priority-id allow-flapping命令(HW),可以禁止相同优先级的接口发生MAC地址覆盖,从而规
避MAC地址漂移问题,提高网络的安全性。
示例
- 还是如上图所示,SW的 GE0/0/1及GE0/0/2接口的MAC地址学习优先级均为0,
- 假设PC1率先接入SW,并且SW已经在GE0/0/1接口上学习到了其MAC地址,
- 在SW上配置undo mac-learning priority priority-id allow-flapping命令,配置该命令之后,交换机将不再允许MAC地址学习优先级均为0的接口之间发送MAC地址漂移。
- 因为GE0/0/1接口先学习到了MAC地址5489-98cb-2bf2,此时如果攻击者连接到GE0/0/2接口并且伪造该MAC地址发送数据帧,SW不会将原有的表项覆盖。
- 如果PC1下电,则交换机的接口GE0/0/1物理状态将会切换为down,此时若在GE0/0/2接口上收到PC2发送的非法数据帧时,由于MAC地址表中没有关于5489-98cb-2bf2的表项(老化超时后被删除),因此它会学习该MAC地址并且与接口GE0/0/2进行关联。
- 现在如果PC1又上电了,由于交换机的MAC地址表中已经存在相关表项,并且使能了禁止相同优先级的接口发生MAC地址覆盖功能,因此SW将无法学习到合法的MAC地址表项,从而发往PC1的数据帧将被SW从GE0/0/2接口转发出去,所以undo mac-learning priority priority-id allow-flapping命令需谨慎配置。