Jeg begynte utenfra, slik en bruker ville gjort: skrev navnet i nettleseren på telefonen over mobildata og så tilkoblingen henge til den timet ut. Navnet ble slått opp, så DNS var i orden. Heller ikke hjemmeruterens port-forward-side førte noe sted, for WAN-adressen var 100.64.31.42, og det er ikke en adresse en tilbyder ruter til meg fra internettet. Tallet forklarer hele feilen: linjen ligger bak carrier-grade NAT, så den offentlige adressen på min side av tunnelen tilhører tilbyderen. Det som følger, er veien jeg gikk fra den hengende fanen til en tjeneste som svarer.

Start hos klienten og arbeid innover

Før du endrer noen regel, må du bevise hvor kjeden stopper. På laptopen kjørte jeg dig +short files.example.net og fikk VPS-adressen tilbake, noe som utelukket gammel DNS på maskinen min. Deretter timet curl -v --connect-timeout 5 files.example.net:5022 ut i stedet for å bli avvist. Den forskjellen betyr noe: en timeout betyr vanligvis at pakker blir droppet underveis, mens en avvisning betyr at noe svarte og sa nei.

Neste hopp innover var VPS-en selv. ss -ltnp viste ingenting som lyttet på 5022, noe som var ventet før DNAT-regelen fantes. På samme maskin bekreftet wg show (eller ip -br a show tun0 for OpenVPN) at hjemme-peeren var oppe med en fersk handshake. Er peeren nede, hjelper ingen NAT-regel, og det grønne lyset på hjemmeruterens VPN-side betyr ingenting.

Bekreft at hjemmelinjen virkelig ligger bak CGNAT

Sammenlign adressen ruteren rapporterer på WAN-grensesnittet med det en ekstern tjeneste ser. Alt i 100.64.0.0/10, altså 100.64.x.x til 100.127.x.x, er delt adresseområde fra RFC 6598 og kan ikke nås fra internettet. Du kommer til samme konklusjon når ruteren påstår en vanlig privat adresse og et offentlig oppslag gir noe urelatert. En CGNAT-linje kan også komme med en offentlig adresse som bare varer til neste lease, slik at en port forward ser ut til å virke i en time og deretter stille dør.

Noen tilbydere deler faktisk ut en ekte offentlig adresse, men blokkerer innkommende 80 og 443 på privatabonnementer. Er tjenesten din bare web og WAN-adressen virkelig offentlig, spør supporten før du bygger en relay. Er den ikke det, gjelder designet nedenfor for hver port like mye, og det er verdt å stoppe eksperimentet på ruteren: translatoren i tilbyderens nett avslutter tilkoblingen før den noen gang når WAN-grensesnittet ditt.

Pek navnet mot VPS-adressen

DNS videresender ikke trafikk, så A-recorden for tjenesten må inneholde VPS-ens offentlige adresse. En A-record mot 192.168.1.20 slås bare nyttig opp for klienter som allerede er inne i VPN-en; fra internettet slås den opp til en adresse ingen kan rute. For VPS-ens egen admin-tilgang holder jeg et eget navn, slik at jeg aldri blander sammen hvilken vert en record peker på.

Hvis både VPS-en og hjemmeboksen serverer HTTP, gi hver sin eget navn og la VPS-en avgjøre hvem som svarer. Å folde dem sammen til ett navn og håpe at proxyen velger riktig backend, er nettopp slik du feilsøker feil vert en hel ettermiddag.

DNAT én port, la SSH bli på 22

Det direkte alternativet er destination NAT på VPS-en. Slå på forwarding for kjernen som kjører, og hold hjemmeserverens tunneladresse i regelen, ikke LAN-adressen:

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

La SSH til VPS-en selv bli på 22 og forward en annen port, for eksempel 5022, til hjemmemaskinen. Forwarder du 22 til en boks som er nede, mister du den eneste veien som kunne ha rettet det. Samme logikk gjelder proxyen: hold VPS-ens administrasjonsport utenfor relay-reglene.

Gjør reglene varige når de virker. På Debian eller Ubuntu skriver apt install iptables-persistent og deretter netfilter-persistent save dem til /etc/iptables/rules.v4. På en firewalld-vert er motstykket en permanent forward-port på sonen, som trenger firewall-cmd --reload før den gjelder. Regler som bare lever i minnet, forsvinner ved tilbyderens første vedlikeholdsreboot, vanligvis på et dårlig tidspunkt.

Fiks returveien, eller slippe å trenge den

DNAT skriver bare om målet. Hjemmeserveren ser en tilkobling fra den opprinnelige klientadressen, og hvis standardruten peker på hjemmeruteren, forlater svaret huset via WAN-et der tilbyderens translator dropper det. Den asymmetrien var den andre feilen jeg traff, etter at DNAT-regelen så helt korrekt ut.

To rettelser virker. Gi hjemmeboksen en policy-rute slik at trafikk fra tunnelen går tilbake gjennom tunnelen:

ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100

Eller la VPS-en skrive om kilden slik at svaret har en adresse den kan nå, og la conntrack snu det tilbake på vei 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 klientadressen for hjemmeserveren, så applikasjonsloggene viser 10.8.0.1 som peer. Send originaladressen videre på applikasjonslaget, eller godta at logging per klient går tapt, men bestem det bevisst i stedet for å oppdage det under en hendelse.

Sjekk hele veien utenfra

Verifiser fra et nett som verken er VPS-en eller huset: en telefon på mobildata, eller et billig shell et annet sted. nc -vz files.example.net 5022 bør rapportere en vellykket tilkobling, og openssl s_client -connect files.example.net:443 -servername files.example.net bør vise sertifikatet for det offentlige navnet. Sjekk deretter tilbyderens security group eller skybrannmur. En DNAT-regel som aldri ser en pakke, blokkeres vanligvis ett lag over verten.

Til slutt: bestem hva som skjer når tunnelen faller. En DNAT-regel fortsetter å ta imot tilkoblinger og fører dem stille inn i en død tunnel, noe som ser nøyaktig ut som en ødelagt tjeneste. En health check på VPS-en som avviser porten mens peeren er nede, koster noen linjer og sparer en time med gjetting. Slutt så å redigere regler og se på det i et døgn før du stoler på det.

Relaterte artikler