cnblogs.com/f-ck-need-u/p/8455004.html

DR模式中,关于ds响应arp请求,但是RS并不会响应arp请求的问题

arp是地址解析协议,用于将主机IP地址解析为主机的MAC地址,既是IP与MAC的对于关系
因为arp广播,想要保证目标地址为vip的报文发送给DS,我们就需要只让LVS上响应VIP的arp请求,而RS上不响应,即修改RS上内核参数:(arp_ignore,arp_announce)将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求
arp_announce 0.1.2级
arp_igonre 0-8级
arp_ignore和arp_announce这两个变量的作用正是设置使用哪个源IP和哪个源MAC
其中arp_ignore设置的是收到请求包后,在应答包中将本机的哪个IP地址和MAC地址回应给请求者以供缓存;arp_announce设置的是发出请求包时,选择哪个IP和MAC地址供响应者缓存
DR模式下ARP设置分析 - 图1

1. ARP协议简介

ARP(Address Resolution Protocol)协议称为地址解析协议,用于将主机的IP地址解析为主机的MAC地址。RARP协议相反,是将MAC解析为IP地址。属于数据链路层的协议
ARP解析时分为两种情况:

  1. 解析目标与自己在同一网段

A解析同网段B,A根据自己的IP和子网掩码判断B和自己处于同一网段,这时A就会向该网段的广播地址,发一个ARP广播,寻求B的MAC地址,所有人都收到了数据包,但是只有B回应自己的MAC的地址

  1. 解析目标与自己不在同一网段

A解析不同网段B,A根据自己的IP和子网掩码判断B和自己不是一个网段,这时A就向自己的网段广播,发送一个ARP广播用来解析网关的MAC地址,也就是路由器的接口MAC地址,然后路由器回应,A缓存回应的MAC地址。

当发送ARP请求广播后,目标设备会进行应答,在这一次请求过程中,发送请求的A会缓存B的arp记录,接收方也会缓存
A的ARP记录。也就是一次请求,两处更新。

ARP报文:
image.png
各字段解释:
其中op代表的是操作数,有1-4。其中1表示ARP请求报文,2为ARP响应报文,3为RAPR请求报文,4是RARP响应报文。
硬件类型:硬件地址类型,硬件地址不止以太网一种,是以太网类型时,值为1
协议类型:表示要映射的协议地址的类型,ipv4为0X0800
发送端以太网地址:时发送端ARP请求或应答的硬件地址。
分析:
当发送ARP请求报文的时候,op的值设置为1。其中目的MAC地址,为广播地址ff:ff:ff:ff。源ip和源mac地址可以不对应。(后面会讲到)
在响应报文的时候,op的值设置为2,会将源IP地址源MAC地址与目的IP目的MAC地址调换。并且之前的广播地址,被替换。
无论时ARP请求还是响应报文都有源MAC,源IP,目标MAC,和目标IP。

2.arp_ignore和arp_announce变量的作用

我们已经知道arp请求和响应报文中,IP地址可以和MAC地址不对应。那么我们在请求的时候,用那个源IP那个源MAC在应答的时候用那个源IP那个源MAC。(应答包中源IP地址并不一定是请求包中的目标IP,可能会更换为本机的其他IP地址)

arp_ignore和arp_announce这两个变量的作用正是设置使用那个源IP和那个源MAC。其中arp_ignore设置的是收到请求包后,在应答包中将本机的那个IP地址和MAC地址回应给请求方以供缓存;arp_announce设置的是发出请求包时,选择那个IP和MAC地址供响应者缓存。
DR模式下ARP设置分析 - 图3

细看arp_announce和arp_ignore
arp_ignore
该变量接受一个整数值。定义的是当本机接收到别的主机发送的ARP请求时的不同应答模式:回应哪个IP和MAC地址给请求者。

  • 0 - (default):将本机所有非lo接口的IP地址都回应出去。
  • 1 - 只有当ARP请求中的目标IP地址配置在流入接口上时才响应。
  • 2 - 只有当ARP请求中的目标IP地址配置在流入接口上时,且该IP地址(即发送者源地址)是接口地址上的子网地址时才响应(例如192.168.100.10/24和192.168.100.10/16的关系)。
  • 3 - do not reply for local addresses configured with scope host, only resolutions for global and link addresses are replied。
  • 4-7 - 保留
  • 8 - 不回应任意地址。
  • 当某接口接收到ARP请求时,将取conf/{all,interface}/arp_ignore中值最大的生效。

