Je tunnel staat, de dienst luistert, en het LAN op kantoor krijgt nog steeds niets terug. Niemand heeft de VPN kapotgemaakt. Vanaf de LAN-kant bestaat het tunneladres van de laptop niet tot iets het LAN vertelt hoe het daar moet komen, en het antwoord moet terugkomen langs dezelfde weg waarlangs het verzoek naar buiten ging. Ik heb mensen drie keer een volkomen gezonde tunnel zien herbouwen voordat iemand naar de terugweg keek.

Niet de tunnel is kapot

Beide uiteinden zitten op privébereiken, wat het normale geval is en geen verkeerde configuratie. Een adres als 10.8.0.6 is echt binnen de tunnel en bestaat nergens anders, dus het LAN heeft geen reden om er iets heen te sturen. Controleer voordat je aan routering komt of de dienst überhaupt binnen de tunnel bereikbaar is: op de client laat ss -ltn zien of de luisteraar aan 127.0.0.1, aan de LAN-interface of aan het tunneladres bindt. Een daemon die alleen aan loopback bindt, antwoordt niemand behalve zichzelf, en geen route, DNAT of port-forwarding verandert dat.

Een proxy op poort 80 of 443 is een ander gereedschap met een andere zichtbaarheid. Hij verplaatst verzoeken, geen pakketten, dus het is de verkeerde laag voor een rauwe databaseverbinding, en er juist naar grijpen is hoe dit probleem drie gereedschappen diep eindigt voordat iemand iets meet.

Routevorm: vertel het LAN waar de pool is

Een statische route op de LAN-gateway is het schoonste antwoord als het LAN en de tunnelpool elkaar niet overlappen. Richt de pool op de machine die de tunnel beëindigt:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

Dat repareert maar één richting, en daarom lijken half afgemaakte versies van deze wijziging op vooruitgang. De tunnelkant heeft de bijpassende helft nodig, anders verlaat het antwoord de client via zijn eigen standaardroute en sterft onderweg:

push "route 192.168.1.0 255.255.255.0"

Voor een subnet dat achter één client zit in plaats van achter de server, heeft de server zowel een systeemroute als een iroute-vermelding in het bestand van die client onder client-config-dir nodig. Zonder iroute weet OpenVPN dat het prefix bestaat en heeft geen idee welke client het bezit: de pakketten komen aan en de daemon heeft niets om ze aan te koppelen.

Hier is de mythe die een naam verdient. Een route maakt een adres bereikbaar; ze maakt de andere kant niet bereid te antwoorden. Site-naar-site-peers leggen er nog een laag bovenop, omdat de externe gateway alleen bronnen binnen de prefixen van zijn beleid accepteert, en een laptop die uit een thuis-pool komt, zit daar niet in.

NAT-vorm: DNAT naar binnen, en de SNAT-regel die iedereen overslaat

Als je de LAN-gateway niet kunt aanraken, of precies één poort wilt publiceren, werkt vertaling op de VPN-host zonder enige route op het LAN. Publiceer de poort, stuur hem door en vertaal de bron op weg naar de tunnel:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

De derde regel is degene die ontbreekt. Sla hem over en de client ziet het oorspronkelijke LAN-adres als bron, antwoordt via zijn eigen standaardroute, en dat antwoord gaat de tunnel in in plaats van terug naar het LAN. Of de verbinding overleeft, hangt dan af van routering die je nooit had gepland. Met SNAT ziet de client het tunneladres van de server, dus het antwoord volgt de tunnel terug naar de enige host die de vertaling kan terugdraaien.

Consumentenfirmware gebruikt zijn eigen kettingnamen en genereert die vertaling niet voor je. Op Tomato belandt een inkomende regel in WANPREROUTING en daarna in een filterketen zoals wanin, en een regelset die compleet lijkt heeft nog steeds een handmatige POSTROUTING-regel nodig. Dat is geen firmwarebug; het is een regelset die alleen voor inkomend verkeer is geschreven.

Waarom een correct uitziende regel het pakket toch laat vallen

De meeste van deze fouten zitten niet in de regel waar je naar staart. Controleer vier dingen in deze volgorde, en stop bij het eerste dat niet klopt:

  • Kettingvolgorde. iptables -I voegt bovenaan in en -A voegt onderaan toe, dus een eerdere toestemmende of blokkerende regel beslist eerst.
  • Verkeerde ketting. Verkeer dat aan de router zelf is gericht, gaat door INPUT, en doorgestuurd verkeer raakt die nooit aan. Eén dienst publiceren kan regels in beide vereisen.
  • Richtingsvlaggen. -i tun0 komt overeen met verkeer dat van clients komt en -o tun0 met verkeer dat naar hen toe gaat. Een REJECT met de verkeerde vlag blokkeert iets wat je niet bedoelde.
  • Bronbeperking. Een doorsturing die één clientadres accepteert, werkt vanaf die client en laat elke andere bron zonder een woord vallen.

Een regel met een pakketten-teller op nul staat helemaal niet op het pad, en de tellers lezen is de snelste manier om een verkeerde-ketting-probleem van een verkeerde-regel-probleem te scheiden.

De lokale doorsturing, als niets op het LAN kan veranderen

Een lokale SSH-doorsturing omzeilt de hele vraag. Hij heeft geen route op het LAN nodig, geen medewerking van de firewall van de client, en geen poort die ergens is gepubliceerd:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

De dienst verschijnt dan op localhost:3000 van de machine die de tunnel draait, en nergens anders. Dat is de grens: één werkstation, één poort, en de doorsturing sterft met de sessie tenzij iets hem herstart. Voor een beheerder die een staging-database controleert is het het juiste gereedschap. Voor een camera of een scanner die andere mensen moeten bereiken niet, omdat elke gebruiker zijn eigen doorsturing nodig zou hebben.

Controleer beide richtingen voordat je een regel toevoegt

Vertaling laat sporen na, en die lezen is beter dan gissen. Op de VPN-host laat conntrack -L zien of de vertaling überhaupt plaatsvond, iptables -t nat -L -n -v laat zien of de tellers bewogen, en tcpdump -ni any port 3000 laat zien welk bronadres werkelijk aankwam. Op de client bevestigt ss -ltn dat de luisteraar op een adres staat dat de tunnel kan bereiken.

Kies dan de vorm die je houdt. Eén gepubliceerde poort, een route voor de hele pool en een doorsturing voor één beheerder zijn drie verschillende verplichtingen, en ze door elkaar halen is hoe een werkende opstelling er een wordt die niemand zes maanden later kan uitleggen. Schrijf op welk adres van waar bereikbaar is, en de volgende persoon die dit debugt begint bij het antwoord in plaats van bij de tunnel.

Gerelateerde artikelen