Publiceer een VPN-clientpoort achter CGNAT: checklist
Een regel voor bestemmings-NAT alleen levert halfopen verbindingen op. Zet het tunneladres vast, vertaal beide kanten op en bevestig het antwoordpad voordat je test.
Zet een dienst op een laptop achter carrier-grade NAT, wijs die laptop via een VPN naar een VPS, en niemand buiten kan erbij. Je voegt een regel voor bestemmings-NAT toe op de VPS en krijgt iets ergers dan stilte: verbindingen openen en blijven dan hangen. Het antwoord ontbreekt niet, het vertrekt via de eigen standaardroute van de client, wat betekent dat de server het nooit ziet. Werk deze vijf controles op volgorde af en stop bij de eerste die niet klopt.
Bevestig dat de server überhaupt doorstuurt
Vink dit vakje aan voordat je één vertaling schrijft. Een DNAT-regel voor een pakket dat de kernel weigert door te sturen, wordt door de regelparser geaccepteerd en daarna door het doorstuurpad weggegooid, wat een time-out oplevert die op een firewallprobleem lijkt.
sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
Het instellen in een draaiende kernel is niet hetzelfde als het instellen over een herstart heen. Schrijf net.ipv4.ip_forward=1 in een bestand onder /etc/sysctl.d/, voer sysctl --system uit en lees de waarde daarna terug in plaats van te vertrouwen op dat het bestand is opgepakt. Een container die zijn eigen netwerknaamruimte beheert, heeft dezelfde waarde nodig binnen die ruimte, niet alleen op de host.
Als het teruglezen nog steeds nul is, stop hier. Niets verderop zal werken.
Zet het tunneladres vast voordat een regel ernaar verwijst
De pool deelt adressen uit in verbindingsvolgorde, dus een regel die voor de huur van vandaag is geschreven, kan volgende week stilletjes naar een andere client wijzen. Bind het adres aan de identiteit van het certificaat in plaats van aan de aankomstvolgorde.
client-config-dir /etc/openvpn/ccd
ifconfig-push 10.77.0.14 10.77.0.13
Dat paar is het clientuiteinde en het peeruiteinde van een punt-tot-punt-tunnel, waarbij de server op de common name van het certificaat is gesleuteld. Onder een subnet-topologie wordt de tweede waarde in plaats daarvan als netmasker gelezen, dus schrijf de vorm die bij de gebruikte topologie past. Verbind de client daarna opnieuw en lees het adres op de client zelf, want de kijk van de server op de pool is geen bewijs van wat de client heeft geconfigureerd.
Als het adres na een herverbinding verandert, stop. Een NAT-regel die een bewegend doel volgt, zal met tussenpozen falen en je niets leren.
Vertaal in beide richtingen
Bestemmingsvertaling stuurt het inkomende pakket naar de client. Bronvertaling is wat de client de server laat antwoorden in plaats van de oorspronkelijke afzender, en dat is de regel die mensen overslaan.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 29443 -j DNAT --to-destination 10.77.0.14:29443
iptables -t nat -A POSTROUTING -d 10.77.0.14 -p tcp --dport 29443 -j SNAT --to-source 10.77.0.13
Zonder de tweede regel antwoordt de client via zijn ISP-uplink, dus de externe peer ziet een bronadres waarmee hij nooit heeft gesproken, terwijl de server geen trackingvermelding voor het antwoord heeft. De buitenstaander ziet een handshake die half wordt afgerond, en dat is precies het symptoom dat mensen op jacht stuurt naar een firewallfout die er niet is.
Lees beide regels terug met iptables -t nat -S en bevestig dat de interfacenaam degene is die het publieke adres draagt. Op een host die al met nftables filtert, schrijf je de vertaling in een nftables-NAT-keten van de overeenkomende adresfamilie in plaats van gereedschap te mengen.
Laat de filtertabel door
De NAT-tabellen herschrijven headers; ze geven geen toestemming. Met een standaard-DROP-beleid heeft de doorgestuurde stroom zijn eigen acceptatie nodig, plus de retourrichting die de meeste beleidsregels al dekken met een established,related-regel.
iptables -A FORWARD -i eth0 -o tun0 -p tcp --dport 29443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Controleer het beleid van de FORWARD-keten voordat je iets toevoegt, want de volgorde van een vroege DROP bepaalt of je regel ooit wordt geraadpleegd. Op een host waarvan de filtering in nftables leeft, voeg je de equivalente regel toe aan de forward-hook van de inet-tabel en bevestig je dat de basisketen echt doorgestuurd verkeer ziet en niet alleen lokale invoer. Als een pakketteller op de nieuwe regel op nul blijft terwijl de NAT-tellers stijgen, wordt het pakket vóór je regel weggegooid. Dat is het signaal om de ketenvolgorde te lezen, niet om een tweede kopie van dezelfde regel toe te voegen.
Bewijs het vanaf een extern netwerk
Test vanaf een niet-verwant netwerk. Een probe vanaf een andere machine op hetzelfde LAN kan door hairpin-NAT-ondersteuning heen gaan en nooit het pad oefenen dat een externe client gebruikt, dus een groen resultaat daar bewijst het verkeerde.
tcpdump -ni any port 29443
conntrack -L | grep 29443
Voer de capture tegelijk op de server en op de client uit. De capture op de server laat zien of het vertaalde pakket richting de tunnel vertrekt; de capture op de client laat zien of het verzoek aankomt en waar het antwoord naartoe is geadresseerd. Een vertaalvermelding in conntrack -L bewijst dat de regel overeenkwam, en het ontbreken ervan bewijst dat het pakket de NAT-keten nooit heeft bereikt.
Portscanners zijn zwak bewijs. Ze melden de poort als gesloten tot de applicatie is gebonden en luistert, dus gebruik een echte verbinding naar de echte dienst. Als het eindelijk werkt, houd de blootstelling bij die ene poort: SSH of een beheerpaneel doorsturen omdat de eerste regel onhandig aanvoelde, is een veel grotere beslissing dan een dienst publiceren.