Op bijna elke kleine OpenVPN-gateway duiken twee naamproblemen op. Je bereikt een verbonden laptop niet via de naam op het certificaat, en de diensten achter de tunnel hebben helemaal geen namen. Ze lijken één probleem en vragen tegenovergestelde behandeling, want het ene adres verschuift met elke sessie en het andere niet. Bepaal welk soort naam je toevoegt voordat je iets wijzigt.

Bepaal per naam, niet per gateway

De test is eenvoudig: verandert dit adres wanneer een client opnieuw verbindt? Zo ja, dan moet de naam uit de VPN-sessie worden gegenereerd. Zo nee, dan hoort hij in een statische vermelding die je kunt lezen en controleren.

Name kindSource of truthWhere it lives
Connected clientThe address OpenVPN just assignedGenerated hosts file, rewritten per session
Service behind the tunnelA fixed address you choseStatic address= drop-in
Anything with a certificate nameThe certificate, not the poolEither, but the name must match the certificate

Ze door elkaar halen is de gebruikelijke fout. Een dienst die in het gegenereerde bestand is vastgezet, verdwijnt de eerste keer dat het script het herschrijft, en een client die in een statische vermelding staat, wijst naar wie dat adres het laatst had. Beide fouten blijven onzichtbaar tot een naam naar de verkeerde machine wordt herleid. Dan gaat degene die het debugt ervan uit dat DNS kapot is en niet het bestand.

Het dynamische pad: learn-address en de pool

OpenVPN kent de toewijzing, dus laat het je die vertellen. Deze serveropties maken de toewijzing duurzaam en scriptbaar:

client-config-dir /etc/openvpn/ccd
ifconfig-pool-persist /etc/openvpn/ip-pool 60
script-security 2
learn-address /etc/openvpn/learn-address.sh

learn-address voert je script uit telkens wanneer een adres wordt toegevoegd, bijgewerkt of verwijderd, en geeft de bewerking, het adres en de common name door. Een minimaal script voegt één regel per client toe en verwijdert die bij verwijderen:

#!/bin/sh
HOSTS=/etc/openvpn/hosts.lan
case "$1" in
  add|update) echo "$2 $3" >> "$HOSTS" ;;
  delete)     sed -i "/^$2 /d" "$HOSTS" ;;
esac
kill -HUP $(cat /var/run/dnsmasq.pid)

Op een tun-apparaat is het tweede argument het tunneladres van de client, dus de regel is direct bruikbaar. Op een tap-apparaat geeft OpenVPN in plaats daarvan het MAC-adres van de client door, omdat een tap-segment ook andere protocollen dan IPv4 kan dragen, en dan moet je het adres in het poolbestand opzoeken op common name voordat je iets schrijft.

Wees duidelijk over wat het gegenereerde bestand is: een momentopname van wie er nu verbonden is. Namen verdwijnen bij verbreken, wat precies is wat je wilt voor laptops die tussen netwerken wisselen en precies wat je niet wilt voor een server die de hele nacht aan staat.

Het statische pad: address= en domeinuitbreiding

Wijs dnsmasq naar het gegenereerde bestand in plaats van het hosts-bestand van het systeem, en geef het een domein zodat korte namen uitbreiden naar volledig gekwalificeerde:

domain=corp.example
no-hosts
addn-hosts=/etc/openvpn/hosts.lan
listen-address=127.0.0.1,10.8.0.1
bind-interfaces

Met domain ingesteld antwoordt een regel als 10.8.0.6 alice zowel voor alice als voor alice.corp.example. Houd listen-address op de tunnelgateway en loopback, want een resolver die per ongeluk op de LAN-interface wordt gepubliceerd is een dienst die je niet van plan was aan te bieden.

Diensten die nooit uit de pool komen, krijgen hun eigen vermeldingen. Zet ze in een apart drop-in-bestand in de configuratiemap van de distributie, zodat een pakketupgrade ze niet kan overschrijven:

address=/files.corp.example/10.8.0.20
address=/db.corp.example/10.9.0.5

Geef de resolver door, anders gebeurt er niets

Een resolver die niemand bevraagt, verandert niets. De server moet hem aankondigen:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

Windows-clients passen beide opties zelf toe. De meeste Linux-clients niet: die hebben een ondersteunde resolverintegratie nodig, zoals de update-resolv-conf-hook van de distributie of de DNS-afhandeling van NetworkManager, of een handmatig zoekdomein en nameserver. Controleer de werkelijke resolver van de client in plaats van aan te nemen dat de push is opgevolgd, want een genegeerde push ziet er precies zo uit als een server die niet antwoordt.

Verifieer op drie lagen

Vraag eerst de server direct, dan een client, dan de toepassing:

dig +short @10.8.0.1 alice.corp.example
getent hosts files.corp.example

Als directe queries antwoorden en de toepassing niet, ligt de fout bij de overdracht aan de client en niet bij de zone. Als de naam wordt herleid en de verbinding nog steeds mislukt, is de naam in orde en is de route of de firewall het volgende dat je moet bekijken.

Schrijf de twee categorieën naast de configuratie: welke namen worden gegenereerd, welke zijn vastgezet en met welk certificaat elk moet overeenkomen. De volgende persoon die een server toevoegt, kopieert het eerste patroon dat hij vindt.

Gerelateerde artikelen