Nadmiarowe połączenia OpenVPN z zaawansowanym routingiem Linux w niewiarygodnej sieci

9

Obecnie mieszkam w kraju, który blokuje wiele stron internetowych i ma niewiarygodne połączenia sieciowe ze światem zewnętrznym. Mam dwa punkty końcowe OpenVPN (powiedzmy: vpn1 i vpn2) na serwerach Linux, których używam do obchodzenia zapory. Mam pełny dostęp do tych serwerów. Działa to całkiem dobrze, z wyjątkiem dużej utraty pakietów na moich połączeniach VPN. Ta utrata pakietów waha się między 1% a 30% w zależności od czasu i wydaje się mieć niską korelację, przez większość czasu wydaje się losowa.

Zastanawiam się nad skonfigurowaniem routera domowego (także w systemie Linux), który utrzymuje połączenia OpenVPN z obydwoma punktami końcowymi i wysyła wszystkie pakiety dwa razy, do obu punktów końcowych. vpn2 wyśle ​​wszystkie pakiety z domu do vpn1. Zwrot ruchu zostanie wysłany zarówno bezpośrednio z vpn1 do domu, jak i przez vpn2.

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

Dla jasności: wszystkie pakiety między serwerem macierzystym a serwerem proxy HTTP zostaną zduplikowane i wysłane różnymi ścieżkami, aby zwiększyć szanse, że jeden z nich dotrze. Jeśli oba pojawią się, pierwszą drugą można po cichu odrzucić.

Wykorzystanie przepustowości nie stanowi problemu, zarówno po stronie głównej, jak i po stronie punktu końcowego. VPN 1 i VPN 2 są blisko siebie (ping 3 ms) i mają niezawodne połączenie.

Wszelkie wskazówki na temat tego, jak można to osiągnąć za pomocą zaawansowanych zasad routingu dostępnych w systemie Linux?

konrad
źródło

Odpowiedzi:

8

Użyj infrastruktury łączenia po stronie „domowej” i „vpn1”, a konkretnie przy ustawieniu mode = 3, które rozgłasza ruch na wszystkich interfejsach należących do powiązania.

Aby uzyskać więcej informacji na temat konfiguracji łączenia, zobacz doskonały podręcznik na stronie http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.37.y.git;a=blob;f = Dokumentacja / sieć / bonding.txt; h = 5dc638791d975116bf1a1e590fdfc44a6ae5c33c; hb = HEAD

jap
źródło
Przetestowałem tę konfigurację i działa fantastycznie. Utrata paczki została zmniejszona z około 5% do 0,0-0,1% dzięki redundantnemu połączeniu tylko z jednym serwerem!
konrad
7

Użyłem odpowiedzi podanej przez @ user48116 i działa to jak urok. Konfiguracja jest właściwie dość prosta!

UWAGA : Zaimplementowałem to z dwoma połączeniami tylko z jednym serwerem, ponieważ już to rozwiązało problem. Jeśli chcesz wypróbować konfigurację z dwoma serwerami, najprościej jest prawdopodobnie użyć przekierowania portów, aby przekierować port UDP z drugiego serwera na pierwszy i użyć tej samej receptury, jak opisano tutaj. Jednak sam tego nie testowałem.

Po pierwsze, upewnij się, że masz jądro 2.6 z obsługą łączenia (domyślnie we wszystkich współczesnych dystrybucjach) i zainstalowano ifenslave.

Następnie umieść to w swoim /etc/rc.local lub w innym preferowanym miejscu, ale upewnij się, że jest uruchomione przed uruchomieniem openvpn (ponieważ będzie próbował połączyć się z bond0):

Klient:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.2 netmask 255.255.255.0 up

W razie potrzeby możesz dodać trochę routingu, upewnij się jednak, że wykonujesz wszystkie prawidłowe routing również z drugiej strony.

route add -net 10.7.0.0/24 gw 10.10.0.1

Serwer:

modprobe bonding mode=broadcast
ifconfig bond0 10.10.0.1 netmask 255.255.255.0 up

Utwórz skrypt /etc/openvpn/tap-up.sh (i nie zapomnij zaznaczyć go jako wykonywalnego za pomocą 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"

Następnie dodaj bridge0a.conf i bridge0b.conf do / etc / openvpn / wraz ze wspólnym kluczem. Pliki są takie same dla aib, z wyjątkiem innego portu (na przykład użyj 3002 dla b). Zastąp 11.22.33.44 publicznym adresem IP twojego serwera.

Klient:

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

Serwer:

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

Nie zapomnij edytować pliku / etc / defaults / openvpn, aby upewnić się, że uruchomiono nowe konfiguracje VPN. Uruchom ponownie maszyny lub załaduj plik rc.local i ręcznie uruchom ponownie openvpn.

Teraz możesz przetestować konfigurację:

# 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

Jeśli wszystko pójdzie dobrze, a linia jest dobra, zobaczysz cztery odpowiedzi dla każdego pakietu ICMP: twoje pakiety są duplikowane po stronie lokalnej, a odpowiedzi na te dwa pakiety są duplikowane ponownie po stronie zdalnej. Nie będzie to stanowić problemu dla połączeń TCP, ponieważ TCP po prostu zignoruje wszystkie duplikaty.

Jest to problem w przypadku pakietów UDP, ponieważ to oprogramowanie zajmuje się obsługą duplikatów. Na przykład zapytanie DNS da cztery odpowiedzi zamiast oczekiwanych dwóch (i użyje czterokrotnie normalnej przepustowości dla odpowiedzi zamiast dwa razy):

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

Powodzenia!

konrad
źródło