Klient uwierzytelnia się, PPP negocjuje adres, a potem nic się nie rusza. Ping zawodzi, przeglądarka zawodzi, a kontener przez cały czas wygląda na połączony. Ten wzorzec nie jest problemem tabeli routingu, bo problemy z routingiem zwykle psują też połączenie sterujące. To ścieżka danych, a w PPTP dane to inny protokół niż ten, który właśnie się udał.

Pięć kontroli, w kolejności, która oszczędza najwięcej czasu.

Kontrola 1: oddziel kanał sterujący od danych

PPTP uwierzytelnia się przez TCP 1723, a następnie przenosi dane PPP wewnątrz GRE, protokołu IP 47. GRE nie jest ani TCP, ani UDP, więc każda reguła przekazująca port sterujący nic o nim nie mówi. NAT lub zapora, która przepuszcza 1723, może bez skargi odrzucić protokół 47, a sesja pozostaje na wpół zbudowana w sposób, który wygląda jak sukces.

Jeśli logowanie działa i żaden pakiet nie wraca, załóż najpierw GRE, a potem to udowodnij.

Kontrola 2: potwierdź pomocnika w jądrze hosta

Śledzenie połączeń nie może bez pomocnika powiązać połączenia sterującego TCP z przepływem GRE. Moduł to nf_conntrack_pptp, żyje w jądrze hosta, a ładowanie go w obrazie kontenera nic nie daje, bo moduły działają na całym hoście. lsmod | grep nf_conntrack_pptp na hoście Docker to właśnie kontrola. Jeśli go brak, modprobe nf_conntrack_pptp ładuje go dla działającego jądra i nic nie mówi o następnym starcie, więc dodaj go także do konfiguracji hosta.

Moduł, który znika przy restarcie, w przyszłym miesiącu staje się tym samym zgłoszeniem.

Kontrola 3: przeczytaj politykę jądra, która go wyłącza

Nawet gdy moduł jest obecny, jądra od 4.7 ustawiają net.netfilter.nf_conntrack_helper domyślnie na 0, co wyłącza automatyczne przypisywanie pomocnika dla każdego protokołu. To ustawienie domyślne jest powodem, dla którego poprawnie zainstalowany moduł nadal nic nie robi: kod jest, a polityka mówi, aby go nie używać. sysctl net.netfilter.nf_conntrack_helper raportuje bieżącą wartość, a ustawienie jej na 1 w czasie działania ponownie udostępnia pomocnika. Zachowaj wartość przez konfigurację sysctl hosta, jeśli projekt na to pozwala.

Automatyczne przypisywanie pozwala ruchowi tworzyć oczekiwania w sposób niejawny, i właśnie dlatego zmieniono ustawienie domyślne. Ogranicz je do zaufanego hosta albo użyj jawnej reguły skierowanej do pomocnika.

Kontrola 4: spójrz osobno na ścieżkę kontenera

Załadowany pomocnik nie tworzy trasy. Kontener potrzebuje ścieżki do serwera PPTP, a przekazywanie na hoście musi zezwalać na GRE w obu kierunkach: iptables -L FORWARD -v -n pokazuje, czy protokół 47 jest akceptowany i czy liczniki się ruszają. Reguły masquerade Dockera tłumaczą TCP i UDP, a nie protokół 47, więc kontener w trybie mostu może potrzebować jawnej akceptacji forward, a na niektórych hostach własnej reguły tłumaczenia. Upewnij się też, że kontener ma obsługę urządzeń PPP, której oczekuje jego obraz.

Czytaj liczniki, a nie tekst reguły. Reguła, która istnieje i do niczego nie pasuje, jest dekoracją.

Kontrola 5: udowodnij, że GRE jest śledzony, potem zdecyduj o PPTP

Gdy klient działa, odczytaj tabelę śledzenia. Ustanowiony wpis sterujący PPTP plus powiązany wpis GRE oznaczają, że pomocnik łączy przepływy, a pozostała usterka jest gdzie indziej. Wpis sterujący bez wpisu GRE oznacza, że dane są odrzucane lub nieśledzone, co sprowadza cię z powrotem do kontroli 2 i 3.

Sam PPTP jest dziedzictwem, a MS-CHAPv2 jest słaby. Jeśli serwer oferuje także L2TP/IPsec, IKEv2 lub WireGuard, przejście na jeden z nich usuwa całą tę klasę problemów.

Tam, gdzie PPTP musi zostać, uruchomienie klienta na hoście zamiast w kontenerze usuwa jedną warstwę NAT i filtrowania, co często jest tańszą decyzją.

Powiązane artykuły