一、应用场景

vyos系统有俩个WAN接口,针对WAN1和WAN2的网关做了failover,并在WAN1和WAN2接口上配置NAT,默认路由默认走WAN1,当WAN1接口down走WAN2。

二、场景问题

vyos系统的NAT存在问题,当WAN1接口down后,默认路由走WAN2出去,此时NAT在WAN2口生效,但是当WAN1口up后,failover重新生效,默认路由切回WAN1口,此时NAT没有切回WAN1,而是走了WAN2,导致用户不能上网。

三、解决方案

通过底层配置本脚本,抓去WAN1口物理状态,刷新conntrack,当WAN1口up后,failover重新生效,脚本运行重置conntrack,当WAN1口down后,脚本运行conntrack。

四、 创建脚本

4.1、进入root模式

root -i

4.2、创建脚本文件路径

mkdir path
cd path
mkdir to 
cd to

4.3、创建脚本文件

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、创建循环脚本文件

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

五、创建脚本系统服务

5.1、创建monitor_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.1、启动服务

sudo systemctl start monitor_eth1_status.service

5.2.2、停止服务

sudo systemctl stop monitor_eth1_status.service

5.2.3、重启服务

sudo systemctl restart monitor_eth1_status.service

5.2.4、查看服务状态

sudo systemctl status monitor_eth1_status.service

5.2.5、设置开机自启动

sudo systemctl enable monitor_eth1_status.service

六、测试脚本

6.1、测试前conntrack状态

 show conntrack table ipv4

Snipaste_2023-11-24_16-17-11

6.2、测试前服务状态

sudo systemctl status monitor_eth1_status.service

Snipaste_2023-11-24_16-20-31

6.3、手动关闭eth1口测试

set interfaces ethernet eth1 disable
commit

Snipaste_2023-11-24_16-22-17

6.4、查看conntrack变化

show conntrack table ipv4

Snipaste_2023-11-24_16-23-38

6.5、查看服务状态变化

sudo systemctl status monitor_eth1_status.service

Snipaste_2023-11-24_16-24-47

6.6、手动开启eth1口测试

delete interfaces ethernet eth1 disable
commit

Snipaste_2023-11-24_16-26-10

6.7、查看conntrack变化

show conntrack table ipv4

Snipaste_2023-11-24_16-27-28

6.8、查看服务状态变化

sudo systemctl status monitor_eth1_status.service

Snipaste_2023-11-24_16-28-41