通过不可靠的networking进行高级Linux路由的冗余OpenVPN连接

我目前生活在一个封锁了许多网站的国家,并且与外部世界有着不可靠的networking连接。 我在Linux服务器上有两个OpenVPN端点(比如:vpn1和vpn2),用于规避防火墙。 我可以完全访问这些服务器。 这工作得很好,除了我的VPN连接上的高包丢失。 这个数据包丢失率根据时间的不同而在1%到30%之间变化,似乎相关性很低,大部分时间似乎是随机的。

我正在考虑build立一个家庭路由器(同样在Linux上),维护两个端点的OpenVPN连接,并将所有数据包两次发送到两个端点。 vpn2会将所有的数据包从家里发送到vpn1。 返回trafic将直接从vpn1发送到家,也通过vpn2发送。

+------------+ | home | +------------+ | | | OpenVPN | | links | | | ~~~~~~~~~~~~~~~~~~ unreliable connection | | +----------+ +----------+ | vpn1 |---| vpn2 | +----------+ +----------+ | +------------+ | HTTP proxy | +------------+ | (internet) 

为了清楚起见,家中和HTTP代理之间的所有数据包将被复制并通过不同的path发送,以增加其中一个到达的机会。 如果两者都到达,第一个第二个可以默默丢弃。

带宽使用不是一个问题,无论是在家庭和端点方面。 vpn1和vpn2彼此接近(3ms ping)并具有可靠的连接。

任何关于如何使用Linux中的高级路由策略来实现的指针?

在'home'和'vpn1'端使用绑定基础设施,特别是在所有属于绑定的接口上广播stream量的mode = 3设置。

有关如何configuration绑定的更多信息,请参阅http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f =文档/networking/ bonding.txt; H = 5dc638791d975116bf1a1e590fdfc44a6ae5c33c; HB = HEAD

我用@ user48116提供的答案,它的作品就像一个魅力。 安装程序其实很简单!

:我实现了这两个连接到只有一台服务器,因为这已经解决了我的问题。 如果您想尝试使用两台服务器进行设置,最简单的方法可能是使用端口转发将UDP端口从第二台服务器转发到第一台服务器,并使用与此处所述相同的配方。 我自己虽然没有testing过。

首先,确保你有一个2.6内核绑定支持(默认在所有现代发行版),你有ifenslave安装。

接下来,把它放到你的/etc/rc.local或者其他你喜欢的地方,但是确保它 openvpn开始之前运行(因为它会尝试绑定到bond0):

客户:

 modprobe bonding mode=broadcast ifconfig bond0 10.10.0.2 netmask 255.255.255.0 up 

如果需要的话,你可以添加一些路由,确保你从另一边做所有正确的路由。

 route add -net 10.7.0.0/24 gw 10.10.0.1 

服务器:

 modprobe bonding mode=broadcast ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up 

创build一个/etc/openvpn/tap-up.sh脚本(不要忘记用chmod a + x tap-up.sh标记它的可执行文件):

 #!/bin/sh # called as: cmd tap_dev tap_mtu link_mtu ifconfig_local_ip ifconfig_netmask [ init | restart ] ifenslave bond0 "$1" 

接下来,将一个bridge0a.conf和bridge0b.conf添加到/ etc / openvpn /和一个共享密钥。 a和b的文件是相同的,除了不同的端口(例如,对于b使用3002)。 用服务器的公共IPreplace11.22.33.44。

客户:

 remote 11.22.33.44 dev tap port 3001 rport 3001 secret bridge.key comp-lzo verb 4 nobind persist-tun persist-key script-security 2 up /etc/openvpn/tap-up.sh 

服务器:

 local 11.22.33.44 dev tap port 3001 lport 3001 secret bridge.key comp-lzo verb 4 script-security 2 up /etc/openvpn/tap-up.sh 

不要忘记编辑/ etc / defaults / openvpn以确保您的新VPNconfiguration已启动。 重新启动机器,或者加载rc.local并手动重新启动openvpn。

现在您已准备好testing您的设置:

 # ping 10.10.0.1 PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data. 64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=50.4 ms 64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!) 64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!) 64 bytes from 10.10.0.1: icmp_req=1 ttl=64 time=51.1 ms (DUP!) 64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.0 ms 64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=52.2 ms (DUP!) 64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.0 ms (DUP!) 64 bytes from 10.10.0.1: icmp_req=2 ttl=64 time=53.1 ms (DUP!) --- 10.10.0.1 ping statistics --- 2 packets transmitted, 2 received, +6 duplicates, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 50.428/51.786/53.160/0.955 ms 

如果一切顺利,线路良好,你会看到每个ICMP软件包有四个回复:你的软件包在本地被复制,这两个软件包的回复在远端再次被复制。 这对于TCP连接来说不是问题,因为TCP会忽略所有重复项。

这是UDP数据包的一个问题,因为这是由软件来处理重复的。 例如,一个DNS查询将产生四个答复,而不是预期的两个(并且使用正常带宽的四倍而不是两倍):

 # tcpdump -i bond0 -n port 53 listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes 13:30:39.870740 IP 10.10.0.2.59330 > 10.7.0.1.53: 59577+ A? serverfault.com. (33) 13:30:40.174281 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49) 13:30:40.174471 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49) 13:30:40.186664 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49) 13:30:40.187030 IP 10.7.0.1.53 > 10.10.0.2.59330: 59577 1/0/0 A 64.34.119.12 (49) 

祝你好运!