基于路由表与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
我的解决思路(亲测有效)
我之前也碰到过类似的需求,你这个脚本缺了几个关键环节,我给你补全并解释一下:
先确认自定义路由表存在
系统默认不会有vpn0和vpn1这两个路由表,得先在/etc/iproute2/rt_tables里添加,不然路由规则会失效。可以直接在脚本里做检查和添加。处理VPN自身的路由
必须把VPN服务器的流量路由到主网卡(默认网关),不然VPN连接会因为自身流量被导回VPN接口而中断。用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
相关产品推荐
相关产品推荐

