kon*_*rad 9 networking linux routing openvpn ip-routing
我目前生活在一个封锁了许多网站并且与外界的网络连接不可靠的国家。我在 Linux 服务器上有两个 OpenVPN 端点(例如:vpn1 和 vpn2),用于绕过防火墙。我可以完全访问这些服务器。这很有效,除了我的 VPN 连接上的高包丢失。这种丢包率随时间的变化在 1% 到 30% 之间变化,并且似乎具有低相关性,大部分时间似乎是随机的。
我正在考虑设置一个家用路由器(也在 Linux 上),它维护与两个端点的 OpenVPN 连接,并将所有数据包发送到两个端点两次。vpn2 会将所有数据包从家庭发送到 vpn1。返回流量将直接从 vpn1 发送到家,也可以通过 vpn2 发送。
+------------+
| home |
+------------+
| |
| OpenVPN |
| links |
| |
~~~~~~~~~~~~~~~~~~ unreliable connection
| |
+----------+ +----------+
| vpn1 |---| vpn2 |
+----------+ +----------+
|
+------------+
| HTTP proxy |
+------------+
|
(internet)
Run Code Online (Sandbox Code Playgroud)
为清楚起见:家庭和 HTTP 代理之间的所有数据包都将被复制并通过不同路径发送,以增加其中之一到达的机会。如果两者都到达,则可以静默丢弃第一个第二个。
带宽使用不是问题,无论是在家庭端还是端点端。vpn1 和 vpn2 彼此靠近(3ms ping)并且具有可靠的连接。
关于如何使用 Linux 中可用的高级路由策略来实现这一点的任何指示?
在“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
我使用了@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
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以在此处添加一些路由,但请确保您也从另一侧进行所有正确的路由。
route add -net 10.7.0.0/24 gw 10.10.0.1
Run Code Online (Sandbox Code Playgroud)
服务器:
modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up
Run Code Online (Sandbox Code Playgroud)
创建一个 /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"
Run Code Online (Sandbox Code Playgroud)
接下来,将bridge0a.conf 和bridge0b.conf 与共享密钥一起添加到/etc/openvpn/。a 和 b 的文件相同,只是端口不同(例如,b 使用 3002)。将 11.22.33.44 替换为您服务器的公共 IP。
客户:
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
Run Code Online (Sandbox Code Playgroud)
服务器:
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
Run Code Online (Sandbox Code Playgroud)
不要忘记编辑 /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
Run Code Online (Sandbox Code Playgroud)
如果一切顺利,线路正常,您将看到每个 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)
Run Code Online (Sandbox Code Playgroud)
祝你好运!