Publiser ein heimeserver via ein VPS når CGNAT blokkerer portar
Vegen frå nettlesar til heimeboks: prov at linja ligg bak CGNAT, peik DNS mot VPS-en, DNAT éin port, fiks returvegen og stadfest utanfrå.
Eg byrja utanfrå, slik ein brukar ville gjere det: skreiv namnet i nettlesaren på telefonen over mobildata og såg sambandet henge til det gjekk i timeout. Namnet vart løyst opp, så DNS var i orden. Heller ikkje port-forward-sida på heimerutaren førte nokon stad, for WAN-adressa var 100.64.31.42, og det er ikkje ei adresse ein tilbydar rutar til meg frå internettet. Talet forklarar heile feilen: linja ligg bak carrier-grade NAT, så den offentlege adressa på mi side av tunnelen høyrer til tilbydaren. Det som følgjer, er vegen eg gjekk frå den hengjande fanen til ei teneste som svarar.
Start hjå klienten og arbeid innover
Før du endrar noka regel, må du prova kvar kjeda stoppar. På laptopen køyrde eg dig +short files.example.net og fekk VPS-adressa attende, noko som utelukka gamal DNS på maskina mi. Deretter gjekk curl -v --connect-timeout 5 files.example.net:5022 i timeout i staden for å bli avvist. Den skilnaden tel: ein timeout tyder vanlegvis at pakkar blir slopne undervegs, medan ei avvising tyder at noko svara og sa nei.
Neste hopp innover var VPS-en sjølv. ss -ltnp viste ingenting som lytta på 5022, noko som var venta før DNAT-regelen fanst. På same maskina stadfesta wg show (eller ip -br a show tun0 for OpenVPN) at heime-peeren var oppe med ein fersk handshake. Er peeren nede, hjelper ingen NAT-regel, og det grøne lyset på VPN-sida til heimerutaren tyder ingenting.
Stadfest at heimelinja verkeleg ligg bak CGNAT
Samanlikn adressa rutaren rapporterer på WAN-grensesnittet med det ei ekstern teneste ser. Alt i 100.64.0.0/10, altså 100.64.x.x til 100.127.x.x, er delt adresseområde frå RFC 6598 og kan ikkje nåast frå internettet. Du kjem til same konklusjonen når rutaren påstår ei vanleg privat adresse og eit offentleg oppslag gir noko urelatert. Ei CGNAT-linje kan også kome med ei offentleg adresse som berre varer til neste lease, slik at ein port forward ser ut til å verke i ein time og deretter stille døyr.
Nokre tilbydarar deler faktisk ut ei ekte offentleg adresse, men blokkerer innkommande 80 og 443 på privatabonnement. Er tenesta di berre web og WAN-adressa verkeleg offentleg, spør supporten før du byggjer ein relay. Er ho ikkje det, gjeld designet nedanfor for kvar port like mykje, og det er verdt å stoppe eksperimentet på rutaren: translatoren i nettet til tilbydaren avsluttar sambandet før det nokosinne når WAN-grensesnittet ditt.
Peik namnet mot VPS-adressa
DNS videresender ikkje trafikk, så A-recorden for tenesta må innehalde den offentlege adressa til VPS-en. Ein A-record mot 192.168.1.20 blir berre nyttig løyst opp for klientar som alt er inne i VPN-en; frå internettet blir han løyst opp til ei adresse ingen kan rute. For admin-tilgangen til VPS-en sjølv held eg eit eige namn, slik at eg aldri blandar saman kva vert ein record peikar på.
Om både VPS-en og heimeboksen serverer HTTP, gi kvar sin eigen namn og lat VPS-en avgjere kven som svarar. Å folde dei saman til eitt namn og håpe at proxyen vel rett backend, er nettopp slik du feilsøkjer feil vert ein heil ettermiddag.
DNAT éin port, lat SSH bli på 22
Det direkte alternativet er destination NAT på VPS-en. Slå på forwarding for kjernen som køyrer, og hald tunneladressa til heimeserveren i regelen, ikkje LAN-adressa:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d 198.51.100.10 --dport 5022 -j DNAT --to-destination 10.8.0.2
Lat SSH til VPS-en sjølv bli på 22 og forward ein annan port, til dømes 5022, til heimemaskina. Forwardar du 22 til ein boks som er nede, mistar du den einaste vegen som kunne ha retta det. Same logikken gjeld proxyen: hald administrasjonsporten til VPS-en utanfor relay-reglane.
Gjer reglane varige når dei verkar. På Debian eller Ubuntu skriv apt install iptables-persistent og deretter netfilter-persistent save dei til /etc/iptables/rules.v4. På ein firewalld-vert er motstykket ein permanent forward-port på sona, som treng firewall-cmd --reload før han gjeld. Reglar som berre lever i minnet, forsvinn ved den første vedlikehaldsrebooten til tilbydaren, vanlegvis på eit dårleg tidspunkt.
Fiks returvegen, eller slepp å trenge han
DNAT skriv berre om målet. Heimeserveren ser eit samband frå den opphavlege klientadressa, og om standardruta peikar på heimerutaren, forlèt svaret huset via WAN-et der translatoren til tilbydaren droppar det. Den asymmetrien var den andre feilen eg traff, etter at DNAT-regelen såg heilt korrekt ut.
To rettingar verkar. Gi heimeboksen ei policy-rute slik at trafikk frå tunnelen går attende gjennom tunnelen:
ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100
Eller lat VPS-en skrive om kjelda slik at svaret har ei adresse han kan nå, og lat conntrack snu det attende på veg ut:
iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1
SNAT-varianten skjuler den ekte klientadressa for heimeserveren, så applikasjonsloggane viser 10.8.0.1 som peer. Send originaladressa vidare på applikasjonslaget, eller godta at logging per klient går tapt, men avgjer det medvite i staden for å oppdage det under ei hending.
Sjekk heile vegen utanfrå
Stadfest frå eit nett som korkje er VPS-en eller huset: ein telefon på mobildata, eller eit billig shell ein annan stad. nc -vz files.example.net 5022 bør rapportere eit vellukka samband, og openssl s_client -connect files.example.net:443 -servername files.example.net bør vise sertifikatet for det offentlege namnet. Sjekk deretter security group eller skybrannmur hjå tilbydaren. Ein DNAT-regel som aldri ser ein pakke, blir vanlegvis blokkert eitt lag over verten.
Til slutt: avgjer kva som skjer når tunnelen fell. Ein DNAT-regel held fram med å ta imot samband og fører dei stille inn i ein død tunnel, noko som ser nøyaktig ut som ei øydelagd teneste. Ein health check på VPS-en som avviser porten medan peeren er nede, kostar nokre linjer og sparar ein time med gjetting. Slutt så å redigere reglar og sjå på det i eit døgn før du stolar på det.