PPTP in Docker authentifiziert, überträgt aber keinen Verkehr
PPTP braucht TCP 1723 für die Steuerung und GRE für die Nutzdaten. Im Container fehlt oft der conntrack-Helfer, also funktioniert die Anmeldung und sonst nichts.
Der Client authentifiziert sich, PPP handelt eine Adresse aus, und dann bewegt sich nichts. Ping schlägt fehl, der Browser schlägt fehl, und der Container sieht die ganze Zeit verbunden aus. Dieses Muster ist kein Routingtabellenproblem, denn Routingprobleme brechen meist auch die Steuerverbindung. Es ist der Nutzdatenpfad, und bei PPTP sind die Nutzdaten ein anderes Protokoll als das, das gerade erfolgreich war.
Fünf Prüfungen, in der Reihenfolge, die am meisten Zeit spart.
Prüfung 1: Steuerkanal und Nutzdaten trennen
PPTP authentifiziert über TCP 1723 und trägt dann die PPP-Nutzdaten in GRE, IP-Protokoll 47. GRE ist weder TCP noch UDP, daher sagt jede Regel, die den Steuerport weiterleitet, nichts darüber aus. Ein NAT oder eine Firewall, die 1723 durchlässt, kann Protokoll 47 ohne Beschwerde verwerfen, und die Sitzung bleibt halb aufgebaut in einer Weise, die wie Erfolg aussieht.
Wenn die Anmeldung funktioniert und kein Paket zurückkommt, nehmen Sie zuerst GRE an und beweisen es danach.
Prüfung 2: den Helfer im Host-Kernel bestätigen
Die Verbindungsverfolgung kann eine TCP-Steuerverbindung ohne Helfer nicht mit einem GRE-Fluss verknüpfen. Das Modul ist nf_conntrack_pptp, es lebt im Host-Kernel, und es im Container-Image zu laden bringt nichts, weil Module hostweit gelten. lsmod | grep nf_conntrack_pptp auf dem Docker-Host ist die Prüfung. Fehlt es, lädt modprobe nf_conntrack_pptp es für den laufenden Kernel und sagt nichts über den nächsten Start, also tragen Sie es auch in die Host-Konfiguration ein.
Ein Modul, das beim Neustart verschwindet, wird nächsten Monat dasselbe Ticket.
Prüfung 3: die Kernel-Richtlinie lesen, die es abschaltet
Selbst mit vorhandenem Modul setzen Kernel seit 4.7 net.netfilter.nf_conntrack_helper standardmäßig auf 0, was die automatische Helferzuweisung für jedes Protokoll abschaltet. Diese Vorgabe ist der Grund, warum ein korrekt installiertes Modul trotzdem nichts tut: Der Code ist da, und die Richtlinie sagt, ihn nicht zu nutzen. sysctl net.netfilter.nf_conntrack_helper meldet den aktuellen Wert, und ihn zur Laufzeit auf 1 zu setzen macht den Helfer wieder verfügbar. Behalten Sie den Wert über die sysctl-Konfiguration des Hosts bei, wenn das Design es erlaubt.
Automatische Zuweisung lässt Verkehr implizit Erwartungen erzeugen, und genau deshalb wurde die Vorgabe geändert. Beschränken Sie sie auf den vertrauenswürdigen Host oder verwenden Sie eine ausdrückliche Regel, die auf den Helfer zielt.
Prüfung 4: den Container-Pfad getrennt betrachten
Ein geladener Helfer erzeugt keine Route. Der Container braucht einen Pfad zum PPTP-Server, und die Weiterleitung auf dem Host muss GRE in beide Richtungen erlauben: iptables -L FORWARD -v -n zeigt, ob Protokoll 47 akzeptiert wird und ob sich die Zähler bewegen. Die Masquerade-Regeln von Docker übersetzen TCP und UDP, nicht Protokoll 47, daher braucht ein gebrückter Container möglicherweise eine ausdrückliche Forward-Freigabe und auf manchen Hosts eine eigene Übersetzungsregel. Stellen Sie außerdem sicher, dass der Container die PPP-Geräteunterstützung hat, die sein Image erwartet.
Lesen Sie die Zähler statt des Regeltexts. Eine Regel, die existiert und nichts trifft, ist Dekoration.
Prüfung 5: beweisen, dass GRE verfolgt wird, dann über PPTP entscheiden
Lesen Sie bei laufendem Client die Tracking-Tabelle. Ein etablierter PPTP-Steuereintrag plus ein zugehöriger GRE-Eintrag bedeutet, dass der Helfer die Flüsse verknüpft und der verbleibende Fehler woanders liegt. Ein Steuereintrag ohne GRE-Eintrag bedeutet, dass die Nutzdaten verworfen oder nicht verfolgt werden, was Sie zu den Prüfungen 2 und 3 zurückbringt.
PPTP selbst ist Altbestand und MS-CHAPv2 ist schwach. Bietet der Server auch L2TP/IPsec, IKEv2 oder WireGuard an, beseitigt ein Wechsel zu einem davon diese ganze Problemklasse.
Wo PPTP bleiben muss, beseitigt der Betrieb des Clients auf dem Host statt im Container eine Schicht NAT und Filterung, was oft die günstigere Entscheidung ist.