Dlaczego drugi tunel VPN psuje pierwszy?
Drugi klient VPN instaluje dwie połówkowe trasy domyślne i pierwszy tunel gaśnie: przeczytaj, która trasa wygrywa, a potem rozdziel według profilu, tabeli lub przestrzeni nazw.
Instalowanie drugiego klienta VPN, aby dotrzeć do jednej sieci klienta, to zwykły sposób, w jaki to się zaczyna, i pierwszy tunel gaśnie, podczas gdy oba klienty zgłaszają sukces. Każdy klient zainstalował trasę domyślną, druga była bardziej szczegółowa, a jądro podąża teraz za nią we wszystkim poza własnym zewnętrznym połączeniem pierwszego tunelu. Nic się nie zawaliło i żaden profil nie jest błędny. Jedna trasa zastąpiła drugą, a rozwiązaniem jest zdecydować, który tunel ma posiadać trasę domyślną.
Objaw: drugi klient wygrywa po cichu
OpenVPN: opcja redirect-gateway def1 nie nadpisuje 0.0.0.0/0. Dodaje 0.0.0.0/1 i 128.0.0.0/1: razem obejmują każdy adres IPv4, a każdy prefiks bije zwykłą trasę domyślną długością. Oryginalna trasa domyślna zostaje w tabeli i przestaje być używana do zwykłego ruchu, a trasa do hosta serwera VPN nie pozwala tunelowi przechwycić własnych pakietów zewnętrznych. Oba klienty to robią, a drugi po prostu instaluje swoją parę później.
Dlatego pierwszy tunel wygląda na martwy, a nie odłączony. Jego interfejs jest podniesiony, kanał kontrolny żyje, i żaden ruch aplikacji już do niego nie dociera. Odwrotna skarga ma ten sam brakujący push: telefon, który się łączy, ale nic nie wysyła, zwykle rozmawia z serwerem, który nigdy nie ogłosił redirect-gateway, więc urządzenie zachowuje własną trasę domyślną i dociera tylko do puli.
Zrób zrzut tras przed i po połączeniu drugiego klienta. Dwie połówkowe trasy, które pojawiają się w tabeli, to cała zmiana, i wyjaśniają obie skargi. Nic innego w tabeli nie musi się ruszyć, aby objaw wystąpił. Dlatego usunięcie drugiego klienta natychmiast przywraca pierwszy.
Przeczytaj, który tunel naprawdę wygrywa
Nie wnioskuj zwycięzcy z kolejności uruchamiania klientów ani z ikony w zasobniku. Zapytaj jądra, której trasy użyłoby dla celu poza obiema sieciami prywatnymi, i przeczytaj zwrócony interfejs.
ip route show
ip route get 198.51.100.24
route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.24
Pierwsze dwa to odpowiedź Linuksa, a ostatnie dwa to odpowiednik Windows. Uruchom je, gdy oba tunele są podniesione, następnie odłącz jeden i uruchom ponownie. Różnica między dwoma wyjściami to fakt, którego potrzebujesz przed wyborem rozwiązania, i zajmuje mniej czasu niż czytanie logu któregokolwiek klienta.
Zapisz wynik, w tym nazwę interfejsu i dopasowany prefiks. Zgłoszenie, które mówi, że drugi VPN zepsuł pierwszy, to opis objawu, a nie twierdzenie o routingu, na którym ktoś może działać. Sprawdzenie zamienia to w fakt, który następny inżynier może odtworzyć jednym poleceniem.
Windows: nie pozwól jednemu profilowi posiadać trasy domyślnej
Windows przechowuje zapisane profile, a wbudowany klient pozwala jednemu zależeć od drugiego, aby pierwszy podnosił się automatycznie, gdy drugi wybiera. Profil połączony ostatnio zwykle zachowuje trasę domyślną, więc praktycznym właścicielem jest ostatnie wybieranie, a nie pierwsze. Daj każdemu profilowi własne trasy push i włącz split tunneling dla tego, który nie powinien posiadać trasy domyślnej.
Set-VpnConnection -Name "Contoso" -SplitTunneling $true
rasdial Contoso
Split tunneling to zmienia: do tabeli trafiają tylko prefiksy wypychane przez serwer, co zostawia trasę domyślną przy pierwszym tunelu. Projekt nadal zawodzi, jeśli oba serwery wypychają trasę domyślną, bo wtedy wygrywa ostatnie połączenie i żadne ustawienie po stronie klienta tego nie zmienia. Napraw push po stronie serwera albo zaakceptuj jednego właściciela.
Profile uruchamiane przez aplikację to inna funkcja i warto ją znać: profil Windows może startować, gdy uruchomi się wskazany plik wykonywalny, a filtry ruchu decydują, co niesie. To ustawienie profilu, a nie reguła firewalla, i rozwiązuje inny problem niż konflikt trasy domyślnej.
Linux: trzymaj drugi tunel poza główną tabelą
Uruchamianie dwóch instancji openvpn --config na jednej maszynie umieszcza oba klienty w tej samej tabeli, a trzy opcje rozdzielają je z rosnącą izolacją. Najlżejsza to całkowicie powstrzymać drugiego klienta od edycji tabeli: route-nopull z jawnymi trasami albo skrypt route-up, który instaluje tylko to, co zamierzasz. Wtedy drugi tunel niesie dokładnie nazwane prefiksy i nic więcej. Wtedy ty decydujesz, które prefiksy gdzie trafiają, zamiast odkrywać to później.
Routing polityk to środkowa opcja. Reguła wybiera osobną tabelę dla jednego adresu źródłowego lub znacznika firewalla, i ta tabela niesie trasy drugiego tunelu. Filtrowanie trasy zwrotnej to tu pułapka, bo odpowiedź, która przyjdzie innym interfejsem niż wybrałaby tabela, jest odrzucana, więc sprawdź ustawienie rp_filter, zanim uznasz tunel za zepsuty.
ip rule add from 10.44.7.0/24 table 100
ip route add default dev tun1 table 100
sysctl net.ipv4.conf.all.rp_filter
Przestrzenie nazw sieci to najcięższa i najczystsza opcja. Uruchom drugiego klienta wewnątrz ip netns, daj mu parę veth i wejdź do tej przestrzeni nazw, aby go używać. Zakłócenia znikają, bo każda przestrzeń nazw ma własne tabele zamiast dzielić jedną, co jest warte dodatkowej konfiguracji, gdy oba tunele muszą stać tygodniami.
Na aplikację, a łańcuchowanie jako osobny problem
Czasem tylko jeden program powinien używać drugiego tunelu. W Linuksie routing polityk według użytkownika, cgroup lub portu osiąga ten wynik, a jeden cel można przypiąć do interfejsu bez dotykania trasy domyślnej. Aplikacja, która przypina swój socket do jednego interfejsu, w ogóle nie konsultuje tabeli routingu, więc launcher może dalej używać adaptera fizycznego, dopóki adres nie zostanie wybrany w jego własnych ustawieniach.
Łańcuchowanie to inna operacja niż uruchamianie dwóch tuneli obok siebie. Łańcuchowanie A przez B oznacza, że adres wewnętrznego serwera musi być osiągalny z wnętrza zewnętrznego tunelu. Zewnętrzny klient nie może też brać zaszyfrowanych pakietów wewnętrznego klienta za wyciek. Jeden klient w maszynie wirtualnej to wersja toporna, ale niezawodna; oba na jednym hoście wymagają pracy routingu powyżej plus zewnętrznej drogi do wewnętrznego serwera, która nigdy nie wchodzi do wewnętrznego tunelu.
Zapisz właściciela trasy domyślnej, listę prefiksów niesionych przez każdy tunel i ścieżkę DNS. Te trzy fakty zamieniają następny incydent w sprawdzenie, a nie śledztwo.