双OpenVPN连接场景下,仅当其中一个连接断开时端口转发的外部访问才生效
兄弟,我太懂你踩的这个坑了!之前帮朋友排查过几乎一模一样的双OpenVPN路由冲突问题,咱们先把根儿上的原因掰明白,再一步步给你解决。
问题到底出在哪?
当你把192.168.178.8这台机器的默认路由改成通过tun0走第三方VPN后,所有从这台机器出去的流量(包括你那台监听1194端口的OpenVPN服务的响应包)都会默认从tun0接口发出去。
而外网用户的请求是通过你的DSL路由器(192.168.178.1)转发到192.168.178.8的,这时候响应包走tun0出去,就会出现「路由不对称」——请求从eth0进来,响应从tun0出去,外网用户根本收不到这个响应,所以看起来1194端口就是不通的。只有当你断开第三方VPN,默认路由切回eth0,响应包才能正常回到DSL路由器,外网才能访问。
一步步解决这个问题
咱们用策略路由来搞定,简单说就是给监听1194端口的OpenVPN服务的响应流量单独开一条「绿色通道」,让它必须走eth0回到DSL路由器。
1. 先确认当前的路由状态
先连好第三方VPN,在192.168.178.8上执行这条命令看看路由表:
ip route show
你会看到类似这样的条目:
default via <tun0的网关IP> dev tun0(这是第三方VPN自动加上的默认路由,坑就在这)192.168.178.0/24 dev eth0 proto kernel scope link src 192.168.178.8(你的内网网段路由)<第三方VPN的公网IP> via 192.168.178.1 dev eth0(这条是对的,保证你能连到VPN服务器)
2. 创建一个自定义路由表
首先咱们得整个专属的路由表,用来存「走eth0回DSL路由器」的规则。编辑/etc/iproute2/rt_tables文件:
sudo nano /etc/iproute2/rt_tables
在文件最后加这么一行(编号100是随便选的,只要不跟现有表重复就行,名字也可以自己改):
100 vpn_backhaul
保存退出即可(nano里按Ctrl+O,回车,再Ctrl+X)。
3. 给自定义路由表加规则
现在咱们要告诉系统:凡是从192.168.178.8发出去、对应1194端口的流量,必须走这个自定义路由表回DSL路由器。
先给自定义表加默认网关:
sudo ip route add default via 192.168.178.1 dev eth0 table vpn_backhaul
再添加规则匹配目标流量:
sudo ip rule add from 192.168.178.8 sport 1194 table vpn_backhaul
另外,为了防止你连第三方VPN的时候出现循环路由,最好把连接VPN服务器的流量锁死在eth0上,执行这条:
sudo ip route add xx.xxx.xxx.xxx via 192.168.178.1 dev eth0
(把xx.xxx.xxx.xxx换成你第三方VPN提供商的实际IP)
4. 让规则重启VPN后自动生效
总不能每次连VPN都手动敲一遍命令吧?咱们把这些规则写到OpenVPN的启动脚本里:
- 打开你那台连第三方VPN的
.ovpn配置文件,在末尾加两行:
up /etc/openvpn/up_custom_routes.sh down /etc/openvpn/down_custom_routes.sh
- 创建启动脚本
/etc/openvpn/up_custom_routes.sh,内容如下:
#!/bin/bash ip route add default via 192.168.178.1 dev eth0 table vpn_backhaul ip rule add from 192.168.178.8 sport 1194 table vpn_backhaul ip route add xx.xxx.xxx.xxx via 192.168.178.1 dev eth0
- 创建停止脚本
/etc/openvpn/down_custom_routes.sh,用来断开VPN时清理规则:
#!/bin/bash ip rule del from 192.168.178.8 sport 1194 table vpn_backhaul ip route del default via 192.168.178.1 dev eth0 table vpn_backhaul ip route del xx.xxx.xxx.xxx via 192.168.178.1 dev eth0
- 给这两个脚本加执行权限:
sudo chmod +x /etc/openvpn/up_custom_routes.sh /etc/openvpn/down_custom_routes.sh
5. 测试效果
现在重新连第三方VPN,然后从外网用手机流量或者朋友的网络,测试访问你的DSL路由器公网IP的1194端口,应该就能正常连接到你家里的OpenVPN服务了——再也不用断开第三方VPN才能远程回家啦!
备注:内容来源于stack exchange,提问作者Ricky883249

