一、应用场景 {#%E4%B8%80%E3%80%81%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF}
vyos系统有俩个WAN接口,针对WAN1和WAN2的网关做了failover,并在WAN1和WAN2接口上配置NAT,默认路由默认走WAN1,当WAN1接口down走WAN2。
二、场景问题 {#%E4%BA%8C%E3%80%81%E5%9C%BA%E6%99%AF%E9%97%AE%E9%A2%98}
vyos系统的NAT存在问题,当WAN1接口down后,默认路由走WAN2出去,此时NAT在WAN2口生效,但是当WAN1口up后,failover重新生效,默认路由切回WAN1口,此时NAT没有切回WAN1,而是走了WAN2,导致用户不能上网。
三、解决方案 {#%E4%B8%89%E3%80%81%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88}
通过底层配置本脚本,抓去WAN1口物理状态,刷新conntrack,当WAN1口up后,failover重新生效,脚本运行重置conntrack,当WAN1口down后,脚本运行conntrack。
四、 创建脚本 {#%E5%9B%9B%E3%80%81-%E5%88%9B%E5%BB%BA%E8%84%9A%E6%9C%AC}
4.1、进入root模式 {#4.1%E3%80%81%E8%BF%9B%E5%85%A5root%E6%A8%A1%E5%BC%8F}
root -i
4.2、创建脚本文件路径 {#4.2%E3%80%81%E5%88%9B%E5%BB%BA%E8%84%9A%E6%9C%AC%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84}
mkdir path
cd path
mkdir to
cd to
4.3、创建脚本文件 {#4.3%E3%80%81%E5%88%9B%E5%BB%BA%E8%84%9A%E6%9C%AC%E6%96%87%E4%BB%B6}
touch monitor_interface.sh #创建
chmod +x monitor_interface.sh #赋权
nano monitor_interface.sh #编辑
#!/bin/bash
interface="eth1"
state_file="/tmp/eth1_state"
如果状态文件不存在,则创建一个空文件
==================
touch "$state_file"
获取当前状态
======
get_interface_state() {
ip link show "$interface" \| awk '/state/ {print $9}'
}
读取之前的状态
=======
last_state=$(cat "$state_file" 2\>/dev/null)
获取当前物理接口状态
==========
current_state=$(get_interface_state)
如果当前状态与之前状态不同
=============
`if [ "$current_state" != "$last_state" ]; then
# 执行 conntrack -F 并更新状态
conntrack -F
echo "$current_state" > "$state_file"
fi
`
4.4、创建循环脚本文件 {#4.4%E3%80%81%E5%88%9B%E5%BB%BA%E5%BE%AA%E7%8E%AF%E8%84%9A%E6%9C%AC%E6%96%87%E4%BB%B6}
touch monitor_eth1_status.sh #创建
chmod +x monitor_eth1_status.sh #赋权
nano monitor_eth1_status.sh #编辑
#!/bin/bash
while true; do
/path/to/monitor_interface.sh # 运行脚本
# 等待接口状态变化
interface="eth1"
state_file="/tmp/eth1_state"
# 获取当前状态
get_interface_state() {
ip link show "$interface" | awk '/state/ {print $9}'
}
# 读取之前的状态
last_state=$(cat "$state_file" 2>/dev/null)
# 获取当前接口状态
current_state=$(get_interface_state)
# 如果当前状态与之前状态相同,则等待接口状态变化
while [ "$current_state" = "$last_state" ]; do
sleep 1 # 每1秒检查一次接口状态
current_state=$(get_interface_state)
done
`done
`
五、创建脚本系统服务 {#%E4%BA%94%E3%80%81%E5%88%9B%E5%BB%BA%E8%84%9A%E6%9C%AC%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1}
5.1、创建monitor_eth1_status.service {#5.1%E3%80%81%E5%88%9B%E5%BB%BAmonitor_eth1_status.service}
touch /etc/systemd/system/monitor_eth1_status.service #创建
chmod +x /etc/systemd/system/monitor_eth1_status.service #赋权
nano /etc/systemd/system/monitor_eth1_status.service #编辑
#备注脚本
[Unit]
Description=Monitor eth1 interface status changes
#备注脚本运行位置,始终重新启动
\[Service\]
ExecStart=/bin/bash /path/to/monitor_eth1_status.sh
Restart=always
`#有sudo权限的user可以执行
[Install]
WantedBy=multi-user.target
`
5.2、systemctl命令 {#5.2%E3%80%81systemctl%E5%91%BD%E4%BB%A4}
5.2.1、启动服务 {#5.2.1%E3%80%81%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1}
sudo systemctl start monitor_eth1_status.service
5.2.2、停止服务 {#5.2.2%E3%80%81%E5%81%9C%E6%AD%A2%E6%9C%8D%E5%8A%A1}
sudo systemctl stop monitor_eth1_status.service
5.2.3、重启服务 {#5.2.3%E3%80%81%E9%87%8D%E5%90%AF%E6%9C%8D%E5%8A%A1}
sudo systemctl restart monitor_eth1_status.service
5.2.4、查看服务状态 {#5.2.4%E3%80%81%E6%9F%A5%E7%9C%8B%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81}
sudo systemctl status monitor_eth1_status.service
5.2.5、设置开机自启动 {#5.2.5%E3%80%81%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E5%8A%A8}
sudo systemctl enable monitor_eth1_status.service
六、测试脚本 {#%E5%85%AD%E3%80%81%E6%B5%8B%E8%AF%95%E8%84%9A%E6%9C%AC}
6.1、测试前conntrack状态 {#6.1%E3%80%81%E6%B5%8B%E8%AF%95%E5%89%8Dconntrack%E7%8A%B6%E6%80%81}
show conntrack table ipv4
6.2、测试前服务状态 {#6.2%E3%80%81%E6%B5%8B%E8%AF%95%E5%89%8D%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81}
sudo systemctl status monitor_eth1_status.service
6.3、手动关闭eth1口测试 {#6.3%E3%80%81%E6%89%8B%E5%8A%A8%E5%85%B3%E9%97%ADeth1%E5%8F%A3%E6%B5%8B%E8%AF%95}
set interfaces ethernet eth1 disable
commit
6.4、查看conntrack变化 {#6.4%E3%80%81%E6%9F%A5%E7%9C%8Bconntrack%E5%8F%98%E5%8C%96}
show conntrack table ipv4
6.5、查看服务状态变化 {#6.5%E3%80%81%E6%9F%A5%E7%9C%8B%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96}
sudo systemctl status monitor_eth1_status.service
6.6、手动开启eth1口测试 {#6.6%E3%80%81%E6%89%8B%E5%8A%A8%E5%BC%80%E5%90%AFeth1%E5%8F%A3%E6%B5%8B%E8%AF%95}
delete interfaces ethernet eth1 disable
commit
6.7、查看conntrack变化 {#6.7%E3%80%81%E6%9F%A5%E7%9C%8Bconntrack%E5%8F%98%E5%8C%96}
show conntrack table ipv4
6.8、查看服务状态变化 {#6.8%E3%80%81%E6%9F%A5%E7%9C%8B%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96}
sudo systemctl status monitor_eth1_status.service