我运行了多个 VPN 连接,它们会给我不同的外部 IP 地址。但这些 VPN 服务器通常会给我相同的本地 IP 地址。
因此我最终得到以下配置:
eth0 [main ip address]
tun0 10.200.1.31
tun1 10.200.1.32
tun2 10.200.1.31
eth0
我的主网络适配器在哪里以及tunX
OpenVPN 创建的虚拟网络接口在哪里
当我想从特定 VPN 连接发出请求时,我可以将套接字绑定到 IP 地址(10.200.1.31
例如)。但我无法将其绑定到特定接口(我无法手动选择tun2
)。
一旦我将其绑定到特定的本地 IP 地址,我就会有一个额外的路由表(使用iproute2
),该路由表告诉系统将来自本地 IP 地址的数据包发送通过相应的网络接口。
当每个 VPN 接口都有不同的本地 IP 时,这可以正常工作。
但是对于tun0
和tun2
,我将有两个路由表,一个告诉从 路由数据包10.200.1.31
,tun0
另一个告诉通过 路由数据包tun2
。因此最终的路由是不可预测的。
我该如何解决这个问题?
我有两个想法,但我不知道如何实现它们,也不知道它们是否可行:
- 为每个 VPN 连接创建一个具有唯一 IP 地址的虚拟接口,并以
iptables
某种方式编辑传出数据包的源地址并通过适当的 VPN 接口发送它们? - 或者有没有办法创建一个可以完成类似工作的虚拟 NAT 路由器?我应该寻找什么软件?
编辑:
我正在研究第一个想法。我正在尝试创建一个虚拟接口dummy0
(具有唯一的本地 IP 地址),将所有数据包重定向到 VPN 接口tun0
。
创建虚拟接口:
modprobe dummy
ifconfig dummy0 192.168.1.1 up
将流量从虚拟接口重定向到 VPN:
iptables -t nat -A POSTROUTING -s 192.168.1.1 -j SNAT --to 10.200.1.31 -o tun0
将流量从 VPN 接口重定向回虚拟接口:
iptables -t nat -A PREROUTING -d 10.200.1.31 -j DNAT --to-destination 192.168.1.1
不幸的是,这不起作用:
ping -I 192.168.1.1 google.com
PING google.com (173.194.40.132) from 192.168.1.1 : 56(84) bytes of data.
--- google.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1009ms
你知道为什么吗?
答案1
我发现解决方案很简单:
首先,我们创建足够的虚拟接口:
modprobe numdummies=254
然后我们做三件事:
- 设置虚拟接口,以便能够绑定到虚拟接口的唯一 IP 地址
- 每个 VPN 接口上均使用 Avctivate IP 伪装
- 设置一条规则,规定对来自虚拟接口 IP 的数据包使用与 VPN 接口关联的路由表
可以通过以下shell脚本实现:
for n in {0..253}
do
n1=`expr $n + 1`
ifconfig dummy$n 192.168.42.$n1/32 up
iptables -t nat -A POSTROUTING -o tun$n -j MASQUERADE
ip rule add from 192.168.42.$n1 lookup tun$n
done
我的路由表如下所示tun0
:
default via 10.200.0.1 dev tun0
10.200.0.0/22 dev tun3 scope link src 10.200.1.31
工作完成了!
答案2
我认为你的问题的关键在于这句话:
以某种方式编辑传出数据包的源地址
我确实知道我从未能够将传出数据包的 IP 地址设置为除接口的基本 IP 之外的任何地址。我相信内核网络代码被设计成这样工作,因为跟踪该数据包应该从哪个接口发出会产生开销。
您可能需要查看网络驱动程序,并可能在那里做一些修改。
如果您确实设法破坏内核之外的 IP,请注意您将为该逻辑付出的性能损失。