Postaw opakowanie TLS przed OpenVPN a wdrożenie zyskuje drugi nasłuch, z których tylko jeden powinien kiedykolwiek wychodzić do internetu. Gdy tunel działa z tej samej maszyny, a zawodzi z zewnątrz, przekierowanie zwykle celuje w niewłaściwy z dwóch. To, co musi się zgadzać, to łańcuch: publiczna reguła dociera do opakowania, a własne połączenie backendowe opakowania dociera do prawdziwego gniazda VPN. Cztery skoki niosą ten łańcuch i każdy z nich może przedwcześnie zakończyć dochodzenie.

Dwa gniazda, dwóch właścicieli, jedno publiczne

Opakowanie kończy TLS dla połączenia zewnętrznego i przekazuje odszyfrowany strumień bajtów zwykłemu nasłuchowi OpenVPN TCP. To osobne gniazda z osobnymi plikami konfiguracji, więc edycja jednego pozostawia drugie nietknięte i nadal pozornie zdrowe. Oznacza to też, że oba mogą się rozjechać, gdy jedno zmienia się bez drugiego.

Praca z samej maszyny dowodzi więc bardzo niewiele o ścieżce publicznej. Bezpośrednie połączenie z portem rodzimym pomija opakowanie, połączenie z opakowaniem na jego adresie LAN pomija tłumaczenie, a tylko pełna konfiguracja po stronie klienta ćwiczy to, co robi użytkownik z zewnątrz. Nazwy też trzeba czytać uważnie, bo localhost oznacza host, na którym działa właśnie ten komponent, a nie host, na którym akurat piszesz. Zapisuj to rozróżnienie w notatkach, bo test zapisany bez skoku, który obejmował, zaprasza do porównania dwóch różnych rzeczy.

Gdzie przekierowanie naprawdę ląduje

Łańcuch łatwiej utrzymać jako cztery skoki niż jako trzy numery portów, bo ten sam numer może znaczyć co innego na każdym końcu. Czytaj tabelę wiersz po wierszu: każdy wiersz to jedno gniazdo, które musi przyjąć połączenie, a następnie otworzyć kolejne. Gdy wiersz celuje w niewłaściwego partnera, objaw w ostatniej kolumnie jest tym, co zgłasza użytkownik.

HopListens onMust reachSymptom when it points elsewhere
Client machineA local plaintext portThe wrapper's public TLS addressPlain text offered to a TLS endpoint
Router forwardPublic TCP 443The wrapper host on its translated portWrapper records no connection at all
Wrapper, server modeIts accepted port, 8443 hereThe native VPN socket on loopbackHandshake completes, then silence
Native VPN listenerLoopback TCP portIts peer, over TCP onlyA UDP socket behind a byte-stream relay

Reguła celująca w rodzimy port VPN zamiast w opakowanie całkowicie pomija zakończenie TLS, i to jest najczęstsza postać tego błędu: klient otwiera uścisk dłoni z nasłuchem, który oczekuje ramkowania OpenVPN, więc połączenie może się otworzyć i potem zaciąć. Potwierdź przetłumaczony port w pliku konfiguracji opakowania, a nie w pamięci, bo następna osoba edytująca ten plik mogła wybrać inny numer. Dwie komendy poniżej pokazują obie strony tego pytania naraz.

grep -nE '^[[:space:]]*(accept|connect)' /etc/stunnel/stunnel.conf
ss -lntp | grep -E ':443|:8443|:1194'

Adres wiązania, który cię odrzuca

Wiersz accept związany z 127.0.0.1 odpowiada tylko samemu hostowi, więc przekierowanie przychodzące na adres LAN nie może się połączyć, a klient widzi odmowę, która brzmi jak problem filtra pakietów. Spójrz na gniazdo, zanim dotkniesz zapory, bo gniazdo jest tańszą odpowiedzią. Albo zwiąż opakowanie z interfejsem, w który celuje przekierowanie, albo trzymaj je na loopbacku i spraw, by przekierowanie docierało do loopbacku przez coś, co naprawdę działa. To dwa projekty i każdy potrzebuje własnej reguły.

Mieszanie ich to sposób, w jaki działające opakowanie staje się nieosiągalne z zewnątrz, podczas gdy każdy plik wygląda poprawnie. Sprawdzenie poniżej to jedno polecenie i odpowiada na pytanie, na które przegląd reguł zapory nie potrafi. Jeśli wynik pokazuje adres loopback, a przekierowanie celuje w adres LAN, poprawka należy do wiersza accept, a nie do filtra pakietów.

ss -lntp '( sport = :8443 )'

Co naprawdę udowodnił lokalny test

Sukces zapisany bez skoku, który obejmował, nie jest dowodem co do pozostałych skoków. Zanotuj, jakiego adresu użył test i który proces odpowiedział. Potem powtórz z zewnątrz sieci, a nie z telefonu w tej samej sieci Wi-Fi, bo zachowanie spinki różni się między routerami, a połączenie, które nigdy nie opuściło LAN-u, może zadowolić klienta bez żadnego udziału przekierowania. Tylko ta druga próba ćwiczy drogę, którą idzie obcy.

Gdy próba zawiedzie, śledź jedno połączenie w obu logach: przyjętych i połączonych wierszach opakowania, potem we własnym logu sesji demona VPN. Pierwsza granica, która nic nie zapisuje, jest miejscem następnej zmiany. Gdy OpenVPN zaczyna porównywać opcje partnera, oceniaj te komunikaty według reguł tej implementacji. Ostrzeżenie o niespójności link-mtu nie jest automatycznie fatalne, przypięcie link-mtu do 1500 nie dowodzi, że fragmentacja ustała, a negocjacja szyfru należy do wewnętrznej konfiguracji OpenVPN, a nie do przekierowania routera.

nc -vz 127.0.0.1 1194
journalctl -u stunnel -n 50 --no-pager

Te sondy obejmują gniazdo backendu i log opakowania, co oddziela odrzucony backend od odrzuconego uścisku dłoni. Uruchamiaj je, gdy trwa jedna próba, a nie potem. Znaczniki czasu z jednej próby czynią porównanie wiarygodnym.

Dwie tożsamości, dwie kolejności awarii

Zewnętrzny certyfikat należy do opakowania, a wewnętrzna tożsamość do OpenVPN, i mogą pochodzić od różnych organów. Wyłączenie którejkolwiek z dwóch kontroli, by ścieżka wyglądała zdrowo, wymienia realną ochronę na kosmetyczny wynik. Zachowaj oba sprawdzenia i debuguj je po kolei, bo kolejność komunikatów nazywa warstwę: problem certyfikatu opakowania pojawia się przed negocjowaniem jakiejkolwiek opcji VPN, natomiast awaria wewnętrznej tożsamości pojawia się dopiero po ustanowieniu strumienia.

podręcznik stunnel precyzyjnie definiuje accept, connect i tryb klienta, a te sekcje odpowiadają na pytanie o gniazdo szybciej niż zgadywanie. Gdy nadal nie możesz powiedzieć, która warstwa odpowiedziała, przeczytaj certyfikat, który przedstawia publiczny port, poleceniem poniżej. Certyfikat opakowania w wyniku oznacza, że przekierowanie dotarło do opakowania, a cisza lub błąd protokołu oznacza, że nie dotarło. To jedno rozróżnienie oszczędza więcej czasu niż każde inne sprawdzenie tutaj.

openssl s_client -connect vpn.example:443 -servername vpn.example </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer

Powiązane artykuły