В настоящее время я живу в стране, которая блокирует множество веб-сайтов и имеет ненадежные сетевые соединения с внешним миром. У меня есть две конечные точки OpenVPN (скажем: vpn1 и vpn2) на серверах Linux, которые я использую для обхода брандмауэра. У меня есть полный доступ к этим серверам. Это работает довольно хорошо, за исключением высокой потери пакетов на моих VPN-соединениях. Эта потеря пакетов варьируется от 1% до 30% в зависимости от времени и, кажется, имеет низкую корреляцию, в большинстве случаев она кажется случайной.
Я думаю о настройке домашнего маршрутизатора (также в Linux), который поддерживает соединения OpenVPN с обеими конечными точками и дважды отправляет все пакеты на обе конечные точки. vpn2 отправит все пакеты из дома на vpn1. Обратный трафик будет отправляться как напрямую от vpn1 к дому, так и через vpn2.
+------------+
| home |
+------------+
| |
| OpenVPN |
| links |
| |
~~~~~~~~~~~~~~~~~~ unreliable connection
| |
+----------+ +----------+
| vpn1 |---| vpn2 |
+----------+ +----------+
|
+------------+
| HTTP proxy |
+------------+
|
(internet)
Для ясности: все пакеты между домашним и HTTP-прокси будут дублироваться и отправляться по разным путям, чтобы повысить вероятность прибытия одного из них. Если оба прибудут, первый второй можно молча выбросить.
Использование полосы пропускания не является проблемой как для домашней, так и для конечной точки. vpn1 и vpn2 расположены близко друг к другу (пинг 3 мс) и имеют надежное соединение.
Есть какие-нибудь указания на то, как этого можно достичь с помощью расширенных политик маршрутизации, доступных в Linux?
Используйте инфраструктуру связывания на "домашней" стороне и "vpn1" и, в частности, с настройкой mode = 3, которая транслирует трафик на все интерфейсы, принадлежащие соединению.
Для получения дополнительной информации о том, как настроить связывание, см. Отличное руководство по адресу http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f=Documentation/networking/bonding.txt;h=5dc638791d975116bf1a1e590fdfc44a6ae5c33c;hb = ГОЛОВА
Я использовал ответ, предоставленный @ 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, за исключением другого порта (например, используйте 3002 для b). Замените 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
Сервер:
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)
Удачи!