Varför privata DNS-namn misslyckas på VPN-klienter och var du ska leta
Privata namn löses bara upp när klienten litar på din resolver, suffixet är avgränsat och svaret kan färdas tillbaka genom tunneln.
Du öppnar en bärbar dator på ett hotellrum, startar klienten, skriver namnet på den interna filservern och får ingenting tillbaka. Tunneln rapporterar ansluten, och en ping till en adress i samma subnät svarar fortfarande, så transporten i sig är okej. Bara namnet misslyckas, och den luckan snävar in problemet till två ställen: vilken resolver klienten frågade, och om svaret den fick kan färdas tillbaka genom tunneln. Få det ena rätt och hoppa över det andra, och felet flyttar sig bara.
Innan du redigerar någon profil, bekräfta vad klienten gör med namnet. På Linux visar resolvectl query files.corp.example vilken länk och vilken resolver som gav svaret. På Windows visar Resolve-DnsName files.corp.example vilken server som svarade och vilken adress den returnerade.
Läs svaret innan du ändrar något
Kommer namnet tillbaka som NXDOMAIN på några millisekunder nådde frågan aldrig din zon, och någon offentlig eller hotellresolver svarade i stället. Kommer det tillbaka efter en lång paus tappar något UDP-port 53 på vägen, och klienten föll till slut tillbaka. Svarar den med rätt adress men anslutningen hackar ändå är uppslaget okej, och problemet är routning eller tjänsten själv.
Den tredelningen sparar en timme av gissningar. Den berättar också om du alls ska röra VPN:et: ett namn som löses upp till rätt privata adress har redan bevisat resolvervägen, så arbetet som återstår ligger på datavägen.
Dela ut resolvern inifrån tunneln
Klienter faller i två grupper. Den ena gruppen kan få en resolver av servern under anslutningsuppsättningen; den andra har inställningen i en lokal fil som ingen gateway kan ändra på distans.
OpenVPN tillhör den första gruppen. På servern färdas push "dhcp-option DNS 10.8.0.53" och push "dhcp-option DOMAIN corp.example" ned genom kontrollkanalen, men bara om klientkonfigurationen fortfarande har pull aktiverat. En handredigerad klient med pull-filter ignore "dhcp-option" ser dem aldrig, och den enda raden förklarar förvånansvärt många fall av »servern pushar det men min bärbara tycker annat«.
WireGuard tillhör den andra gruppen, eftersom protokollet inte har någon optionsförhandling alls. Resolvern och sökdomänen går in i klientens eget [Interface]-block som DNS = 10.8.0.53, corp.example. wg-quick tillämpar det via resolvconf eller systemd-resolved, och på Windows installerar den officiella klienten NRPT-regler som bara finns medan tunneln är uppe – Get-DnsClientNrptPolicy listar dem, vilket gör det till ett snabbt sätt att se om klienten någonsin tillämpade din fil.
IPsec/IKEv2 ligger däremellan. strongSwans attr-plugin kan returnera en DNS-server hämtad ur en pool, och en Windows-klient accepterar normalt det, men en profil som låser sin egen namnserver vinner över vad gatewayen än erbjuder. På en Linux-klient är motsvarande manuella steg resolvectl dns wg0 10.8.0.53 följt av resolvectl domain wg0 '~corp.example'; båda försvinner när gränssnittet gör det, vilket är precis vad du vill ha för en tunnelavgränsad inställning.
Avgränsa suffixet i stället för att svälja varje fråga
Att peka klientens hela resolverlista mot din interna server är enkelt och oftast fel. Då löses varje offentligt namn upp från ditt datacenters utgång, så CDN:er lämnar tillbaka avlägsna adresser, och ett enda resolveravbrott tar användarens surfande med sig.
Skicka bara det privata suffixet inåt. På systemd-resolved är en domän som börjar med ~ enbart routning, så ~corp.example betyder att frågor under det suffixet går till den länkens servrar medan allt annat fortsätter använda det fysiska nätet. Windows gör samma sak med NRPT-regler avgränsade till en namnrymd, och macOS med en kompletterande resolverfil under /etc/resolver/.
Multicastnamn förtjänar ett eget svar. .local-namn är link-local av konstruktion (RFC 6762) och ett punkt-till-punkt-tun-gränssnitt bär inte den multicastgruppen, så en extra offentlig resolver publicerar dem inte, och frågar man en intern unicastresolver får man NXDOMAIN tillbaka. En reflektor som avahi i reflektorläge kan bygga bro mellan två segment, men det är ett beslut på serversidan som ingen klient kan begära. Måste en skrivare eller NAS nås på namn, ge den då en A-post i din zon i stället.
Bevisa att svaret kan färdas tillbaka
Ett korrekt svar som pekar på en onåbar adress ser precis ut som ett resolverproblem tills du kontrollerar rutten. Fråga kärnan vart svaret skulle ta vägen: ip route get 10.20.5.20 namnger gränssnittet och, mer användbart, källadressen den skulle använda.
Håll koll på resolveradressen själv. En klient med DNS = 10.8.0.53 bredvid AllowedIPs = 10.20.0.0/16 skickar sina frågor ut genom det fysiska nätverkskortet, där de dör tyst, eftersom resolvern inte ligger inom något prefix som tunneln gör anspråk på. Den missanpassningen är det vanligaste enskilda felet i hela det här området, och den är osynlig om du inte jämför DNS-inställningen med de tillåtna prefixen rad för rad.
Överlappande intervall ger det omvända felet. Svaret är rätt, rutten finns, och den pekar på fel värd, eftersom 192.168.0.0/24 hemma är mer specifik än tunnels rutten till samma intervall. Numrera om ena sidan eller pusha en snävare rutt, och bekräfta sedan tjänstevärden brandvägg och returväg; strongSwans anteckningar om vidarebefordran täcker sysctl-sidan av den vägen.
Certifikat är en separat identitetskontroll som folk skyller på DNS. Rapporterar webbläsaren ett namnmissförhållande i stället för ett uppslagsfel har uppslaget redan fungerat, och det är SAN i certifikatet som behöver fixas. Testa HTTPS mot namnet, aldrig mot den nakna IP-adressen.
Testa om från klienten, inte från gatewayen
Testa inne i programmet som användaren klagar på, för ett uppslag på kommandoraden bevisar inte att webbläsaren tar samma väg. Chromes säkra DNS och Firefox network.trr.mode kan kringgå systemresolvern helt, och när de gör det misslyckas ett privat namn eller läcker till en offentlig resolver. Att jämföra resolvectl query med en handkörd dig @10.8.0.53 files.corp.example berättar vilket av de två som hände.
Koppla sedan från och återanslut innan du kallar det löst. Inställningar som satts för hand på ett gränssnitt försvinner med gränssnittet, och en profil som bara såg rätt ut på grund av en kvarglömd lokal ändring fallerar vid nästa start.
En kort checklista för nästa maskin: namnet löses upp genom tunnels resolver, suffixet är avgränsat i stället för globalt, resolveradressen ligger inom de tillåtna prefixen, värden i svaret svarar på tjänsteporten, och certifikatet täcker namnet användaren skrev.