Stream relay w Nginx dla OpenVPN UDP: co się zmienia
UDP nie należy do location HTTP. Przenieś go do warstwy stream, dobierz limit czasu sesji dla VPN i licz się z tym, że źródłem będzie proxy.
Twój klient jest ustawiony na UDP, serwer Nginx ma blok location wskazujący na port VPN, a nic nie dociera. To oczekiwane: location HTTP nie może przenieść datagramu UDP, jakkolwiek nazwiemy front end. Nginx potrzebuje do tego listenera stream, a po przeniesieniu tam konfiguracji o tym, czy sesja przetrwa, decyduje drugi zestaw szczegółów.
Warstwa proxy przychodzi przed adresem
Moduł stream Nginx proxuje TCP i UDP bez analizowania HTTP. Jego moduł HTTP oczekuje linii żądania, nagłówków i odpowiedzi, a niczego z tego nie ma w natywnym OpenVPN datagramie. Wybór warstwy jest więc pierwszą decyzją i nie zależy od tego, czy listener jest IPv4, czy IPv6.
Konfiguracja, która wygląda na działającą z TCP OpenVPN, nic nie mówi o przypadku UDP. Transport jest tu częścią protokołu, a nie szczegółem wdrożenia.
Listener i backend
nginx -V 2>&1 | tr ' ' '\n' | grep stream
stream {
server {
listen [::]:1194 udp reuseport;
proxy_pass [2001:db8::20]:1194;
}
}
Przed czymkolwiek edytowaniem upewnij się, że build zawiera moduł stream; pakiet dystrybucyjny może go wydzielić do osobnego modułu, a brakujący moduł daje błąd konfiguracji, a nie tunel. Umieść blok w głównym kontekście konfiguracji, nie wewnątrz http, i zastąp adres dokumentacyjny prawdziwym backendem.
Zarówno obie trasy, jak i obie zapory muszą przepuszczać datagramy: ścieżka do listenera i ścieżka od proxy do backendu. Listener IPv6 nie tworzy też ścieżki IPv4, więc jeśli część klientów nadal używa IPv4, ten listener jest osobnym wpisem z własnymi testami. Sprawdź zaporę samego backendu z adresu proxy, a nie z laptopa.
Limity czasu sesji to nie limity czasu żądania
Proxy stream trzyma stan sesji UDP i odrzuca go zgodnie ze swoim limitem czasu i ustawieniami odpowiedzi. Krótki limit czasu skopiowany z relay DNS słabo pasuje do VPN, który oczekuje wymiany datagramów przez godziny, a awaria objawia się jako połączenie, które cicho umiera, a nie takie, które odmawia startu.
Odczytaj efektywny proxy_timeout wdrożenia i dowolne ustawienie liczby odpowiedzi, a następnie porównaj je z zachowaniem keepalive, którego VPN faktycznie używa. Dwie liczby zapisane w różnych plikach przez różnych ludzi to normalny stan działającego systemu. Dwie liczby, których nigdy nie porównano, to normalny stan systemu działającego z przerwami. Zapisz obie w rejestrze usługi, żeby porównanie odbyło się raz, w świetle dnia.
Co relay zmienia, a czego nie
Proxy stream nie kończy kanału sterującego TLS OpenVPN i nie zamienia go na HTTPS. Backend pozostaje usługą VPN, a relacja certyfikatu pozostaje między klientem a tą usługą. Zachowanie zamierzonej tożsamości backendu nadal należy do klienta i serwera.
Zwykłe proxowanie zmienia też adres źródłowy, który widzi backend. Logi pokażą proxy, a każda reguła dostępu oparta na IP na serwerze VPN oceni ten adres, a nie adres klienta. Przezroczyste zachowanie źródła to osobny projekt routingu i uprawnień, a nie coś, co wynika z dodania udp do listenera. Zaplanuj to, zanim powstanie polityka zależna od adresu klienta.
Weryfikuj z klienta, nie z portu
Lokalne sprawdzenie, że port UDP jest otwarty, dowodzi istnienia listenera. Nie dowodzi, że klient może się przez niego uwierzytelnić lub dalej wymieniać ruch. Wykonaj prawdziwe połączenie z zatwierdzonego klienta, a następnie potwierdź, że sesja utrzymuje się wystarczająco długo, by miało to znaczenie.
Gdy ktoś zgłasza, że Nginx nie potrafi UDP, bo zamiast niego zadziałało proste narzędzie relay, te dwa fakty nie mają ze sobą związku. Narzędzie dowiodło, że backend odpowiada; nie powiedziało nic o tym, co obsługuje front end. Oba mogą być prawdziwe, a tylko jeden z nich jest konfiguracją dla tego wdrożenia.