
ARP与Proxy ARP
ARP简介
当我们有两个PC通过三层路由进行通信时,我们的路由既希望拿到目标主机的IP也希望拿到目标主机的Mac地址的时候(因为IP报文必须封装成帧才能通过物理网络发送,因此发送方还需要找到接收方的物理MAC地址),ARP就产生了,它会获取目标主机的Mac地址与IP地址(也可以理解为将IP地址解析尾MAC地址的协议)。并且会产生一张ARP的表,用于存储IP地址和MAC地址的关系。一般ARP表项包括动态ARP表项和静态ARP表项。
ARP实验与分析
首先创建AR1220
的三层路由器,然后添加两台PC配置分别如下。
PC6 192.168.1.2/24 255.255.255.0 192.168.1.1
PC7 192.168.2.2/24 255.255.255.0 192.168.2.1
然后我们可以通过如下命令去配置路由器,绑定接口与网关。
# 查看ARP表
dis arp
system-view
# 配置PC6接口与网关地址
int G0/0/1
ip a 192.168.1.1 24
# 查看当前配置情况
dis this
# 配置PC7接口与网关地址
int G0/0/0
ip a 192.168.2.1 24
# 查看当前配置情况
dis this
# 查看配置表情况
dis ip int b
# 禁用当前接口
undo shut
然后我们来抓GE0/0/1
的接口,然后我们通过PC6向PC7发包来进行分析。
首先第一个包,是一个广播包54-89-98-CA-13-B5
物理Mac是我们PC6主机的,发了一个广播包(全f
)。
接着我们来看第二个Arp包。
我们发现它是从AR2的网关192.168.1.1
发往PC6的。为什么会这样?
其实就好像PC6说我要找PC7,然后网关192.168.1.1
(G0/0/1接口)说我帮你找到了,你要找PC7找我就好了,我帮你转告PC7。然后PC6就在本地记录了网关的ip与mac地址。
我们可以通过arp -a
查看本地记录的arp表
然后我们来看我们的ping包,可以看到首先PC6把包发往了网关,然后路由再根据路由表发往了指定的IP地址的mac主机PC7。
关于包中字段的意思如下:
获取接口的Mac地址
# 查看g0/0/0接口信息,其中有MAC地址
dis int g0/0/0
从PC6发往PC7时,源IP和目的IP一直都没变,但是源MAC和目的MAC一直在变。
Proxy ARP
企业内部进行子网划分时,可能会出现两个子网网络属于同一网段,但是却不属于同一物理网络的情况,两个子网网络间被路由器分割。这时可以通过网络内主机的路由信息,使发往其他子网的数据先发送到连接不同子网的网关设备上,再由网关设备转发此数据报文。但是这种解决方案需要配置子网中所有的主机的路由,并不便于管理和维护。
在网关上部署路由式Proxy ARP功能,可以有效解决子网划分带来的管理和维护方面的问题。路由式Proxy ARP的功能可以使IP地址属于同一网段却不属于同一物理网络的主机间能够相互通信,并且主机上不需要配置缺省网关,便于管理和维护。
路由式Proxy ARP组网如图所示。Router通过接口IF1和IF2连接两个子网网络,接口IF1和接口IF2的IP地址不在同一个网段。子网1内的主机Host_1与子网2内的主机Host_2的IP地址也在同一网段。主机Host_1和Host_2上未配置缺省网关。在Router上配置路由式Proxy ARP可以使子网1和子网2内主机间能够互相通信。
注意:Host1主机的192.168.1.1/16
与Host2主机的192.168.2.1/16
是在同一网段下,因为在以前我们讲到过,ip一位占8bit,这里写的16
占两位,所以他们都是在192.168.0.0
下,所以他们是在同一网段中。
要想使同一网段不同子网通信,只需要在R1路由器中启动ARP Proxy就可以了。
(下面我们来操作演示一下)
首先需要更具我们刚刚讲的PC进行配置。
然后我们需要在ARP中进行配置启动ARP代理
# 找到0/0/0接口
interface GigabitEthernet0/0/0
# 配置ip
ip address 192.168.1.254 255.255.255.0
# 启动arp代理
arp-proxy enable
interface GigabitEthernet0/0/1
ip address 192.168.2.254 255.255.255.0
arp-proxy enable
# 查看配置情况
dis ip int b
注意:如果不进行启动arp代理,包发出去后就回不来了。
运行测试:
Linux ARP Proxy
接下来我们来实现Linux下的ARP Proxy。
我这里的环境是两台Ubuntu系统,所以在此之前请关闭防火墙。
# 关闭防火墙
sudo ufw disable
下载抓包工具
apt-get install bison flex
wget http://www.winpcap.org/install/bin/WpcapSrc_4_1_2.zip
unzip WpcapSrc_4_1_2.zip
cd winpcap/wpcap/libpcap
chmod +x configure runlex.sh
CFLAGS=-static ./configure
make
cd rpcapd
按照上面的图,首先我们在第一台机器创建虚拟网卡对,创建ns0
网络名称空间,然后为ns0
网络名称空间的eth0
配置IP10.1.1.10/24
并激活网卡。
# 创建虚拟网卡对eth0
ip l a veth0 type veth peer name eth0
# 创建名称空间
ip netns add ns0
# 关联网络名称空间于虚拟网卡
ip l s eth0 netns ns0
# 配置网络名称ip
ip netns exec ns0 ip a a 10.1.1.10/24 dev eth0
# 激活网卡
ip netns exec ns0 ip l s eth0 up
# 查看网络情况
ip netns exec ns0 ifconfig
然后我们添加一个不存在且受保护的ip169.254.1.1
,让它作为网关发出去,然后通过ARP代理又以相同的接口返回回来。
目的是:当ns0发送 ARP 请求服务器 169.254.1.1
的 MAC 地址,veth0
收到这个请求时会进行判断,由于目标 169.254.1.1
不属于本网段(即跨网段),此时便返回自己的接口 MAC 地址给 ns0,后续ns0(10.1.1.10
)访问ns1(10.1.1.20
)时,目标 MAC 直接封装为 MAC254。
# 添加本地交换路由 clico
ip netns exec ns0 ip route add 169.254.1.1 dev eth0 scope link
# 添加默认路由
ip netns exec ns0 ip route add default via 169.254.1.1 dev eth0
# 启动arp_proxy代理
echo 1 > /proc/sys/net/ipv4/conf/veth0/proxy_arp
查看路由表,并删除ns0默认路由10.1.1.0
的记录,然后激活网卡,并在路由表中添加好接收有10.1.1.10
的路由记录。
以及添加10.1.1.20
的出处为Host1的Ip,并且是从ens3出去的。(这里根据自己的实际情况做调整)
# 查看路由表
ip netns exec ns0 route
ip netns exec ns0 route -n
# 删除虚拟网卡对
ip netns exec ns0 route delete -net 10.1.1.0 netmask 255.255.255.0
# 激活网卡
ip l s veth0 up
# 添加路由
ip route add 10.1.1.10 dev veth0 scope link
ip route add 10.1.1.20 via 10.0.0.3 dev ens3
veth0的mac。
接下来Host1需要执行的是一样的命令。
arp -a
# 创建虚拟网卡对
ip l a veth0 type veth peer name eth0
# 添加网络名称空间
ip netns a ns1
# 绑定虚拟网卡到ns1中
ip l s eth0 netns ns1
# 绑定IP到ns1中的eth0网卡
ip netns exec ns1 ip a a 10.1.1.20/24 dev eth0
# 激活ns1中的eth0网卡
ip netns exec ns1 ip l s eth0 up
# 添加路由
ip netns exec ns1 ip route add 169.254.1.1 dev eth0 scope link
ip netns exec ns1 ip route add default via 169.254.1.1 dev eth0
echo 1 > /proc/sys/net/ipv4/conf/veth0/proxy_arp
# 删除默认路由记录
ip netns exec ns1 route delete -net 10.1.1.0 netmask 255.255.255.0
# 激活eth0网卡
ip l s veth0 up
# 查看网卡
route -n
# 访问 10.1.1.20 从默认路由出去
ip route add 10.1.1.20 dev veth0 scope link
# 要想访问 10.1.1.10 从ens33出去找到172.12.1.10的ip
ip route add 10.1.1.10 via 10.0.0.2 dev ens3
# 查看网络名称空间ns1的路由规则
ip netns exec ns1 route -n
然后我们开启一个新的终端进行抓包。
# Host1抓包
tcpdump -i veth0 -e -nn
# Host2抓包
tcpdump -i veth0 -e -nn
# 运行测试
ip netns exec ns0 ping 10.1.1.20
测试没有问题。下图是我们抓的包。
通过抓包我们会发现,ns0的eth0会先去问veth0谁是169.254.1.1
?veth0说他也不晓得,但是我可以把我的mac给你,我这边的路由可以给你用。ns0说好好好。然后他就去请求10.1.1.20
但这个10.1.1.20
我本身没得但是我有veth0的mac地址,veth0所处的路由表有我以它的身份去访问就行。(所以就把ns0的mac身份证改成veth0的mac身份证,IP不变然后就去访问)。到了Host1那边veth0又问谁是10.1.1.20
?然后那边eth0就回答我是。
好处
这样做的好处如下:
1.通过将所有流量引导到一个特殊的网关 169.254.1.1
,从而引流到主机的 veth0
网络设备上,最终将二三层流量全部转换成三层流量来转发。
2.在主机上通过开启代理 ARP 功能来实现 ARP 应答,使得 ARP 广播被抑制在主机上,抑制了广播风暴,也不会有 ARP 表膨胀的问题。(也就是只在veth0和eth0之间有arp包不会向其他网卡发送广播)
如果是Bridge的话将会向所有连接的进行广播,从而造成网络瘫痪。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

