OpenVPN za stunnel: przekieruj opakowanie, nie port 1194
Dwa nasłuchy, trzy porty. Sprawdź, gdzie ląduje przekierowanie, gdzie wiąże się opakowanie, dokąd się łączy, co pominął lokalny test i obie tożsamości.
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.
| Hop | Listens on | Must reach | Symptom when it points elsewhere |
|---|---|---|---|
| Client machine | A local plaintext port | The wrapper's public TLS address | Plain text offered to a TLS endpoint |
| Router forward | Public TCP 443 | The wrapper host on its translated port | Wrapper records no connection at all |
| Wrapper, server mode | Its accepted port, 8443 here | The native VPN socket on loopback | Handshake completes, then silence |
| Native VPN listener | Loopback TCP port | Its peer, over TCP only | A 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