注意这里是否响应不是指是否构建响应,而是响应的包能不能从端口发出去。换句话说就是包一定会构建,能不能出去就要看设置的情况。
案例:
image.png
分析:
当arp_ignore=1时,当主机收到arp请求时,只有arp请求包中目标ip和流入接口上的ip相同时,才会响应该IP以及该接口的MAC地址。
例如设置eth0网卡的该变量值为1。
这时主机B上ping 192.168.100.17时,主机A将只会响应eth0_MAC给主机B。且Ping 192.168.100.36ping不通(这点需要注意,在后面配置LVS的arp参数时,外界主机往往只能ping通同网段的其中一个地址)
image.png
从结果可以看出,主机A收到目标ip为192.168.100.36的ARP请求后,并没有响应给主机B,因为主机B发出的ARP请i去包到达主机A时流入的接口为eth1,构建号ARP响应包后,经过路由策略从eth0出去(因为eth0在路由表的前面,优先级高)而eth0上的arp_ignore=1,表示只响应从eth0进入的数据包。而从其他接口流入,想从我这里流出是不可能的。因此主机B就不知道192.168.100.36的MAC地址,从而无法与主机A通信。

这里的关键是:流入接口时eth1。如果从eth1流出是可以的。但是默认路由策略是从eth0流出。而eth0设置的ignore=1也就是只响应从eth0流入的arp数据包。如果此时将eth0接口的优先级调低。则此响应正常能进行,并且配置在eth0上的地址也可以响应出去,并且MAC地址是eth1网卡的地址。因此在arp请求过程中,目标主机路由表的先后顺序非常重要。它不仅决定了数据从哪儿流出,更深层次上还决定了流出时使用哪个MAC地址。而这直接决定是否能成功响应ARP请求。

arp_annouce:
该变量接受一个整数值。它定义的是当发送ARP请求时,在请求数据包中填入的源IP地址和源MAC地址,它们是被响应者缓存的内容

  • 0 - (default)可以使用本机上任意接口的任意地址。
  • 1 - 尽量不使用不在目标IP所在子网的地址。当目标主机可以通过该接口达到,但要求ARP数据包中的源IP地址是逻辑网络接口网段中的地址时,设置为该级别很有用。当生成ARP请求数据包时,将检测所有包含目标IP的子网(自身网段或子网都可以),如果源IP地址处于该子网内,则使用该地址。如果没有包含该源IP地址的子网,则使用级别2(arp_announce=2)来处理。
  • 2 - 总是为目标地址寻找最佳本地地址作为ARP请求的源IP地址。这种模式下,将忽略源IP地址,而是尝试选择出能和目标IP最佳通信质量的IP地址。这个IP是通过寻找各流出接口上的主IP地址(primary IP,不能是secondary IP)得到的,它需要和目标IP地址在同网段或属于其子网内。如果没有选出合适的地址,将选择第一个流出接口上的IP地址,这样不仅可以接收到应答包,还能无视已经手动通告的源地址。

解释一下:

  • arp_announce=0时,向外发送ARP请求时,很可能会使用流出接口的ip地址和MAC地址,这没有硬性限制
  • arp_announce=1时,尽量使用与目标ip地址在同一子网的地址,例如目标IP地址为192.168.100.40/16而本机有ip地址192.168.10022/24,这个ip地址时目标IP地址子网内的一个地址,因此会尽量使用该地址作为arp请求中的源ip地址,但是源mac地址还是数据流出接口的mac地址
  • arp_announce=2时,不管APR请求包中指定的源IP地址是什么,总会在本地搜索出和目标ip地址最匹配的ip地址来作为源地址,它会优先选和目标ip同一子网的本地ip,如果没有则选路由表中第一个流出接口的ip。

3.设置arp_ignore和arp_announce

从linux2.2.xx开始,除了回环地址(127.0.0.1)和广播地址外,其他所有地址(包括回环接口上的别名接口)都会做arp响应。
在lo接口上设置两个参数没有意义,因为这两个变量只对能arp回应的接口才生效(例如eth0和eth1等对外通信的普通接口)
如果在接口设置了别名IP,例如eth0:0,由于它们仍然通过使用所依附的接口流入流出数据,因此别名一样生效。

  1. echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
  2. echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
  3. echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
  4. echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce

将conf/all/arp_ignore设置为1,可以保证无论哪个对外通信的网卡接口都只会向外响应自己接口上的IP地址(甚至可能有些同网段的接口因为路由顺序排在后面而响应不出去),这样就隐藏了设置在lo别名接口上的VIP地址。
将conf/all/arp_announce设置为2,可以保证本机只向外通告普通网卡上的IP地址,lo别名接口上的VIP不可能被通告出去。