Dlaczego nc -uz nie potrafi udowodnić, że serwer OpenVPN jest gotowy
Sonda UDP netcat zgłasza sukces, nawet gdy nic nie nasłuchuje, więc nie może udowodnić, że serwer OpenVPN jest gotowy. Sprawdź proces, dziennik, nasłuchujący socket i prawdziwego klienta.
Uruchomienie nc -uz wobec OpenVPN serwera prawie nic nie mierzy, a podręcznik OpenBSD mówi o tym w swoich zastrzeżeniach: skany UDP w tym trybie zgłaszają sukces niezależnie od tego, czy coś nasłuchuje. Kod wyjścia odzwierciedla lokalne wysłanie, a nie stan zdalny, więc nadzorca, który mu ufa, trzyma martwy serwer oznaczony jako zdrowy, dopóki tablica procesów wygląda wiarygodnie. Zastąpienie go zaczyna się od decyzji, na jakie pytanie ma odpowiedzieć kontrola, bo proces, nasłuchujący socket, uwierzytelnianie i osiągalność aplikacji to cztery różne obserwacje. Sonda, która nazywa jedną z nich, jest użyteczna; sonda, która sugeruje wszystkie cztery, jest obciążeniem.
Co sonda UDP może, a czego nie może zaobserwować
nc -uz wysyła datagram i kończy pracę, a zwracany status opisuje lokalne wysłanie. Zamknięty port może odpowiedzieć ICMP port unreachable, ale udokumentowane zachowanie tego trybu skanowania nie zamienia tego w błąd, a filtrowany port nie daje żadnej odpowiedzi. Cisza i sukces znaczą więc dla wywołującego to samo.
To czyni sondę testem lokalnego stosu, a nie serwera. Nie ustala, że host jest osiągalny, że port jest związany, że proces OpenVPN działa ani że klient mógłby się uwierzytelnić. Test połączenia TCP jest silniejszy, bo uścisk dłoni daje jednoznaczną odpowiedź, ale tylko wtedy, gdy wdrożenie naprawdę nasłuchuje na TCP. Przełączenie sondy na TCP na tym samym numerze testuje nasłuch, którego może nie być, a wobec serwera tylko z UDP zawiedzie zdrową usługę.
Dopasowanie sondy do skonfigurowanego transportu przychodzi przed zaufaniem do któregokolwiek z dwóch wyników. Wdrożenie UDP potrzebuje innego sygnału, a nie innego protokołu.
Trzej wywołujący, trzy różne pytania
Gotowość zależy od tego, kto pyta. Menedżer usług, który restartuje zawieszony proces, musi wiedzieć, że instancja wystartowała i związała swój nasłuch. Moduł równoważenia obciążenia musi wiedzieć, że klient, który przyjdzie teraz, zostałby przyjęty. System monitorowania musi wiedzieć, że ścieżka z prawdziwej sieci nadal niesie sesję do dozwolonego zasobu.
To nie ta sama kontrola i jedna sonda nie może uczciwie pokryć wszystkich trzech. Najpierw wybierz wywołującego, potem dowód.
Zbuduj sondę z bieżącej instancji
OpenVPN zapisuje linię startową, gdy instancja kończy inicjalizację, i ta linia jest użytecznym dowodem lokalnego startu. Czytaj ją z bieżącego startu, a nie z końca dopisywanego pliku, bo sukces z zeszłego tygodnia czyta się dokładnie tak samo jak sukces sprzed minuty. Serwer może też zakończyć inicjalizację, zanim kiedykolwiek połączył się jakikolwiek klient, więc linia nic nie mówi o uwierzytelnianiu.
Do kontroli startu połącz stan procesu z bieżącym dowodem z dziennika i nasłuchem zgodnym ze skonfigurowanym transportem. Kontrola powinna zawieść, gdy proces działa, ale nie zakończył inicjalizacji, co oznacza, że zapytanie do dziennika musi być ograniczone do tego rozruchu i tej jednostki.
systemctl is-active openvpn@server
sudo journalctl -u openvpn@server -b --no-pager | grep "Initialization Sequence Completed"
ss -lunp | grep 1194
Trzy wyjścia, trzy twierdzenia: jednostka jest aktywna, ten rozruch wytworzył linię inicjalizacji i coś trzyma port UDP. Żadne z nich nie mówi, że klient może się połączyć. Trzymaj je osobno na stronie statusu, aby incydent nie zapadł się w jedną zieloną kropkę.
Zepsuj to celowo i obserwuj sondę
Sonda jest wiarygodna dopiero wtedy, gdy zobaczysz jej porażkę. Zatrzymaj serwer, uruchom sondę i potwierdź oczekiwany wynik. Następnie uruchom go ponownie i potwierdź, że sonda wraca do normy bez żadnej innej zmiany.
sudo systemctl stop openvpn@server
nc -uz 203.0.113.10 1194; echo "exit=$?"
ss -lunp | grep 1194
sudo systemctl start openvpn@server
ss -lunp | grep 1194
Czytaj blok linia po linii. Polecenie netcat wypisuje exit=0 , choć nic nie jest związane, i to jest cały problem w jednej linii. Pierwszy ss nic nie wypisuje, restart się udaje, a drugi ss znów pokazuje nasłuch. Jeśli twoja sonda przechodzi wobec zatrzymanego serwera, mierzy lokalny stos i nic więcej.
Odwrotna porażka też się liczy. Sonda, która zawodzi wobec zdrowego serwera, powoduje restarty, które nigdy nie były potrzebne, a pętla restartów sama jest awarią. Przetestuj oba kierunki, zanim podłączysz sondę do czegokolwiek, co może na nią reagować.
Co powinna mówić linia statusu
Zanotuj, którą granicę pokrywa każda kontrola: proces, nasłuch, uwierzytelnianie albo aplikację. Jedna kontrola rzadko pokrywa więcej niż jedną, a strona statusu, która zgniata je w “up”, ukrywa różnicę, która ma znaczenie podczas incydentu. Dla ścieżki sieciowej użyj prawdziwego klienta z dedykowaną tożsamością, pozwól mu dokończyć uścisk dłoni i jedną nieszkodliwą dozwoloną operację, a potem go odłącz. To ćwiczy kanał sterowania, politykę uwierzytelniania i nasłuch w jednym kroku.
Trzymaj tę tożsamość osobno od prawdziwych użytkowników i daj jej minimalne uprawnienia, których potrzebuje kontrola. Sonda gotowości z szerokim dostępem to nowa powierzchnia ataku dodana dla wygody. Rotuj jej poświadczenia jak każde inne konto, bo sonda, która przestaje się uwierzytelniać, wygląda dokładnie jak serwer, który przestał przyjmować klientów.
Nazwij granicę w treści alertu, żeby pierwszy reagujący wiedział, czy patrzeć na jednostkę, gniazdo, certyfikat czy trasę. Sonda, która nie potrafi powiedzieć, co udowodniła, będzie zaufana z niewłaściwego powodu, i właśnie tak kontrola netcat przetrwała na początku.