网关服务器的主要作用有二:1、路由 2、nat。考虑到网关是公司的核心服务,决定使用keepalived实现网关的双机热备。
使用keepalived实现只监控主机的存活非常简单,而且在本次需求中并不需要监控服务。然后看似双机做成了,但是问题来了。
网关上跑的全是iptables脚本,而且主要是状态跟踪和snat,最突出的一个问题是,keepalived发出的vrrp广播的源地址有时被转换成了外网地址,而且这个还不决定什么时候转换成外网地址。
配置文件如下:
[root@gw-175 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
}
notification_email_from [email protected]
smtp_server xxxxxxxx
smtp_connect_timeout 30
router_id gw_ha_175
}
#vrrp_sync_group VG1 {
# group {
# VI_1
# }
#}
vrrp_script check_run {
script "/data/sbin/checkgw.sh"
weight -5
interval 5
}
vrrp_instance VI_1 {
state BACKUP
# nopreempt
interface eth0
virtual_router_id 150
priority 150
advert_int 1
track_script {
check_run
}
track_interface {
eth0
}
authentication {
auth_type PASS
auth_pass 12345678
}
notify_master "/data/sbin/master.sh"
notify_backup "/data/sbin/backup.sh"
# notify_fault "/data/sbin/backup.sh"
# smtp_alert
mcast_src_ip eth0 192.168.8.175
virtual_ipaddress {
192.168.8.254/24 dev eth0
192.168.9.254/24 dev eth0
192.168.7.254/24 dev eth0
192.168.6.254/24 dev eth0
192.168.5.254/24 dev eth0
192.168.4.254/24 dev eth0
192.168.2.254/24 dev eth0
192.168.1.254/24 dev eth0
192.168.10.254/24 dev eth0
192.168.100.254/24 dev eth0
192.168.16.254/24 dev eth0
192.168.33.254/24 dev eth0
192.168.38.254/24 dev eth0
192.168.39.254/24 dev eth0
}
}
另外一台机器配置文件除了mcast_src_ip eth0 192.168.8.175和上面的不一样外,其余都一样。
我使用tcpdump抓到的包应该是这样,
[root@gw-174 ~]# tcpdump vrrp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
09:34:28.681948 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
09:34:29.682389 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
但实际情况确是,
[root@gw-174 ~]# tcpdump vrrp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
09:34:28.681948 IP 1.1.1.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
09:34:29.682389 IP 1.1.1.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
在进行了各种研究,发现是状态跟踪导致的,
[root@gw-175 ~]# grep src=192.168.8.175 /proc/net/ip_conntrack
unknown 112 599 src=192.168.8.175 dst=224.0.0.18 packets=11662 bytes=1072904 [UNREPLIED] src=1.1.1.1 dst=224.0.0.18 packets=0 bytes=0 mark=0 secmark=0 use=2
iptables会对每一个连接进行连接跟踪,除非这个连接断开或者/proc/net/ip_conntrack表中的记录超时才回重新跟踪。而vrrp广播是不停的发,所以连接不会断开,表中记录也不会超时,一直会匹配这个错误的记录。(至于这条记录是如何产生的,应该刚开始运行的时候iptables的nat表中还没添加相应的vrrp规则)
对于这种情况,尝试删除这个表中条目,失败!!!停止keepalived,等待表中条目超时,不可能!(停止后vip就会消失,就会断网)
在研究后决定对vrrp广播包就行取消状态跟踪,在filter表中添加UNTRACKED状态,
iptables -I FORWARD -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
在raw中,添加如下:
iptables -t raw -A OUTPUT -s 192.168.8.175 -d 224.0.0.0/8 -j NOTRACK
抓到的变为包如下:
[root@gw-174 ~]# tcpdump vrrp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
09:34:28.681948 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
09:34:29.682389 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
等待表中条目超时后,在nat中添加对应vrrp的规则即可!
参考连接http://linuxnet527.blog.163.com/blog/static/172982867201151395821550/
http://wangcong.org/articles/learning-iptables.cn.html