Linux内核参数之arp_ignore和arp_announce

2,003 阅读7分钟

arp_ignore和arp_announce参数都和ARP协议相关,主要用于控制系统返回arp响应和发送arp请求时的动作。这两个参数很重要,特别是在LVS的DR场景下,它们的配置直接影响到DR转发是否正常。

一、arp_ignore 和 arp_announce 介绍

1. arp_ignore

arp_ignore的作用是控制系统在收到外部的arp请求时,是否要返回arp响应。
arp_ignore参数常用的取值主要有 0、1、2、3-8 较少用到:
0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。
1:只响应目的IP地址为接收网卡上的本地地址的arp请求。
2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。
3:如果ARP请求数据包所请求的IP地址对应的本地地址其作用域(scope)为主机(host),则不回应ARP响应数据包,如果作用域为全局(global)或链路(link),则回应ARP响应数据包。
4~7:保留未使用
8:不回应所有的arp请求

/etc/sysctl.conf 文件中包含 all 和 eth/lo(具体网卡)的 arp_ignore 参数,取其中较大的值生效。

2. arp_announce

arp_announce的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址。 arp_announce参数常用的取值有0,1,2。
0:允许使用任意网卡上的IP地址作为arp请求的源IP,通常就是使用数据包a的源IP。
1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。
2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。

sysctl.conf中包含all和eth/lo(具体网卡)的arp_ignore参数,取其中较大的值生效。

二、arp_ignore和arp_announce参数示例

1. arp_ignore

若 arp_ignore = 0,eth1网卡上收到目的IP为环回网卡IP的arp请求,但是eth1也会返回arp响应,把自己的mac地址告诉对端。 image.png




若 arp_ignore = 1,eth1网卡上收到目的IP为环回网卡IP的arp请求,发现请求的IP不是自己网卡上的IP,不会回arp响应。 image.png

2. arp_announce

若 arp_announce = 0,系统要发送的IP包源地址为eth1的地址,IP包目的地址根据路由表查询判断需要从eth2网卡发出,这时会先从eth2网卡发起一个arp请求,用于获取目的IP地址的MAC地址。该arp请求的源MAC自然是eth2网卡的MAC地址,但是源IP地址会选择eth1网卡的地址。

image.png




若 arp_announce = 2,eth2网卡发起arp请求时,源IP地址会选择eth2网卡自身的IP地址。 image.png

三、arp_ignore 和 arp_announce 参数在LVS DR 模式下的作用

1. arp_ignore

因为DR模式下,每个真实服务器节点都要在环回网卡上绑定虚拟服务IP。这时候,如果客户端对于虚拟服务IP的arp请求广播到了各个真实服务器节点,如果arp_ignore参数配置为0,则各个真实服务器节点都会响应该arp请求,此时客户端就无法正确获取LVS节点上正确的虚拟服务IP所在网卡的MAC地址。假如某个真实服务器节点A的网卡eth1响应了该arp请求,客户端把A节点的eth1网卡的MAC地址误认为是LVS节点的虚拟服务IP所在网卡的MAC,从而将业务请求消息直接发到了A节点的eth1网卡。这时候虽然因为A节点在环回网卡上也绑定了虚拟服务IP,所以A节点也能正常处理请求,业务暂时不会受到影响。但时此时由于客户端请求没有发到LVS的虚拟服务IP上,所以LVS的负载均衡能力没有生效。造成的后果就是,A节点一直在单节点运行,业务量过大时可能会出现性能瓶颈。

所以DR模式下要求arp_ignore参数要求配置为1。

2. arp_announce

每个机器或者交换机中都有一张arp表,该表用于存储对端通信节点IP地址和MAC地址的对应关系。当收到一个未知IP地址的arp请求,就会再本机的arp表中新增对端的IP和MAC记录;当收到一个已知IP地址(arp表中已有记录的地址)的arp请求,则会根据arp请求中的源MAC刷新自己的arp表。

如果arp_announce参数配置为0,则网卡在发送arp请求时,可能选择的源IP地址并不是该网卡自身的IP地址,这时候收到该arp请求的其他节点或者交换机上的arp表中记录的该网卡IP和MAC的对应关系就不正确,可能会引发一些未知的网络问题,存在安全隐患。

