通过不可靠网络的高级Linux路由实现冗余的OpenVPN连接


9

我目前居住在一个封锁许多网站并且与外界的网络连接不可靠的国家。我在用于绕过防火墙的Linux服务器上有两个OpenVPN端点(例如:vpn1和vpn2)。我拥有对这些服务器的完全访问权限。这很好,除了我的VPN连接丢失大量数据包外。根据时间的不同,此丢包率在1%到30%之间变化,并且在大多数情况下似乎是随机的,其相关性较低。

我正在考虑建立一个家庭路由器(也在Linux上),该路由器维护与两个端点的OpenVPN连接,并将所有数据包两次发送到两个端点。vpn2会将所有数据包从家发送到vpn1。回程交通既可以直接从vpn1发送到家庭,也可以通过vpn2发送。

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

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

带宽使用不是问题,无论是在本地端还是在端点端。vpn1和vpn2彼此靠近(3毫秒ping)并具有可靠的连接。

关于使用Linux中可用的高级路由策略如何实现此目标的任何指示?

Answers:


8

在“ home”和“ vpn1”侧使用绑定基础结构,并特别使用mode = 3设置,该设置在属于绑定的所有接口上广播流量。

有关如何配置绑定的更多信息,请参见http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f上的出色手册=文档/网络/bonding.txt;h=5dc638791d975116bf1a1e590fdfc44a6ae5c33c;hb=HEAD


我测试了此设置,效果很好。通过仅一台服务器的冗余连接,程序包损失从5%左右降低到0.0-0.1%!
康拉德2011年

7

我使用了@ user48116提供的答案,它的工作原理就像一个魅力。设置实际上非常简单!

注意:我通过仅连接到一台服务器的两个连接来实现此目的,因为这已经为我解决了问题。如果要尝试使用两台服务器进行安装,最简单的方法可能是使用端口转发将UDP端口从第二台服务器转发到第一台服务器,并使用此处所述的相同配方。我自己还没有测试过。

首先,请确保您具有支持绑定的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

创建一个/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)。用服务器的公用IP替换11.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以确保您的新VPN配置已启动。重新启动计算机,或加载rc.local并手动重新启动openvpn。

现在您可以测试设置了:

# 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)

祝好运!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.