Vérifiez d'abord ce que vous avez
Lancez ceci sur la machine que vous voulez atteindre, ou regardez la page d'état de votre routeur :
curl -4 https://ifconfig.me # the public IPv4 others see
curl -6 https://ifconfig.me # the public IPv6, if you have one
ip -6 addr show scope global # IPv6 addresses on this machine
Cherchez ensuite l'adresse WAN sur la page d'état de votre routeur. Si elle diffère de ce qu'affiche la première commande, votre fournisseur place un autre NAT devant vous. Une adresse de 100.64.0.0 à 100.127.255.255 côté WAN est un fort indice de CGNAT, car la RFC 6598 réserve cette plage à cet usage.
Les options
| Nécessite | Marche derrière un CGNAT | Limites | |
|---|---|---|---|
| VPN ou overlay | Un logiciel aux deux extrémités. Un pair joignable ou un service de coordination | Oui | Le logiciel doit être installé sur chaque appareil depuis lequel vous vous connectez |
| Tunnel SSH inverse | Un serveur à adresse publique | Oui | Le serveur supplémentaire porte le trafic |
| IPv6 | IPv6 globale sur la machine, et sur le réseau d'où vous vous connectez | Oui, si le fournisseur donne l'IPv6 | Échoue depuis les réseaux IPv4 uniquement. Le pare-feu doit l'autoriser |
| Redirection de port du routeur | Une IPv4 publique sur le routeur, et l'accès à ses réglages | Non | Le port est ouvert sur internet. L'adresse peut changer |
VPN ou réseau overlay
WireGuard
WireGuard est un VPN que vous faites tourner vous-même. Derrière un CGNAT, la machine cachée se connecte vers un pair qui a une adresse publique, et le keepalive maintient ouverte la correspondance NAT. Le quick start de WireGuard suggère 25 secondes. Sur la machine cachée, /etc/wireguard/wg0.conf :
[Interface]
Address = 10.0.0.2/24
PrivateKey = HIDDEN_MACHINE_PRIVATE_KEY
[Peer]
PublicKey = PUBLIC_PEER_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25
Sur le pair à adresse publique :
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = PUBLIC_PEER_PRIVATE_KEY
[Peer]
PublicKey = HIDDEN_MACHINE_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Créez les clés avec wg genkey | tee priv | wg pubkey > pub, démarrez chaque côté avec sudo wg-quick up wg0, et connectez-vous avec ssh user@10.0.0.2 depuis le pair. L'UDP 51820 doit y être ouvert. Nous avons exécuté ces deux fichiers entre des conteneurs, et la connexion SSH via 10.0.0.2 a fonctionné. Seul le pair a besoin d'une adresse publique.
Tailscale
Tailscale est un réseau overlay construit sur WireGuard, avec un service de coordination hébergé et un compte. Sous Linux, d'après sa documentation :
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Faites de même sur votre propre appareil, puis connectez-vous en SSH à l'adresse qu'il attribue, que tailscale ip -4 affiche sur la machine cachée. Tailscale essaie d'abord une connexion directe entre les appareils, et son article sur la traversée de NAT dit que c'est plus difficile derrière un CGNAT. Quand les chemins directs échouent, le trafic passe par ses relais DERP, chiffré de bout en bout.
Tunnel SSH inverse
Il ne demande que SSH et un serveur à adresse publique, comme 203.0.113.10. Sur la machine cachée :
ssh -N -o ExitOnForwardFailure=yes -R 2222:localhost:22 user@203.0.113.10
Depuis votre portable :
ssh -J user@203.0.113.10 -p 2222 hiddenuser@localhost
Les détails sont dans les tunnels SSH inverses. Pour le relancer automatiquement après une coupure et restreindre la clé qu'il utilise, voir autossh et systemd.
L'option -J est expliquée dans ProxyJump et les serveurs de rebond.
IPv6
Le CGNAT concerne IPv4, et certains fournisseurs qui l'utilisent donnent aussi des adresses IPv6 globales. Si ip -6 addr show scope global en affiche une, essayez depuis un réseau qui a IPv6 :
ssh user@2001:db8::10
Le routeur ou le fournisseur peut bloquer l'IPv6 entrant : un délai dépassé peut donc signifier que le pare-feu a besoin d'une règle pour le port 22. Voir Connection timed out. Le réseau d'où vous vous connectez doit aussi avoir IPv6, ce qui n'est pas le cas de certains réseaux d'entreprise et d'hôtel. Si votre adresse change, un nom DNS dynamique aide.
Redirection de port du routeur
Cela marche quand le routeur a une vraie adresse IPv4 publique. Dans ses réglages, redirigez un port TCP extérieur vers le port 22 de la machine, puis connectez-vous à l'adresse publique du routeur :
ssh -p 2222 user@203.0.113.10
Derrière un CGNAT, cela ne sert à rien, car l'adresse publique appartient à votre fournisseur. Certains fournisseurs donnent une IPv4 publique sur demande, parfois contre paiement : cela peut valoir la peine de demander. Un port ouvert reçoit aussi en permanence des tentatives de connexion venues d'internet, n'utilisez donc que des clés. Voir comment désactiver la connexion par mot de passe et fail2ban.
Questions
Comment savoir si je suis derrière un CGNAT ?
Comparez l'adresse WAN de votre box avec celle que voient des sites comme ifconfig.me. Si elles diffèrent, ou si l'adresse WAN est entre 100.64.0.0 et 100.127.255.255, votre fournisseur utilise le CGNAT.
Puis-je me connecter en SSH à une machine derrière un CGNAT sans VPN ?
Oui, avec un tunnel SSH inverse vers un serveur qui a une adresse publique. La machine cachée se connecte vers l'extérieur, et vous la joignez par ce serveur.
La redirection de port du routeur marche-t-elle derrière un CGNAT ?
Non. L'adresse publique appartient au fournisseur, pas à votre routeur, il n'y a donc rien à rediriger. Demandez une IPv4 publique au fournisseur ou utilisez une autre solution.
Sources
- RFC 6598, espace d'adressage partagé
- WireGuard quick start
- Install Tailscale on Linux
- How NAT traversal works, Tailscale
- ssh(1), manuel OpenBSD