首页 > > > ARP与OpenFlow based SDN
本文图片源自互联网,侵删。
ARP平时的使用比较多,原理也比较简单,今天来系统的全面的看一下ARP,以及在SDN中的ARP可以是怎么样的。
ARP全称是地址解析协议(Address Resolution Protocol)。它由RFC826定义,这是个不太长的RFC,标题比较有意思:An Ethernet Address Resolution Protocol -- or -- Converting Network Protocol Addresses to 48.bit Ethernet Address for Transmission on Ethernet Hardware
一个以太网地址解析协议 --或者是-- 将网络协议地址转换成48bit的以太网地址,以便在以太网设备上传输
够直观!
目前最广泛的应用是通过IP地址,查询MAC地址。如无特殊说明,本文之后说网络协议地址,就是IP地址,以太网地址,就是MAC地址。ARP是IPv4中必不可少的协议,不过在IPv6中已经被NDP代替。
了解ARP的应用之前,先来看看ARP的协议格式。

之后的28个字节是ARP协议的具体内容。主要就是描述了对应的网络协议地址和数据链路标识。
前面说过ARP的作用就是获得邻居设备的MAC地址,这一节看看这个过程具体是怎样。

前面已经提到了ARP cache。试想一下,如果每个ICMP封包都需要ARP广播一次获取目的设备的MAC地址,那网络上必定泛滥着ARP广播,而各个设备也必定疲于应付广播数据,即使没有任何实际数据包发送到设备本身。ARP cache就是为了解决这个问题提出的,这是设备本身的一个缓存,用来记录已知的IP地址和MAC地址的对应关系。根据RFC826,任何设备收到了任何ARP数据包,都必须更新其本地的ARP cache,更新的内容来自于ARP数据包的SPA和SHA。因此,在上面的过程中,设备A和设备B的ARP cache同时得到了更新。
ARP cache可以通过arp命令查看:
[~]$ arp -a
也可以通过ip neighbor命令查看。确切的说,arp命令只能查看IPv4地址和MAC地址的对应,而ip neighbor 还包含了IPv6的对应关系。
[~]$ ip neighbor
192.168.31.203 dev eth0 lladdr 10:48:b1:b6:0a:a7 STALE
192.168.31.1 dev eth0 lladdr 8c:be:be:28:40:75 REACHABLE
fe80::122a:b3ff:fea1:73a2 dev eth0 lladdr 10:2a:b3:a1:73:a2 STALE
那新的问题来了,随着时间的运行,设备上的ARP cache必定越来越大,消耗设备的资源也必定越来越多。为了解决这个问题,ARP cache中每条entry都有对应的存活时间。在Linux下,这个存活时间不是简单的过了一定时间就删除,具体过程比较复杂。stackoverflow上的解释比较到位,感兴趣可以看看。简单概括:
这是恶意攻击的场景。
前面说过任何设备仅会处理TPA与自身IP地址匹配的ARP数据,但是ARP spoof system会修改这个行为。对于想拦截的逻辑连接,ARP spoof system会匹配含有相应的TPA的ARP请求,并且回送一个带有自身的MAC地址的ARP响应。这样,发送ARP请求的源设备会以为ARP spoof system是期望的目的设备,所有数据包都会发送到ARP spoof system。
通常ARP spoof system会伪装成默认网关,这样所有出外网的数据包都会被拦截。简单的攻击是直接丢包,造成断网,稍微复杂点的会篡改包的内容,再转发出去。ARP spoof通常是网络攻击的开始。
这是正常网络规划的场景。原理其实与ARP spoof类似,只是这是设计好的网络特性。具体可以参考RFC925和RFC1027。
当目的设备不能够或者不愿意(出于安全或者性能角度)响应ARP请求时。可以由另一个设备将自己的MAC地址回送给源设备,之后源设备将所有的数据发送到该设备,再由该设备转发到实际的目的设备。这实际上也是欺骗了源设备,只不过这里的设备是一个设计好的,不会干坏事的中继设备。
proxy ARP可以在路由器上配置,从而代替默认网关,为子网实现三层转发。而子网内的设备仍然会认为自己在一个二层网络中。这种用途现在比较少。

proxy ARP还有个用途就是用于NAT设备的ARP应答。设备X访问设备Y,当网络包走到路由器C,路由器C首先也会发送ARP广播请求,来查询目的设备的MAC地址。但是由于Y设备与路由器C不在一个数据链路中,Y设备收不到路由器C发出的ARP广播请求,因此需要NAT设备代答ARP。这里也可以理解成,22为一个虚拟的端口(72.3.4.55)提供ARP响应功能。这样数据包能接着发送到NAT设备,进而转发到设备Y。

