Namen lossen niet meer op op het moment dat de VPN verbindt, terwijl een ping naar een openbaar adres nog wel antwoordt en de firewallstatus niets laat zien dat verkeerd lijkt. Aan het beleid is niets veranderd; wat veranderd is, is dat er een nieuwe interface verscheen, en de standaardweigering dekt die vanaf het eerste pakket. UFW beslist op richting en interface, dus een regel die voor de draadloze verbinding is geschreven zegt niets over verkeer dat de tunnel verlaat. De reparatie is een handvol smalle regels, in een bepaalde volgorde toegepast.

Het symptoom verschijnt pas als de tunnel staat

Een standaardweigeringsbeleid doet precies wat ervan gevraagd is: alles zonder passende regel wordt geweigerd, op elke interface die bestaat. De tunnel bestond niet toen de regels werden geschreven, dus geen ervan kan hem raken, en de weigering die er altijd was, geldt nu voor naamresolutie. Direct verkeer naar een letterlijk adres kan nog werken wanneer een bredere toestemming het dekt, en daarom lukt een ping naar een openbare resolver terwijl een naam opzoeken mislukt. Het gat is een regel voor een interface die het beleid nooit heeft gezien.

Dat verklaart ook waarom de storing zich netjes omkeert: haal de tunnel weg en namen lossen weer op, omdat de query terugkeert naar een interface die wel regels heeft. Een beleid dat alleen faalt zolang de tunnel staat is geen DNS-probleem, en de resolver zelf bijstellen kost hier de meeste tijd. Lees de interfacelijst voordat je de resolverconfiguratie leest.

Drie richtingen, drie verschillende regelsets

Eén sessie raakt regels in meer dan één richting, en een tunnel voegt aan bijna elk daarvan een tweede interface toe. Het verkeer eerst op richting en interface sorteren maakt de rest mechanisch, want elke regel hieronder heeft zijn eigen regel op zijn eigen plek nodig. De voorbeelden gebruiken tun0 en een pool van 10.8.0.0/24, dus vervang de namen en bereiken door die uit de eigen uitvoer van de client.

DirectionExample packetRule that admits itWritten on
Client to the pushed resolverA DNS query to 10.8.0.1Destination port 53 over the tunnelThe client's tun0
Client to the VPN serverA handshake to the server's public addressServer address and port on the physical linkThe client's physical interface
Server to a serviceSSH from the pool to port 22Source pool, destination port, tunnel interfaceThe server's tun0
Anyone to the listenerThe VPN listener itself1194/udp on the public sideThe server's public interface

Twee regels worden vaak verward omdat beide de tunnel noemen. Een regel voor de resolver staat verkeer toe dat de client de tunnel in stuurt, terwijl een regel voor SSH verkeer toestaat dat de server daaruit ontvangt; ze leven op verschillende machines en falen onafhankelijk. De regel die het vaakst vergeten wordt is de tweede, omdat de client de tunnel helemaal niet kan opbouwen voordat zijn verkeer naar het openbare adres van de server is toegestaan. Werk van boven naar beneden en elke storing heeft één mogelijke oorzaak.

Een gepushte resolver heeft zijn eigen regel nodig

Of de tunnel DNS draagt hangt af van wat de server stuurt. Een server die een resolveroptie pusht, installeert een privéadres in de configuratie van de client, en dat adres is alleen via de tunnel routeerbaar. Als de server niets pusht, houdt de client de resolver die hij al had en de regels hieronder hebben niets toe te staan. Controleer de gepushte toestand en het huidige queryresultaat voordat je iets schrijft:

dig +short @10.8.0.1 example.com
resolvectl status tun0
sudo ufw status numbered

De statusuitvoer noemt de resolver die in gebruik is en de verbinding waaraan die is gebonden, en de routeopzoeking daarachter laat zien welke interface een query naar dat adres zou dragen. Wanneer de resolver op een andere verbinding zit, is het probleem eerder dan de firewall en geen regel zal helpen. Wanneer beide het over de tunnel eens zijn, zijn er twee regels nodig, omdat UDP de meeste queries draagt en TCP het overneemt wanneer een antwoord wordt afgekapt. Noteer beide waarden, want dat zijn degene die de regels zullen noemen:

sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto udp comment 'pushed resolver'
sudo ufw allow out on tun0 to 10.8.0.1 port 53 proto tcp comment 'truncated answers'

Open de buitenste weg vóór de binnenste

De client moet het openbare adres van de server bereiken voordat er een tunnel bestaat, dus de regel daarvoor zit op de fysieke verbinding en moet er eerst staan. Een beleid dat de resolver toestaat maar de server vergeet, laat de client helemaal niet in staat de tunnel te bouwen, en dat symptoom krijgt meestal de schuld van een kill switch. Sta daarna de diensten toe die je echt door de tunnel wilde, één smalle regel tegelijk, in plaats van de interface in zijn geheel open te zetten. De smalle regels zijn de reden dat de weigering kan blijven staan.

sudo ufw allow out to 198.51.100.10 port 1194 proto udp comment 'vpn server'
sudo ufw allow out on tun0 to any port 443 proto tcp comment 'web through tunnel'

De volgorde is belangrijk tijdens het testen, want de eerste regel is wat de tunnel überhaupt laat opkomen. Voeg die toe, maak verbinding en bevestig dat de tunnel staat voordat je de dienstenregel toevoegt, want beide tegelijk doen betekent dat een storing je niets zegt over welke helft fout is. Vervang het documentatieadres hierboven door het eindpunt waarvoor de client is geconfigureerd.

Rond de clientzijde af door met opzet te verbreken. De weigering zou het verkeer dat je bewust hebt uitgesloten nog steeds moeten weigeren, want een resolver die antwoordt terwijl de tunnel staat dekt maar de helft van een beleid dat bij twijfel weigert.

Een client die verbindt is nog niet toegelaten

De server heeft zijn eigen richting te overwegen, en een client die de handshake afrondt bereikt nog steeds niets dat op de server draait totdat de server hem toelaat. De regel voor de openbare listener laat de tunnel alleen bestaan; hij laat het verkeer van de tunnel niet binnen. Op de server zijn dat twee regels plus één controle dat de dienst echt luistert:

sudo ufw allow 1194/udp comment 'openvpn listener'
sudo ufw limit in on tun0 from 10.8.0.0/24 to any port 22 proto tcp comment 'admin over tunnel'
ss -ltn | grep ':22'

De pool in de regel moet gelijk zijn aan het bereik dat de server toekent, en het tunnelnummer moet overeenkomen met wat de server heeft aangemaakt, want een regel voor een andere interface is niet te onderscheiden van geen regel. limit is bewust voor een administratieve poort, want het beperkt herhaalde verbindingen in plaats van ze onbeperkt toe te laten. De listenercontrole scheidt een gesloten poort van een weggegooid pakket, die er vanaf de client identiek uitzien. Genummerde regels zijn ook niet het hele beeld: de before-regels van UFW en elke met de hand geschreven nftables-regel matchen eerder en kunnen nog steeds een pakket weigeren dat de lijst lijkt toe te staan.

Gerelateerde artikelen