Il vostro portatile è sulla VPN, dig service.internal.example risponde con un indirizzo 10.x e curl esce ancora con Could not resolve host. Il tunnel non è il problema: ha trasportato la query di dig senza lamentarsi. A cambiare è chi pone la domanda. dig invia una query a un server che nominate voi, mentre curl passa per la catena di risoluzione del sistema operativo, e quella catena ha regole proprie su quale server viene interrogato.

Due risoluzioni per lo stesso nome

dig è uno stub resolver a sé. Legge /etc/resolv.conf, sceglie un nameserver, invia una singola query A o AAAA e stampa la risposta. Salta del tutto nsswitch e non sa nulla dello stato per collegamento che systemd-resolved o NetworkManager tengono fuori da quel file, ed è per questo che una risposta di dig può essere corretta e non dirvi comunque nulla su ciò che vedrà la vostra applicazione.

Le applicazioni chiamano getaddrinfo, e getaddrinfo percorre una catena più lunga: l’ordine dei moduli di nsswitch, poi il modulo che gestisce il nome, poi il resolver costruito dalla configurazione di collegamento corrente. Su una macchina systemd la query va a 127.0.0.53 e systemd-resolved sceglie un server upstream per collegamento in base al dominio di routing associato all’interfaccia tun.

Due comandi separano questi livelli senza indovinare:

getent ahosts service.internal.example
resolvectl query service.internal.example

getent usa lo stesso percorso di curl, quindi un errore di getent accanto a un dig funzionante localizza il guasto nella politica di risoluzione e non nell’instradamento dei pacchetti. resolvectl query stampa anche l’interfaccia e l’upstream che ha fornito la risposta, e mostra così se ha vinto il collegamento del tunnel o quello fisico.

Leggere il resolver che l’applicazione usa davvero

/etc/resolv.conf viene generato sulla maggior parte dei desktop, e un client VPN ha tre modi per interagire con esso: anteporre un nameserver, sovrascrivere il file oppure passare i suoi server a NetworkManager lasciando che il demone lo riscriva. Solo il terzo schema conserva il DNS per collegamento, perché i server restano legati a un’interfaccia invece di essere appiattiti in un unico elenco globale.

Sui sistemi NetworkManager l’esito dipende dal backend in /etc/NetworkManager/NetworkManager.conf:

[main]
dns=systemd-resolved

Con dns=default i server del client vengono fusi in resolv.conf nell’ordine che vince, e una risoluzione privata può comunque essere inviata al resolver pubblico. Con un backend che capisce i collegamenti, systemd-resolved o dnsmasq, i server del tunnel restano limitati al tunnel e solo i nomi che corrispondono al suo dominio di routing vanno lì. Questa limitazione è ciò che significa split DNS in pratica, ed è il pezzo che manca più spesso quando un client dichiara di supportarlo.

Leggete lo stato prima di modificare qualcosa:

resolvectl status
resolvectl dns tun0

Volete vedere l’interfaccia tun elencata con un server DNS e un dominio di routing per il suffisso privato, mostrato come ~internal.example. Nessun server sul collegamento significa che il client non ha inviato nulla. Un server senza dominio significa che le risoluzioni vanno tutte lì o nessuna, a seconda del client, e nessuna delle due cose è split DNS.

Dove nsswitch chiude la risoluzione in anticipo

Una riga standard di desktop è così:

hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname

mdns4_minimal gestisce il DNS multicast e rivendica ogni nome che termina in .local. Un servizio Kubernetes come api.infra.svc.cluster.local termina anch’esso in .local. Quando il modulo mDNS riporta NOTFOUND, l’azione [NOTFOUND=return] termina l’intera risoluzione invece di proseguire verso il modulo dns, così il nome non viene mai inviato al resolver della VPN. dig aggira del tutto il file, ed è esattamente per questo che i due strumenti non concordano.

