Même un ordinateur portable derrière le NAT de l'opérateur peut servir un collègue, tant que le serveur VPN fait office de point de rencontre. Deux mécanismes y mènent : le client se connecte vers l'extérieur et demande au serveur de tenir un port d'écoute, ou le serveur publie un port et le traduit dans le tunnel. Les deux résolvent le même problème d'accessibilité et se comportent différemment en cas de panne, de supervision et de journalisation. Trois conditions décident laquelle appartient à votre installation.

Deux formes, un point de rencontre

Dans la première forme, le client ouvre une session SSH vers l'extérieur et demande au serveur d'écouter sur un port choisi, en renvoyant chaque connexion par cette session. Rien n'est redirigé sur le serveur et aucune traduction de paquets n'a lieu, donc les seules exigences sont un compte SSH, une redirection autorisée et une règle de pare-feu pour le port. Le service reste lié à la boucle locale sur le client, ce qui est généralement souhaité.

ssh -N -R 8081:127.0.0.1:8080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 [email protected]

Dans la seconde forme, le serveur possède le port public et réécrit chaque connexion vers l'adresse du tunnel du client. Cela exige le transfert IP activé, une traduction de destination à l'entrée et une traduction de source à la sortie, et cela continue de fonctionner lorsqu'aucune session SSH n'existe. Le port appartient au serveur et non à une session, et c'est cette propriété qui tranche la plupart des cas réels.

Aucune des deux formes n'est plus sûre par construction. Toutes deux finissent par exposer un port de service à quiconque peut atteindre l'adresse publique du serveur, et toutes deux dépendent encore de l'authentification propre au service.

Condition une : le port doit-il survivre à la session

Une redirection inversée vit exactement aussi longtemps que la session SSH qui l'a créée. Quand le lien tombe, l'écouteur disparaît et le collègue voit une connexion refusée plutôt qu'un chemin lent. Superviser la commande avec une unité systemd et une politique de redémarrage règle cela, et ExitOnForwardFailure=yes rend immédiatement visible une liaison échouée au lieu de laisser une session sans redirection.

Un port traduit survit aux redémarrages si les règles sont conservées, mais il dépend du maintien de la même adresse de tunnel par le client. Un pool dynamique qui donne une autre adresse à l'ordinateur portable après une reconnexion pointe silencieusement la règle vers rien. Réservez d'abord l'adresse du tunnel, écrivez ensuite la règle, et traitez les deux comme un seul changement.

Si le service doit répondre à trois heures du matin sans personne pour regarder, la forme avec le port publié par le serveur a moins de pièces mobiles, car le seul processus qui doit rester en marche est le tunnel lui-même.

Condition deux : qui possède le pare-feu et les journaux

La forme inversée garde toute la politique à deux endroits. sshd décide si les redirections distantes sont autorisées du tout via AllowTcpForwarding, et GatewayPorts décide si l'écouteur se lie à la boucle locale ou à toutes les adresses. Avec la valeur par défaut no, un collègue hors du serveur ne peut pas atteindre le port même si la redirection a réussi, et cela ressemble à un tunnel cassé alors qu'il s'agit en réalité d'une adresse de liaison.

sudo ss -ltn '( sport = :8081 )'
sudo grep -E '^(GatewayPorts|AllowTcpForwarding)' /etc/ssh/sshd_config

La forme traduite nécessite le transfert activé et deux règles, et la seconde règle est là où la plupart des recettes se trompent. Limiter la traduction de source à l'état conntrack DNAT signifie que seules les connexions créées par la règle de destination sont réécrites, au lieu de chaque paquet que le serveur envoie dans le tunnel.

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8081 -j DNAT --to-destination 10.88.0.6:8080
sudo iptables -t nat -A POSTROUTING -o tun0 -m conntrack --ctstate DNAT -j SNAT --to-source 10.88.0.1

Cette réécriture détruit aussi l'attribution. Après elle, le client voit chaque appelant comme l'adresse du tunnel du serveur, ce qui réduit toute limite de débit par adresse à un seul seau et masque qui a envoyé quoi. Si l'attribution compte, terminez la connexion sur le serveur ou gardez-y la décision d'autorisation et transmettez une identité dans un en-tête auquel le service fait confiance. Choisir entre ces deux corrections dépend de si le service lit un en-tête de proxy.

Condition trois : un port ou plusieurs, et qui possède le nom

Un seul service sur un seul port est le cas où la redirection inversée l'emporte à l'effort. Il faut une commande, un compte et une règle de pare-feu, et le nettoyage consiste à tuer la session. Plusieurs services sur la même adresse publique vous poussent vers la forme publiée par le serveur, car chaque redirection inversée a besoin de son propre port serveur et l'ensemble grandit à chaque service.

Les noms compliquent encore. Une redirection inversée peut se trouver derrière un proxy TCP qui route selon le SNI, tandis qu'un port traduit est généralement un port par service. Si le service termine lui-même le TLS et a besoin du nom d'hôte d'origine, l'approche par proxy le préserve et l'approche DNAT ne le préserve que si le service accepte ce nom sur ce port.

Notez laquelle des trois conditions a décidé la forme. Sinon, la personne suivante qui ajoutera un second service rouvrira la même comparaison avec moins de contexte.

Décidez, puis testez depuis l'extérieur

Testez le chemin depuis un réseau qui n'a aucune route vers l'ordinateur portable, et observez les compteurs du serveur pendant que la requête s'exécute. Tester depuis le serveur vers sa propre adresse publique ne prouve rien ici, car le paquet est créé localement et n'atteint jamais le crochet de traduction entrant, donc le test peut réussir alors que le chemin réel est cassé.

sudo iptables -t nat -L PREROUTING -n -v
sudo tcpdump -ni any 'tcp port 8081' -c 20

Des compteurs qui restent plats signifient que le paquet n'a jamais atteint la règle, ce qui pointe vers le fournisseur ou le pare-feu de l'hôte. Des compteurs qui bougent alors que le service refuse pointent vers le pare-feu du client ou l'adresse sur laquelle le service écoute. Un tunnel qui transporte le paquet mais ne renvoie rien est un problème de route ou de chemin inverse, et aucun de ces trois résultats ne doit être débogué en modifiant l'adaptateur du client. Notez quel compteur a bougé avant de changer quoi que ce soit, car le test suivant a besoin de cette référence.

Une fois la forme fonctionnelle, consignez le port, le propriétaire et la méthode de supervision à côté de la configuration du tunnel. Un correctif d'accessibilité qui n'existe que dans l'historique de shell de quelqu'un est à un redémarrage d'un incident répété.

Articles similaires