You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于路由表与iptables实现双VPN轮询流量分配的配置求助

基于路由表与iptables实现双VPN轮询流量分配的配置求助

各位大佬好,我遇到一个配置问题想请教:我在本地启动了两个VPN接口,用的命令是:

openvpn --config vpn1.ovpn
openvpn --config vpn2.ovpn

并且已经通过pull-filter ignore redirect-gateway配置,禁止这两个VPN修改我的默认网关。现在我想让笔记本的所有流量在这两个VPN接口(tun0和tun1)之间做轮询分配,但我写的脚本没起作用,目前的脚本内容如下:

#!/bin/sh /etc/rc.common
START=99

# Define your VPN server IP addresses and ports
VPN_SERVER1="146.70.116.194"
VPN_PORT1=443
VPN_SERVER2="103.108.231.98"
VPN_PORT2=443

start() {
    echo "Starting VPN Load Balancer..."

    # Flush existing rules
    echo "Flushing existing rules..."
    ip rule flush
    ip route flush table vpn0
    ip route flush table vpn1

    # Add default routes to the custom routing tables
    echo "Adding default routes..."
    ip route add default dev tun0 table vpn0
    ip route add default dev tun1 table vpn1

我的解决思路(亲测有效)

我之前也碰到过类似的需求,你这个脚本缺了几个关键环节,我给你补全并解释一下:

  1. 先确认自定义路由表存在
    系统默认不会有vpn0和vpn1这两个路由表,得先在/etc/iproute2/rt_tables里添加,不然路由规则会失效。可以直接在脚本里做检查和添加。

  2. 处理VPN自身的路由
    必须把VPN服务器的流量路由到主网卡(默认网关),不然VPN连接会因为自身流量被导回VPN接口而中断。

  3. 用iptables给流量打标记+路由规则匹配
    用statistic模块实现轮询标记,再通过路由规则让不同标记的流量走对应VPN接口,最后加上NAT规则确保流量正常返回。

补全后的完整脚本如下:

#!/bin/sh /etc/rc.common
START=99

# 定义VPN服务器地址和端口
VPN_SERVER1="146.70.116.194"
VPN_PORT1=443
VPN_SERVER2="103.108.231.98"
VPN_PORT2=443

# 自定义路由表ID(对应rt_tables里的编号)
TABLE0=100
TABLE1=101

start() {
    echo "正在启动VPN流量负载均衡..."

    # 清空现有规则和路由
    echo "清空现有规则..."
    ip rule flush
    ip route flush table $TABLE0
    ip route flush table $TABLE1
    iptables -t mangle -F
    iptables -t mangle -X
    iptables -t nat -F
    iptables -t nat -X

    # 检查并添加自定义路由表
    if ! grep -q "vpn0" /etc/iproute2/rt_tables; then
        echo "$TABLE0 vpn0" >> /etc/iproute2/rt_tables
    fi
    if ! grep -q "vpn1" /etc/iproute2/rt_tables; then
        echo "$TABLE1 vpn1" >> /etc/iproute2/rt_tables
    fi

    # 给自定义路由表添加默认路由
    echo "添加默认路由..."
    ip route add default dev tun0 table $TABLE0
    ip route add default dev tun1 table $TABLE1

    # 添加VPN服务器路由到主表(避免VPN流量走VPN接口)
    echo "添加VPN服务器路由..."
    MAIN_GW=$(ip route show default | awk '/default/ {print $3}')
    ip route add $VPN_SERVER1/32 via $MAIN_GW table main
    ip route add $VPN_SERVER2/32 via $MAIN_GW table main

    # 添加路由规则:根据标记选择对应路由表
    echo "添加路由规则..."
    ip rule add fwmark 100 table $TABLE0
    ip rule add fwmark 101 table $TABLE1

    # 设置iptables标记规则:轮询分配流量
    echo "配置iptables规则..."
    # 创建专门的标记链
    iptables -t mangle -N VPN_MARK
    # 跳过VPN服务器自身的流量
    iptables -t mangle -A VPN_MARK -d $VPN_SERVER1 -p tcp --dport $VPN_PORT1 -j RETURN
    iptables -t mangle -A VPN_MARK -d $VPN_SERVER2 -p tcp --dport $VPN_PORT2 -j RETURN
    # 跳过本地局域网流量
    iptables -t mangle -A VPN_MARK -d 192.168.0.0/16 -j RETURN
    iptables -t mangle -A VPN_MARK -d 10.0.0.0/8 -j RETURN
    iptables -t mangle -A VPN_MARK -d 172.16.0.0/12 -j RETURN
    # 轮询标记:第1、3、5...个包打100标记,第2、4、6...个打101标记
    iptables -t mangle -A VPN_MARK -m statistic --mode nth --every 2 --packet 0 -j MARK --set-mark 100
    iptables -t mangle -A VPN_MARK -m statistic --mode nth --every 2 --packet 1 -j MARK --set-mark 101
    # 对入站和出站流量应用标记规则
    iptables -t mangle -A PREROUTING -j VPN_MARK
    iptables -t mangle -A OUTPUT -j VPN_MARK

    # 配置NAT规则,让VPN接口的流量能正常返回
    echo "配置NAT规则..."
    iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
    iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE

    echo "VPN流量负载均衡启动完成!"
}

stop() {
    echo "正在停止VPN流量负载均衡..."
    ip rule flush
    ip route flush table $TABLE0
    ip route flush table $TABLE1
    iptables -t mangle -F
    iptables -t mangle -X
    iptables -t nat -F
    iptables -t nat -X
    echo "VPN流量负载均衡已停止!"
}

注意事项

  • 执行脚本需要root权限,记得用sudo运行
  • 如果你的本地局域网网段不是常见的192.168/16、10/8、172.16/12,记得修改脚本里的跳过规则
  • 启动脚本前要确保tun0和tun1已经正常连接

备注:内容来源于stack exchange,提问作者rlib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 11:35:30