Inverse ARP由RFC2390定义,用来通过数据链路标识(MAC地址)查找网络协议地址(IP地址),对应的ARP协议操作码分别是8,9。Reverse ARP用于主机启动的时候通过向RARP server请求自身的IP地址,对应的ARP协议操作码分别是3,4。不过Reverse ARP已经被DHCP替代了(想当年学计算机网络的时候还是考试内容)。这两者的区别是Reverse ARP只能通过自己的MAC地址查询IP地址,而Inverse ARP可以查询别人的。
ARP数据传输本身是无状态的。因此,就算设备没有发出ARP请求,如果该设备收到了其他设备发来的ARP数据包(包括ARP请求和响应),那么该设备还是会更新自身的ARP cache。这就是GARP(Gratuitous ARP)的实现背景。Gratuitous翻译过来可以是无故的,免费的。GARP的作用就是告知别的设备来更新它们自身ARP cache中关于GARP中的SPA和SHA的对应关系。就像前面说过的一样,任何ARP的数据都来自SHA和SPA。
前面说过,任何设备收到了任何ARP数据包,都必须更新其本地的ARP cache。因此,GARP可以是一个ARP请求(操作码1),也可以是一个ARP响应(操作码2)。这两种情况的共同点:
不同点在于:
由于TPA被设置成了源设备的IP地址,即使GARP是一个ARP请求,它也不期望会得到任何响应。因为不会有设备的IP能匹配TPA。
GARP的实际应用,除了让别的设备更新相应的ARP entry。还有个重要的作用就是用在冗余IP(或者说虚拟IP)的场景下。
现在假设有一个虚拟IP 10.0.0.1作为网络的默认网关,而上行线路有两个路由器做主备。当路由器A发生故障,路由器B得知之后,会广播一个GARP出来,让网络中的设备更新ARP cache,使得默认网关的MAC地址指向路由器B,这样路由器B将作为主路由器提供服务。这就是VRRP协议的基础,而OpenStack Neutron中的HA router正是基于VRRP实现的。

ARP探测,这个由RFC5227定义。当一个设备以任何方式获取了IP地址,想在一个数据链路中上线时,如果该数据链路中已经存在了一个相同IP地址的设备,那该设备上线将导致两个设备网络都不可用。为了防止该情况的发生,可以使用ARP probe判断当前网络是否已经有指定IP地址。
ARP探测包本身也是一个普通的ARP请求(操作码1),但是其SPA需要设置成0.0.0.0。前面说过,ARP cache的更新内容来自于SPA和SHA,由于SPA为空,ARP探测包中的ARP数据是无效的,因此ARP probe数据包不会更新任何设备的ARP cache。这是合理的,因为ARP 探测本身就是一个不确定的行为,如果数据链路中已经有了相应的IP地址设备,自然也不希望在ARP探测时修改已有的ARP entry。
ARP探测报文是一个广播报文,也就是说它的以太网报头中的目的MAC地址是ff:ff:ff:ff:ff:ff
ARP探测报的TPA设置成希望探测的IP地址,这样如果数据链路中已经有同IP的设备,收到探测包之后会给源设备发送ARP响应,而源设备也就知道了数据链路中存在相同IP地址的设备。
ARP探测如果没有发现IP被占用,通常会接着发送一个GARP来告知数据链路中的其他设备有关自己的IP地址和MAC地址。根据RFC5227,这个时候的GARP应该是一个ARP请求(操作码1)。

设备通过ARP获取邻居设备的MAC地址,第一步就是发送ARP广播。由于ARP cache有老化时间,如果一个数据链路足够大,那在实际的网络链路中,ARP广播数量也不容小觑。
在SDN中,由于SDN的控制层面掌握着所有端口的信息,包括了端口的IP地址和MAC地址,可以在数据层面下发ARP代答流表。
priority=100,arp,arp_tpa=10.0.0.1,arp_op=1 actions=load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],mod_dl_src:fa:16:3e:1d:53:34,load:0xfa163e1d5334->NXM_NX_ARP_SHA[],load:0xa000001->NXM_OF_ARP_SPA[],IN_PORT
例如,这条流表中,对目的地址是10.0.0.1的ARP请求,直接生成ARP响应:
从源设备的角度来说,这就是一个再正常不过的ARP请求响应过程。但是通过OpenFlow的实现,可以带来以下好处:
SDN管理的环境中,虚拟IP可以配置在多个端口上,例如OpenStack Neutron 里的allowed address pair,可以将一个虚拟IP在多个端口上浮动配置。当虚拟IP从端口A移动到端口B时,需要通知数据链路中的其他端口虚拟IP对应的MAC地址发生变化,这个时候可以由SDN控制器代为发送GARP来更新数据链路中的设备的ARP cache。
前面说过NAT设备需要为对应的外网IP地址做ARP代答,否则数据包在最后一个链路无法获取MAC地址。SDN可以为floatingIP下发ARP代答流表,这样目的地址是floatingIP的数据包最终能发送到SDN 交换机并转发到实际的端口。
传统的ARP协议的大部分实现都基于操作系统协议栈的响应。SDN的出现增加了网络实现的灵活性,通过SDN对ARP进行优化,能降低网络延时,减轻数据链路的负担,增加网络的安全性。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31509949/viewspace-3161202/ ,如需转载,请注明出处,否则将追究法律责任。