Questo è il contrasto più netto del problema, e si riduce a una parola in un file di configurazione più vecchio della vostra VPN. Cambiare l’azione in [NOTFOUND=continue] mantiene mDNS per stampanti e dispositivi locali lasciando che DNS veda il nome. Sostituire la riga con hosts: files dns funziona anch’esso ed è più brutale: elimina la risoluzione .local per la stampante che usate davvero.

Nomi che esistono in una sola rete

Le zone private fanno autorità in un solo posto. Un nome AWS come ip-10-0-4-31.eu-west-1.compute.internal viene risolto dal resolver della VPC di quella regione, e solo finché il vostro endpoint VPN si trova nella stessa regione della risorsa. Collegatevi a un endpoint di Francoforte, interrogate un nome compute.internal irlandese e nessuna impostazione locale aiuterà: la zona che detiene il record non è raggiungibile da lì.

I domini di ricerca producono l’immagine speculare. Un semplice service viene completato con il suffisso che il resolver ritiene applicabile, e con un collegamento VPN il dominio locale può prevalere su quello aziendale. Interrogate con un punto finale per togliere l’indovinello, getent ahosts service.internal.example., e se questo funziona mentre il nome breve no, la correzione è il dominio di ricerca sul tunnel, non l’indirizzo del server.

I client gestiti aggiungono un terzo livello sopra il resolver di sistema. Un profilo VPN Windows può portare una propria politica di risoluzione dei nomi, regole per app e una tabella NRPT che si applica anche a tunnel spento. Le applicazioni con una cache DNS propria, comuni nei runtime .NET e Java, conservano un errore obsoleto molto dopo che la catena è stata sistemata. I client Apple configurano lo split DNS tramite domini di corrispondenza nelle impostazioni DNS invece che tramite resolv.conf, e Chromium o Firefox in modalità DNS sicuro possono aggirare il resolver di sistema per i nomi pubblici. Il riferimento Microsoft sulla risoluzione dei nomi VPN descrive il lato Windows di questo livello di policy.

Decidere quale livello correggere

Andate dal sintomo al livello invece di provare correzioni in ordine:

SymptomWhat it meansCheck first
dig answers, getent failslookup chain, not the packet pathnsswitch line and resolvectl status
Timeout rather than NXDOMAINprivate resolver unreachable through the tunnelresolvectl dns tun0, route to that address
NXDOMAINan authority answered and does not know the namezone owner, endpoint region
FQDN works, short name failssearch suffix mismatchresolvectl domain on the tun link
getent works, app failsapp cache or its own resolverrestart the app, check secure DNS

Due righe portano quasi tutto il peso. Un timeout è un problema di raggiungibilità: il resolver privato non risponde attraverso il tunnel, quindi controllate la rotta verso il suo indirizzo e se il server DNS sul collegamento è quello che pensate. NXDOMAIN è un problema di autorità: qualcosa ha risposto e non conosce il nome, il che punta alla zona, alla regione o a un resolver che non avrebbe mai dovuto ricevere la query.

L’ultima riga è quella che sfugge perché entrambe le metà sembrano un successo. Un nome breve che si risolve diversamente dal FQDN è un disallineamento di suffisso, e riconnettere il tunnel non cambierà quale suffisso invia il client.

Catturate lo stato prima di modificare un file di configurazione, così potete dire se la modifica ha fatto qualcosa:

resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt

Eseguite i controlli in questo ordine e fermatevi al primo che fallisce. getent e resolvectl query devono concordare; se getent fallisce mentre dig risponde, restate nella catena di risoluzione e non toccate l’instradamento. resolvectl status deve mostrare un server DNS e un dominio di routing sull’interfaccia tun. nsswitch non deve tornare in anticipo su NOTFOUND per il suffisso che state provando. Il nome deve fare autorità nella rete a cui è collegato il vostro endpoint, provato con un punto finale. L’applicazione non deve tenere una cache propria né una sovrascrittura DNS sicura.

Correggete solo il primo livello che fallisce, poi rieseguite gli stessi comandi. Due modifiche insieme vi lasciano senza poter dire quale sia contata, e il guasto successivo riparte da zero.

Articoli correlati