例如: HOST上有多个网卡,却在不同一网段,例如 eth0:net0    eth1:net1    eth2:net2 ..... ,这时 如果 net0 网段的主机 发起ARP请求,那么HOST 会把 eth0,eth1,eth2... 这些在HOST的网卡设备的 IP 与MAC 都发给 net0 里的请求端,但是 请求端 拿到了3个 设备的IP与MAC (eth0:IP MAC , eth1:IP MAC  eth2 : IP MAC)  以为这3个 IP 都能通信,而实际上 ,只有net0 内的eth0 网卡给他的IP和MAC 才能通信 , 而 eth1,eth2 给的IP与MAC 对于 请求端来说 是没有意义。

所以DR模式下要求arp_announce参数要求配置为2。

四、arp_ignore 和 arp_announce参数的配置方法

arp_ignore和arp_announce参数分别有all,default,lo,eth1,eth2...等对应不同网卡的具体参数。当all和具体网卡的参数值不一致时,取较大值生效。

一般只需修改all和某个具体网卡的参数即可(取决于你需要修改哪个网卡)。下面以修改lo网卡为例:

方式1. 修改/etc/sysctl.conf文件,然后sysctl -p刷新到内存。

net.ipv4.conf.all.arp_ignore=1

net.ipv4.conf.lo.arp_ignore=1

net.ipv4.conf.all.arp_announce=2

net.ipv4.conf.lo.arp_announce=2

方式2. 使用sysctl -w直接写入内存:

sysctl -w net.ipv4.conf.all.arp_ignore=1

sysctl -w net.ipv4.conf.lo.arp_ignore=1

sysctl -w net.ipv4.conf.all.arp_announce=2

sysctl -w net.ipv4.conf.lo.arp_announce=2

方式3. 修改/proc文件系统:

echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore

echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/all/arp_announce

echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce

五、常用脚本

/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up

VIP(虚拟IP):跟物理网卡是绑定的,它实际上就是绑定在物理网卡上的别名,如lo:x ,x为0-255的任意数字,你可以在一块网卡上绑定多个别名。这个VIP可以看作是你上网的QQ网名、昵称、外号等。
lo:0 表示这个VIP绑定的目标网卡设备
10.122.130.125 就是VIP的值
广播地址为10.122.130.125
子网掩码为:255.255.255.255
up表示立即启用这个VIP

#!/bin/bash
 
VIP=10.122.130.125
 
case "$1" in
    start)
 
    echo "Start REAL Server"
    /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
    echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
    echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
    echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
 
    ;;
 
    stop)
 
    /sbin/ifconfig lo:0 down
    echo "Stop REAL Server"
    echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
    echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
    echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
    echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
 
    ;;
 
    restart)
 
    $0 stop
    $0 start
 
    ;;
 
    *)

image.png

六、 DR模式工作原理:

image.png

Client发送请求 -->prerouting --> INPUT— DS(调度器) --> -->postrouting
–>RS(真正的服务器)–>lo回环接口 --> 网卡eth0 -->Client 

整个过程的数据流向如下:
用户(client)发送请求给调度器(DS),DS调度器先把请求发往prerouting链(内核空间kernal space),确定请求的是不是VIP 
到了INPUT链之后,如果请求的是集群服务,会在这里修改MAC地址,把源MAC地址改为DS的MAC地址,把目的MAC地址改为RS的MAC地址,此时IP仍然不变
处理完成后把请求发往postrouting链,检测请求的是否为RS(会检测请求的MAC地址),如果是,接受请求,把请求通过回环接口发给出口的网卡,再发回给客户端

数据在系统内的交流用的是回环接口,与外部的交流用的是网卡eth0

DR模式高效的原因就是RS服务器会直接响应客户端的请求,发送的请求一直往前发送数据包,不会再返回数据包给调度器

注意:这里的prerouting,input,postrouting都是iptables防火墙里面的链,

参考

Linux内核参数之arp_ignore和arp_announce
LVS 之 DR model arp_announce arp_ignore
LVS DR 模式后端RS lo网卡必须绑定VIP
LVS/DR模式(直接路由模式)(ipvsadm+ipvs)