采取负载均衡之LVS(二)爬山涉水VS_TUN和VS_D纳瓦拉的arp难点,lvsvs_tun

1.使用keepalived进行热备份的系统需要一个虚拟的IP地址,然而该虚拟IP地址到底属于哪台机器是根据热备群的主备来决定的,因此主机器在获得该虚拟IP的时候,必须要广播一个免费的arp,起初人们认为这没有必要,理由是不这么做,热备群也工作的很好,然而事实证明,这是必须的;

Linux邻居子系统的细节之confirm-OpenVPNserver模式的MAC地址学习

在《Linux实现的ARP缓存老化时间原理解析》一文中,我剖析了Linux协议栈IPv4的邻居子系统的转化,再次贴出那个状态机转化图,可是这个图更详细了些,因为它有一个外部输入,那就是confirm:

图片 1

请注意,如果socket或者路由子系统在上层confirm了一个neighbour,那么该arp将持续留在reachable状态而可以不用转换到stale状态。这个特性是有意义的。请观察一个现象:
**1.本机IP地址为192.168.1.10/24,直连的机器IP地址为192.168.1.20/24,从本机ping对端;

为何本端在reachable状态到期了仍然不切换状态,不重新解析对端IP地址?为何对端的IP地址修改掉或者删除掉之后,本端马上发现了这一事实,间隔reachable到期时间后发出了arp
request?**

**MSG_CONFIRM (Since Linux 2.3.15)

**

在《Linux实现的ARP缓存老化时间原理解析》一文中,我剖析了Linux协议栈IPv4的邻…

应用负载均衡之LVS(二):VS_TUN和VS_DR的arp问题,lvsvs_tun

本文目录:

  1. ARP协议简介
  2. arp_ignore和arp_announce变量的作用分析
     2.1 arp_ignore
     2.2 arp_announce
  3. 设置arp_ignore和arp-announce

  4. ARP协议简介


ARP(Address Resolution
Protocol)协议称为地址解析协议,用于将主机IP地址解析为主机的MAC地址,即IP<-->MAC之间一一映射。RARP协议相反,是将MAC地址解析为IP地址。

ARP解析时分两种情况:

当发送ARP请求广播后,目标设备会进行应答,其中请求数据包和应答数据包的格式非常接近。以下是请求包和应答包数据格式的一部分,完整格式请百度或者翻阅TCP/IP协议卷(一)。

当响应者接收到请求者的ARP请求时,它会将请求包中的源MAC和源IP缓存到ARP缓存表中。当请求者接收到响应者的应答包时,它会将应答包中的源MAC地址和源IP地址缓存到ARP缓存表中。也就是说,一次arp请求,会让两端主机都缓存对方的IP和MAC地址。

使用ping命令或其他TCP连接时,两端都会缓存对方的ARP条目。但为了测试,可以手动使用arping命令发送一个自定义源MAC和源IP的arp请求让对方缓存自己的IP和MAC。

假如主机A上有eth0(192.168.100.54)和eth1两网卡,主机B有eth0(192.168.100.70)。下面的命令表示,在主机A上向主机B发送一个arp广播包(如果”-c
N”的N大于1,则只有第一个请求包是广播,其他是单播),其中源MAC为eth1网卡的MAC,但源IP为eth0上的IP地址192.168.100.54。这会使得主机B缓存的arp条目为192.168.100.54<-->eth1_MAC,但实际上这并非正确的映射关系。

arping -c 1 -I eth1 src 192.168.100.54 192.168.100.70

有些程序可以检测到IP地址冲突的现象。典型的如DHCP服务器准备提供IP地址给客户端之前,会发送一个arp广播,以便确认该IP地址是否已被其他主机使用(例如其他主机使用静态IP时手动输入了该IP)。如果没有收到回应,则表示该IP地址没有被使用,可以提供给客户端使用,如果收到了回应,则表示该IP地址已经被使用了,DHCP会从IP池中换一个IP提供给客户端。

arp -a命令可以显示arp缓存表的内容,arp -d ADDR可以删除ARP缓存表中某条ARP记录,这两命令对于Windows和Linux系统都可用。此外,对于Windows,arp -d *表示删除arp缓存表中的所有记录,对于Linux,则使用ip neigh flush all命令来删除arp缓存中所有记录。

注意,无论是arp请求还是arp应答,都带有完整的源MAC、源IP、目标MAC和目标IP。这看似一句废话,但不熟知arp请求的人很容易因此而陷入困惑。

2.ARP缓存表项都有一个老化时间,然而在linux系统中却没有给出具体如何来设置这个老化时间。那么到底怎么设置这个老化时间呢?

2.2 arp_announce

arp_announce - INTEGER
    Define different restriction levels for announcing the local
    source IP address from IP packets in ARP requests sent on
    interface:
    0 - (default) Use any local address, configured on any interface
    1 - Try to avoid local addresses that are not in the target's
    subnet for this interface. This mode is useful when target
    hosts reachable via this interface require the source IP
    address in ARP requests to be part of their logical network
    configured on the receiving interface. When we generate the
    request we will check all our subnets that include the
    target IP and will preserve the source address if it is from
    such subnet. If there is no such subnet we select source
    address according to the rules for level 2.
    2 - Always use the best local address for this target.
    In this mode we ignore the source address in the IP packet
    and try to select local address that we prefer for talks with
    the target host. Such local address is selected by looking
    for primary IP addresses on all our subnets on the outgoing
    interface that include the target IP address. If no suitable
    local address is found we select the first local address
    we have on the outgoing interface or on all other interfaces,
    with the hope we will receive reply for our request and
    even sometimes no matter the source IP address we announce.

    The max value from conf/{all,interface}/arp_announce is used.

    Increasing the restriction level gives more chance for
    receiving answer from the resolved target while decreasing
    the level announces more valid sender's information.

大致翻译一下:该变量接受一个整数值。它定义的是当发送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.100.22/24,这个IP地址是目标IP地址子网内的一个地址,因此会尽量使用该地址作为ARP请求中的源IP地址,但是源MAC地址还是数据流出接口上的MAC。
  • arp_announce=1时,不管ARP请求包中指定的源IP地址是什么(因为ARP请求包中的源IP和源MAC可以手动指定),总会在本地搜索出和目标IP最匹配的IP地址来作为源地址。它会优先选和目标IP同子网的本地IP,如果没有则选路由表中的第一个流出接口上的IP。

例如,如果Linux主机有3个网卡:eth0(IP0)、eth1(IP1)和eth2(IP2)。如果想通过eth2接口流出源地址为IP0的ARP请求广播包,默认情况下是行不通的。因为默认情况下,使用eth2流出ARP请求的源IP地址必须使用IP2。因此必须设置arp_announce=1或2,其实设置为1时也只是有机会流出,因为它要判断IP0和目标IP地址是否存在子网所属关系。只有设置arp_announce=2才必然能流出,但这时该Linux主机向外通告的IP地址将不是IP0,而是IP2。

发表评论

电子邮件地址不会被公开。 必填项已用*标注