Le client s'authentifie, PPP négocie une adresse, puis rien ne bouge. Le ping échoue, le navigateur échoue et le conteneur semble connecté tout le temps. Ce schéma n'est pas un problème de table de routage, car les problèmes de routage cassent généralement aussi la connexion de contrôle. C'est le chemin de la charge, et en PPTP la charge est un protocole différent de celui qui vient de réussir.

Cinq vérifications, dans l'ordre qui fait gagner le plus de temps.

Vérification 1 : séparez le canal de contrôle de la charge

PPTP s'authentifie sur TCP 1723 puis transporte la charge PPP dans GRE, protocole IP 47. GRE n'est ni TCP ni UDP, donc chaque règle qui transmet le port de contrôle ne dit rien à son sujet. Un NAT ou un pare-feu qui laisse passer 1723 peut abandonner le protocole 47 sans se plaindre, et la session reste à moitié construite d'une manière qui ressemble à un succès.

Si la connexion fonctionne et qu'aucun paquet ne revient, supposez GRE d'abord et prouvez-le ensuite.

Vérification 2 : confirmez l'assistant dans le noyau de l'hôte

Le suivi des connexions ne peut pas relier une connexion de contrôle TCP à un flux GRE sans assistant. Le module est nf_conntrack_pptp, il vit dans le noyau de l'hôte, et le charger dans l'image du conteneur n'apporte rien car les modules sont communs à tout l'hôte. lsmod | grep nf_conntrack_pptp sur l'hôte Docker est la vérification. S'il manque, modprobe nf_conntrack_pptp le charge pour le noyau en cours et ne dit rien du prochain démarrage, donc ajoutez-le aussi à la configuration de l'hôte.

Un module qui disparaît au redémarrage devient le même ticket le mois suivant.

Vérification 3 : lisez la politique du noyau qui le désactive

Même avec le module présent, les noyaux depuis 4.7 mettent net.netfilter.nf_conntrack_helper à 0 par défaut, ce qui désactive l'attribution automatique d'assistant pour chaque protocole. Cette valeur par défaut explique pourquoi un module correctement installé ne fait toujours rien : le code est là et la politique dit de ne pas s'en servir. sysctl net.netfilter.nf_conntrack_helper indique la valeur actuelle, et la mettre à 1 à l'exécution rend l'assistant de nouveau disponible. Conservez la valeur via la configuration sysctl de l'hôte si la conception le permet.

L'attribution automatique laisse le trafic créer des attentes implicitement, et c'est exactement pourquoi la valeur par défaut a changé. Limitez-la à l'hôte de confiance ou utilisez une règle explicite ciblant l'assistant.

Vérification 4 : examinez le chemin du conteneur séparément

Un assistant chargé ne crée pas de route. Le conteneur a besoin d'un chemin vers le serveur PPTP, et le transfert sur l'hôte doit autoriser GRE dans les deux sens : iptables -L FORWARD -v -n montre si le protocole 47 est accepté et si les compteurs bougent. Les règles masquerade de Docker traduisent TCP et UDP, pas le protocole 47, donc un conteneur ponté peut avoir besoin d'une acceptation forward explicite et, sur certains hôtes, de sa propre règle de traduction. Vérifiez aussi que le conteneur dispose du support d'appareil PPP que son image attend.

Lisez les compteurs plutôt que le texte de la règle. Une règle qui existe et ne correspond à rien est une décoration.

Vérification 5 : prouvez que GRE est suivi, puis décidez pour PPTP

Avec le client en marche, lisez la table de suivi. Une entrée de contrôle PPTP établie plus une entrée GRE associée signifient que l'assistant relie les flux et que la panne restante est ailleurs. Une entrée de contrôle sans entrée GRE signifie que la charge est abandonnée ou non suivie, ce qui vous ramène aux vérifications 2 et 3.

PPTP lui-même est hérité et MS-CHAPv2 est faible. Si le serveur propose aussi L2TP/IPsec, IKEv2 ou WireGuard, passer à l'un d'eux élimine toute cette classe de problèmes.

Là où PPTP doit rester, exécuter le client sur l'hôte plutôt que dans un conteneur élimine une couche de NAT et de filtrage, ce qui est souvent la décision la moins coûteuse.

Articles similaires