Vous avez ajouté une route par politique qui envoie le trafic d’un client VPN vers un hôte exécutant un écouteur SOCKS sur le port 1080. Les paquets arrivent, l’écouteur ne journalise rien et la connexion reste bloquée. La route n’a rien d’anormal : le saut suivant choisit où va un paquet, et SOCKS est une conversation que le client doit engager. Comparez les trois architectures que les gens désignent habituellement quand ils font passer le trafic par un proxy, et il devient clair quelle pièce manque à votre configuration.

Le routage, le DNAT et SOCKS changent des choses différentes

Une route par politique réécrit une décision de couche 3. Deux lignes suffisent pour envoyer le trafic d’un client vers un saut suivant choisi :

ip route add default via 10.50.0.2 table 101
ip rule add from 10.77.0.2 lookup 101

Ensuite, le noyau remet le paquet à 10.50.0.2, la destination d’origine restant dans l’en-tête IP. Si 10.50.0.2 est un routeur, il transfère le paquet. S’il s’agit d’un hôte avec un démon SOCKS sur 1080, le paquet n’est adressé à rien qui puisse l’accepter, et le DNAT vers le port 1080 n’aide pas non plus, car un paquet traduit transporte toujours la charge utile applicative d’origine au lieu d’un salut SOCKS.

SOCKS5 commence par un octet de version, une liste de méthodes, un échange d’authentification et une requête qui nomme la destination. Ce sont des données applicatives. Aucune entrée de routage et aucune cible netfilter ne les génèrent, et c’est la comparaison en une ligne : le routage choisit un chemin, SOCKS demande à un serveur d’établir une seconde connexion.

Cas un : l’application peut parler SOCKS elle-même

Quand le programme dispose d’un réglage de proxy, c’est le chemin le plus court et il ne nécessite aucune modification du noyau. Pointez-le vers l’écouteur, fournissez des identifiants si le serveur les demande, et décidez si les noms sont résolus localement ou transmis au proxy. Avec curl, ce sont des indicateurs différents, et la différence compte quand la destination n’est résolue que du côté du proxy :

curl --socks5 10.50.0.2:1080 https://docs.example.com
curl --socks5-hostname 10.50.0.2:1080 https://internal.example.com

Les applications qui ignorent les variables d’environnement de proxy, ou qui ouvrent des sockets brutes, ne peuvent pas être aidées ainsi. Les navigateurs et la plupart des outils HTTP vont bien ; un client de jeu, un démon de messagerie ou un binaire quelconque d’un fournisseur ne le sont généralement pas. La frontière est par application et par protocole, c’est pourquoi cette option est excellente pour tester et faible comme réponse pour tout le VPN.

Cas deux : un adaptateur qui convertit des flux IP en sessions de proxy

Pour les programmes qui ne peuvent pas parler SOCKS, la conversion doit se faire dans quelque chose qui termine le trafic IP et ouvre des sessions de proxy à leur place. Ce composant possède une interface de tunnel, accepte les flux sélectionnés par le routage par politique, effectue la poignée de main SOCKS pour chacun et reconstruit les réponses. La route dirige le trafic vers lui ; l’adaptateur est ce qui crée la session.

Lisez sa documentation avant de lui confier un sous-réseau entier. Beaucoup d’adaptateurs transportent bien TCP et ne gèrent UDP que par une association UDP de SOCKS5, et aucun ne transforme ICMP en trafic de proxy, donc un ping réussi ne dit rien du chemin du proxy. Le DNS est l’autre piège : si l’adaptateur résout les noms localement, les enregistrements strictement internes se résolvent vers une mauvaise réponse, ou vers rien du tout.

La prévention des boucles est le détail opérationnel qui mord. Les propres connexions de l’adaptateur vers le serveur SOCKS ne doivent pas être routées de nouveau vers l’adaptateur, son trafic a donc besoin d’une exception dans la règle ou d’une adresse source dédiée. Faites-le mal et la session de proxy tentera de faire proxy d’elle-même.

Cas trois : l’hôte est en réalité une passerelle routée

Parfois la configuration qui fonctionne ne contient aucun SOCKS. L’hôte distant transfère les paquets ou leur applique du NAT, et la règle fondée sur la source le choisit simplement comme sortie. Ce design est légitime, et il explique pourquoi une configuration copiée fonctionne sur un réseau et échoue sur un autre : la règle est identique, la pièce manquante est un service de transfert de l’autre côté.

Les trois cas se séparent vite. Vérifiez ce qui écoute réellement, puis regardez les premiers octets qui atteignent l’hôte :

ss -ltnp 'sport = :1080'
tcpdump -ni eth0 -X 'tcp port 1080'

Le premier octet de charge utile d’un vrai client SOCKS est 0x05, la version dans le salut. Si la capture montre à la place des données applicatives d’origine, aucun démon SOCKS ne répondra, car la négociation n’a jamais commencé. Si rien n’écoute sur 1080, l’hôte est une passerelle, et la question devient de savoir s’il transfère et s’il existe un chemin de retour.

Choisissez la couche avec quatre questions

Le programme a-t-il un réglage de proxy ? Utilisez-le et arrêtez-vous là. Le trafic comprend-il de l’UDP ou de l’ICMP qui doivent survivre ? Seule une passerelle routée ou NAT transporte ICMP, et UDP exige une association SOCKS5 que les deux extrémités prennent en charge. Chaque processus de la machine doit-il être couvert, y compris ceux que vous ne pouvez pas configurer ? Alors il vous faut un adaptateur qui possède l’interface et termine les flux. Pouvez-vous aussi assumer son routage, son DNS et ses exceptions de prévention des boucles ? Sinon, la passerelle simple coûtera moins cher à exploiter.

Une distinction mérite d’être gardée claire. La propre option socks-proxy d’un client VPN décrit comment la connexion du tunnel extérieur atteint son serveur, et ne dit rien de la conversion des flux internes du client. Les deux sont constamment confondues dans le même ticket. Décidez de la relation dont vous avez besoin avant de toucher à une route.

Articles similaires