Prima controlla cosa hai
Esegui questi comandi sulla macchina che vuoi raggiungere, oppure guarda la pagina di stato del router:
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
Poi trova l'indirizzo WAN nella pagina di stato del router. Se è diverso da quello mostrato dal primo comando, il tuo provider ha un altro NAT davanti a te. Un indirizzo da 100.64.0.0 a 100.127.255.255 sul lato WAN è un forte segno di CGNAT, perché la RFC 6598 riserva quell'intervallo a questo scopo.
Le opzioni
| Richiede | Funziona dietro CGNAT | Limiti | |
|---|---|---|---|
| VPN o overlay | Software su entrambe le estremità. Un peer raggiungibile o un servizio di coordinamento | Sì | Il software va installato su ogni dispositivo da cui ti colleghi |
| Tunnel SSH inverso | Un server con indirizzo pubblico | Sì | Il server aggiuntivo trasporta il traffico |
| IPv6 | IPv6 globale sulla macchina e sulla rete da cui ti colleghi | Sì, se il provider dà IPv6 | Fallisce da reti solo IPv4. Il firewall deve consentirlo |
| Inoltro di porta sul router | Un IPv4 pubblico sul router e accesso alle sue impostazioni | No | La porta è aperta a internet. L'indirizzo può cambiare |
VPN o rete overlay
WireGuard
WireGuard è una VPN che gestisci tu. Dietro CGNAT, la macchina nascosta si collega in uscita a un peer che ha un indirizzo pubblico, e il keepalive mantiene aperta la mappatura NAT. La guida rapida di WireGuard suggerisce 25 secondi. Sulla macchina nascosta, /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
Sul peer con l'indirizzo pubblico:
[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
Crea le chiavi con wg genkey | tee priv | wg pubkey > pub, avvia ciascun lato con sudo wg-quick up wg0 e collegati con ssh user@10.0.0.2 dal peer. Su di esso la porta UDP 51820 deve essere aperta. Abbiamo eseguito questi due file tra container e il login SSH su 10.0.0.2 ha funzionato. Solo il peer ha bisogno di un indirizzo pubblico.
Tailscale
Tailscale è una rete overlay costruita su WireGuard, con un servizio di coordinamento ospitato e un account. Su Linux, secondo la sua documentazione:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Fai lo stesso sul tuo dispositivo e poi collegati con SSH all'indirizzo che assegna, che tailscale ip -4 mostra sulla macchina nascosta. Tailscale prova prima una connessione diretta tra i dispositivi, e il suo articolo sul NAT traversal dice che dietro CGNAT è più difficile. Quando i percorsi diretti falliscono, il traffico passa dai suoi relay DERP, cifrato da un capo all'altro.
Tunnel SSH inverso
Servono solo SSH e un server con indirizzo pubblico, come 203.0.113.10. Sulla macchina nascosta:
ssh -N -o ExitOnForwardFailure=yes -R 2222:localhost:22 user@203.0.113.10
Dal tuo portatile:
ssh -J user@203.0.113.10 -p 2222 hiddenuser@localhost
I dettagli sono in tunnel SSH inversi. Per riavviarlo automaticamente dopo una caduta e limitare la chiave che usa, vedi autossh e systemd.
L'opzione -J è spiegata in ProxyJump e jump host.
IPv6
Il CGNAT riguarda IPv4, e alcuni provider che lo usano assegnano anche indirizzi IPv6 globali. Se ip -6 addr show scope global ne mostra uno, prova da una rete che ha IPv6:
ssh user@2001:db8::10
Il router o il provider possono bloccare l'IPv6 in ingresso, quindi un timeout può significare che il firewall ha bisogno di una regola per la porta 22. Vedi Connection timed out. Anche la rete da cui ti colleghi deve avere IPv6, e alcune reti di uffici e hotel non ce l'hanno. Se il tuo indirizzo cambia, aiuta un nome DNS dinamico.
Inoltro di porta sul router
Funziona quando il router ha un vero indirizzo IPv4 pubblico. Nelle sue impostazioni, inoltra una porta TCP esterna alla porta 22 della macchina, poi collegati all'indirizzo pubblico del router:
ssh -p 2222 user@203.0.113.10
Dietro CGNAT non serve a nulla, perché l'indirizzo pubblico appartiene al tuo provider. Alcuni provider ti danno un IPv4 pubblico su richiesta, a volte a pagamento, quindi può valere la pena chiedere. Una porta aperta riceve inoltre continui tentativi di login da internet, quindi usa solo chiavi. Vedi come disattivare l'accesso con password e fail2ban.
Domande
Come capisco se sono dietro CGNAT?
Confronta l'indirizzo WAN del router con quello che vedono siti come ifconfig.me. Se sono diversi, o se l'indirizzo WAN è tra 100.64.0.0 e 100.127.255.255, il tuo provider usa il CGNAT.
Posso collegarmi in SSH a una macchina dietro CGNAT senza VPN?
Sì, con un tunnel SSH inverso verso un server con indirizzo pubblico. La macchina nascosta si collega in uscita e tu la raggiungi passando da quel server.
Il port forwarding del router funziona dietro CGNAT?
No. L'indirizzo pubblico è del provider, non del tuo router, quindi non c'è niente da inoltrare. Chiedi al provider un IPv4 pubblico o usa una delle altre soluzioni.
Fonti
- RFC 6598, spazio di indirizzi condiviso
- Guida rapida di WireGuard
- Install Tailscale on Linux
- How NAT traversal works, Tailscale
- ssh(1), manuale OpenBSD