VPN-clients verbinden maar hebben geen internet: drie ontbrekende delen
Een tunnel die ping beantwoordt, heeft nog steeds doorsturen, vertaling en een doorstuurregel nodig. Zoek uit welk van de drie ontbreekt voordat je de client opnieuw bewerkt.
De client krijgt een adres, de server beantwoordt pings, en elke pagina loopt toch vast in een time-out. De meeste mensen beginnen op dit punt het clientprofiel te bewerken, wat meestal verspilde moeite is: zodra de tunnel staat, moet de server zich als een router gedragen. Drie voorwaarden moeten tegelijk gelden voordat een pakket naar buiten gaat en een antwoord terugkomt, en het symptoom is identiek, welke ook ontbreekt.
Waarom een werkende tunnel toch geen uitweg heeft
De kernel moet pakketten tussen interfaces doorsturen, wat op de meeste Linux-distributies standaard uit staat. Het verkeer moet worden vertaald naar een adres dat de buitenwereld kan beantwoorden, tenzij elke upstream-router de terugroute naar het tunnelsubnet al kent. Het doorstuurpad van de firewall moet het verkeer in beide richtingen toestaan, inclusief de antwoorden.
Elk daarvan is afzonderlijk te repareren, en dat is de valkuil. Doorsturen aanzetten zonder vertaalregel laat pakketten vertrekken met een privébron en zonder terugweg. Vertaling toevoegen zonder doorstuurregel laat de kernel het pakket een stap later laten vallen.
Test dus de drie lagen in plaats van de client, en verander er één tegelijk zodat het resultaat iets betekent.
Doorsturen is een kernschakelaar die je blijvend moet maken
Controleer de huidige waarde voordat je die wijzigt, stel hem dan in en bevestig dat de wijziging is doorgevoerd.
sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
sysctl net.ipv4.ip_forwardHet eerste commando meldt de huidige waarde, het tweede stelt die in tijdens runtime, en het derde bewijst dat het schrijven werkte. De runtime-waarde verdwijnt bij de volgende herstart, waardoor een werkende sessie na onderhoud kan breken zonder enige configuratiewijziging.
Maak het blijvend in een bestand onder /etc/sysctl.d/, en pas dat bestand dan toe in plaats van te herstarten om het uit te zoeken. Op FreeBSD is het equivalent net.inet.ip.forwarding, met gateway_enable=YES in rc.conf voor blijvendheid. Een apparaat dat doorsturen als uitgeschakeld meldt, verklaart een hele klasse meldingen „pakketten komen aan en er komt niets terug”. Controleer de instelling ook na elke upgrade, want een herbouwde kernel of een vervangen apparaatimage kan die terugzetten zonder het iemand te vertellen.
Kies masquerade of één vast vertaaladres
Met een dynamisch buitenadres is masquerading de eenvoudigste juiste vorm. Noem het tunnelsubnet als bron en de buiteninterface als uitgang.
iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -o eth0 -j MASQUERADEMet een statisch openbaar adres is brontranslatie naar precies dat adres voorspelbaarder en makkelijker te controleren.
iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -j SNAT --to-source 198.51.100.10De tweede vorm draagt een onderhoudsvalkuil: een hardgecodeerd adres dat later verandert, houdt de tunnel aan de praat terwijl internettoegang stil stopt. Gebruik masquerade of werk de regel bij telkens wanneer de provider je verplaatst. De interface is ook belangrijk, want een router die zijn eigen upstream-tunnel deelt moet via die tunnel vertalen en niet via de fysieke WAN.
De filtertabel is de derde poort
Doorsturen en vertaling kunnen beide correct zijn terwijl het pakket alsnog sterft in de filtertabel. ufw is een veelvoorkomende boosdoener: het doorstuurbeleid wordt als DROP geleverd, en de rest van de opzet kan er volkomen correct uitzien terwijl die ene instelling het verkeer doodt. Die verhogen is een bewuste beveiligingsbeslissing en geen selectievakje.
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTDe eerste regel staat nieuw verkeer van de tunnel naar buiten toe, en de tweede alleen antwoorden terug. Vernauw beide tot het tunnelsubnet en de bedoelde bestemming, want een algemene toestemming op de tunnelinterface maakt de VPN een open uitgangspunt voor iedereen die kan authenticeren.
Een gebrugde tunnel vraagt een ander antwoord. Het adres hoort bij de bridge, niet bij de fysieke poort, dus het slaaf maken van de interface verwijdert het adres dat die eerder had en de host lijkt onbereikbaar tot de bridge zelf er een krijgt, wat dhclient br0 kan leveren. Die fout lijkt op een VPN-probleem en is een probleem op laag twee. Controleer het eigen adres van de bridge voordat je de firewall aanraakt, want een filterwijziging kan een host niet repareren die geen adres meer heeft om van te verzenden.
Waar je moet kijken als een pagina nooit laadt
Ping het tunneladres van de server om te bewijzen dat de tunnel bestaat. Voer dan een traceroute uit van de client naar een openbaar adres en lees waar die stopt: bij de server komt het pakket aan maar wordt het niet doorgestuurd of vertaald; voorbij de server zit het probleem upstream en buiten je handen.
ping -c 3 10.9.0.1
traceroute -n 198.51.100.10Het eerste commando bewijst dat de tunnel verkeer naar de server zelf draagt, en het tweede laat zien hoe ver een pakket naar buiten komt. Een spoor dat eindigt op het tunneladres wijst op doorsturen of vertaling op de server, terwijl een spoor dat een hop later stopt wijst op de provider of de terugroute van de upstream-router.
Let op de server op de buiteninterface terwijl een client een pagina laadt. Verkeer dat met een privébronadres naar buiten gaat, betekent dat vertaling ontbreekt, en helemaal geen antwoord betekent dat het doorstuurpad of de upstream-terugroute het laat vallen.
Als externe clients ook hosts op het LAN van de server moeten bereiken, onthoud dan dat het LAN een terugroute naar het tunnelsubnet nodig heeft. Dat is routing en geen vertaling, en het is de stap die het vaakst wordt vergeten nadat de internetroute eindelijk werkt.