LVS-DR的ARP污染问题
LVS-DR模式很简单,但是LVS的DR模式下会出现一个arp污染的问题,这正是由于DR模式下,RS携带自己的MAC和VIP作为封装,直接经过网关然后给到客户端,然而我们的VIP是在服务器上面和LVS上面都有配置,其中LVS的VIP不做arp抑制,而服务器上面的VIP做了arp抑制。目的是为了让我们的网关在发送arp广播找VIP的mac时,仅有LVS回应,让网关将流量给到LVS。
但是问题就出在这里,网关会为了下一次的传输,对VIP的MAC进行加表,MAC是LVS的,但是RS服务器回的包是通过二层给到网关,那么网关的VIP对应的MAC就会被刷新。以至于让网关误以为VIP对应的mac为RS的。那么下次的流量就不会再走LVS,直到arp表更新。
下面这个实验就很好的说明了问题:
实验
四台主机:router:网关,两块网卡:ens160:192.168.118.150,ens224:192.168.40.50 lvs服务器(仅主机模式):ens160:192.168.40.151 web1/2: 192.168.40.100/200
要求是外网通过访问192.168.118.150能够负载均衡,上面的AR2作为LVS,并且提供LVS-DR服务,AR1作为网关。
配置
RS服务器
web1/2服务器同时配置
#web1/2
dnf install nginx -y
firewall-cmd --permanent --add-port 80/tcp#也可以关闭防火墙systemctl stop firewalld
firewall-cmd --reload
setenforce 0
#web2就改为192.168.40.200/24
nmcli con mod ens160 ipv4.method manual ipv4.address 192.168.40.100/24 ipv4.gateway 192.168.40.50 connection.autoconnect yes
echo "Test page which from ip:$(hostname -I)" > /usr/share/nginx/html/index.html
systemctl enable --now nginx
添加虚拟网卡,配置VIP然后做arp抑制
#web1/2同时配置
nmcli con add type dummy ifname lvstest ipv4.address 192.168.40.150/24 ipv4.method manual connection.autoconnection yes
nmcli con up dummy-lvstest
echo '1' > /proc/sys/net/ipv4/conf/lvstest/arp_ignoresysctl -p
echo '1' > /proc/sys/net/ipv4/conf/lvsTest/arp_ignore
作用:让接口
lvsTest
忽略 ARP 请求,除非 ARP 请求的目标 IP 就是本机接口的 IP。取值 1 的含义:
0
(默认):对所有 ARP 请求都响应(可能导致冲突)。1
:只响应目标 IP 是本机接口的 ARP 请求(其他 VIP 的 ARP 请求不响应)。
配置lvs
systemctl stop firewalld
#添加VIP
nmcli con add type dummy ifname lvstest ipv4.address 192.168.40.150/24 ipv4.method manual connection.autoconnect yes
nmcli con up dummy-lvstest
#配置原有的仅主机网卡
nmcli con mod ens160 ipv4.method manual ipv4.address 192.168.40.151/24 ipv4.gateway 192.168.40.50 connection.autoconnect yes
nmcli con up ens160
dnf install ipvsadm -y
firewall-cmd --add-port 80/tcp --permanent
ipvsadm -A -t -A -t 192.168.40.150:80 -s rr
ipvsadm -a -t 192.168.40.150:80 -r 192.168.40.100:80 -g
ipvsadm -a -t 192.168.40.150:80 -r 192.168.40.200:80 -g
我们这里直接就配置router,先看看arp污染的效果
Router网关
这里需要写两条iptables,一条将进来的流量打到lvs上,一条用于内部出去。其次自己需要添加两块网卡,一块用于内部之间通信,所以内部用仅主机模式,外部用nat模式
#配置内部IP作为网关
nmcli dev con ens224
nmcli con mod ens224 ipv4.method manual ipv4.address 192.168.40.50/24 connection.autoconnect yes
nmcli con up ens224
#systemctl stop firewalld
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.conf
sysctl -p
配置iptables
#进行DNAT将流量给到VIP
iptables -t nat -A PREROUTING \-d 192.168.118.150 \ # 1. 报文的目的 IP 必须是 118.150-p tcp \ # 2. 协议必须是 TCP--dport 80 \ # 3. 目的端口必须是 80-j DNAT \ # 4. 动作:做目的地址转换(DNAT)--to-destination 192.168.40.150 # 5. 把目的 IP 改成 40.150
#进行一个SNAT,让流量出去
iptables -t nat -A POSTROUTING \-s 192.168.40.0/24 \ # 源网段-j SNAT --to-source 192.168.118.150
[root@router ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 192.168.118.150 tcp dpt:80 to:192.168.40.150
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT tcp -- 192.168.40.150 0.0.0.0/0 tcp spt:80 to:192.168.118.150
以上大致就配置完成了,我们测试一下效果,看看是否进行了arp污染
测试
我们先在router网关服务器上面直接curl内网的VIP
[root@router ~]# curl 192.168.40.150
Test page which from 192.168.40.100
[root@router ~]# curl 192.168.40.150
Test page which from 192.168.40.100
[root@router ~]# curl 192.168.40.150
Test page which from 192.168.40.100
[root@router ~]# curl 192.168.40.150
Test page which from 192.168.40.100
我们发现根本不会走lvs,但是我们明明做了arp抑制,我们直接查询arp表
[root@router ~]# ip neigh show | grep 192.168.40.150
192.168.40.150 dev ens224 lladdr 00:0c:29:33:be:12 STALE
在去到100这个服务器上面查本地mac
[root@localhost ~]# ip link show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:33:be:12 brd ff:ff:ff:ff:ff:ff
发现一模一样,也就是直接给到了服务器没有走lvs
解决问题
很简单,只要将mac地址永久性设置成为LVS上面的物理接口的mac就可以了,也可以加上一句arp_announce,这两个方法常用
方法一:
这种是直接在RS上面将arp给在对应网卡进行抑制了
echo '2' > /proc/sys/net/ipv4/conf/lvstest/arp_announce
sysctl -p
方法二:
[root@lvs ~]# ip link show dev ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000link/ether 00:0c:29:df:dd:5c brd ff:ff:ff:ff:ff:ff #mac为00:0c:29:df:dd:5caltname enp3s0
dummy 接口本质上是一个纯软件回环设备:
没有对应的物理网卡,也不会把帧发到外部交换芯片;
所以 dummy 接口收不到也发不出任何二层广播(包括 ARP);
只有 真正挂在链路/交换机上的物理接口 才能与网关交互 ARP。
因此,当网关(router)想确定 192.168.40.150 的 MAC 时,它只能向 同一二层域里的物理接口 发送 ARP 请求,得到的必须是 LVS 物理网卡的 MAC; dummy 接口的 MAC 对网关来说永远不可见,也无法用来转发流量。
router上面配置lvs的mac
#先删除原有的
[root@router ~]# ip neigh del 192.168.40.150 dev ens224
[root@router ~]# ip neigh add 192.168.40.150 lladdr 00:0c:29:df:dd:5c dev ens224 nud permanent
[root@router ~]# ip neigh show | grep 192.168.40.150
192.168.40.150 dev ens224 lladdr 46:32:3a:c4:2c:a7 PERMANENT
测试
[root@router ~]# for ((i=1;i<=5;i++))do curl 192.168.40.150;done
Test page which from 192.168.40.200
Test page which from 192.168.40.100
Test page which from 192.168.40.200
Test page which from 192.168.40.100
Test page which from 192.168.40.200