Perché la risoluzione DNS su Linux è più complicata di quanto sembri
Chiunque amministri server Linux prima o poi si scontra con il fastidioso “Temporary failure in name resolution” o con un DNS che risolve alcuni domini e non altri. La causa quasi sempre non è il DNS in sé, ma la catena di componenti che sta tra un comando come curl e la vera query verso un nameserver: /etc/nsswitch.conf, /etc/resolv.conf, e — sulle distribuzioni moderne — systemd-resolved o NetworkManager che gestiscono tutto al posto nostro, spesso silenziosamente.
In questo articolo ricostruiamo l’intera catena di risoluzione dei nomi su Linux, i comandi giusti per ispezionarla e un metodo pratico per isolare il problema in pochi minuti, invece di procedere per tentativi.
L’ordine di risoluzione: nsswitch.conf
Il primo file da guardare non è resolv.conf, ma /etc/nsswitch.conf. La riga che interessa è quella che inizia con hosts:, tipicamente:
hosts: files dns myhostname
Questo significa che il sistema consulta prima /etc/hosts (voce files), poi il DNS, e infine risolve il proprio hostname locale. Se un dominio dovrebbe risolvere correttamente ma non lo fa, e in /etc/hosts c’è una voce residua o sbagliata, il DNS non c’entra affatto: la query non arriva nemmeno a un resolver.
Chi gestisce davvero /etc/resolv.conf
Sulle distribuzioni Linux di qualche anno fa, /etc/resolv.conf era un file statico che si editava a mano. Da Ubuntu 18.04 in poi, e su gran parte delle distribuzioni moderne (Fedora, molte immagini cloud di Debian/RHEL), quel file è generato dinamicamente — modificarlo a mano spesso non produce alcun effetto persistente, perché viene sovrascritto al prossimo evento di rete.
Il modo più veloce per capire chi ha il controllo è guardare cosa punta il file:
ls -la /etc/resolv.conf
- Se è un file regolare, probabilmente la configurazione è statica.
- Se è un symlink verso
/run/systemd/resolve/stub-resolv.conf, il sistema usa systemd-resolved. - Se punta a
/run/NetworkManager/resolv.conf, è NetworkManager a gestire il DNS.
Sapere quale dei due componenti è “al comando” evita l’errore più comune: editare resolv.conf a mano, vederlo funzionare per pochi secondi, e poi ritrovarsi la modifica cancellata al riavvio dell’interfaccia di rete.
Il formato di resolv.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
search example.com
options ndots:5
Alcuni dettagli spesso ignorati ma rilevanti in produzione:
nameserver— Linux ne considera al massimo tre; gli altri vengono ignorati.search— suffisso di dominio aggiunto automaticamente a hostname “corti” (senza punti o con pochi punti).options ndots:5— controlla quando un nome viene considerato “già qualificato” e quando invece riceve il suffisso disearch. È un parametro che in ambienti Kubernetes causa non pochi grattacapi, perché una query con pochi punti può generare fino a 5 lookup DNS prima di andare a buon fine.
systemd-resolved: il resolver locale che (quasi) nessuno vede
Sulla maggior parte delle distribuzioni moderne, le query DNS delle applicazioni non vanno direttamente a Internet: passano per un listener locale su 127.0.0.53:53, gestito da systemd-resolved, che si occupa di caching e — dove configurato — di DNSSEC. Lo strumento per interagirci è resolvectl.
# Stato completo per interfaccia
resolvectl status
# Query esplicita tramite systemd-resolved
resolvectl query esempio.it
# Svuotare la cache (utile dopo un cambio DNS o un test)
sudo resolvectl flush-caches
# Statistiche su cache hit/miss
resolvectl statistics
Per impostare server DNS validi per l’intero sistema, indipendentemente dall’interfaccia attiva, si edita /etc/systemd/resolved.conf:
[Resolve]
DNS=1.1.1.1 1.0.0.1
FallbackDNS=8.8.8.8 8.8.4.4
e si riavvia il servizio:
sudo systemctl restart systemd-resolved
dig, getent e la differenza che fa risparmiare ore di debug
Il tool principale per interrogare direttamente un server DNS è dig (pacchetto dnsutils su Debian/Ubuntu, bind-utils su Fedora/RHEL):
dig esempio.it
dig @8.8.8.8 esempio.it # interroga un resolver specifico
dig esempio.it MX # record di posta
dig esempio.it AAAA # IPv6
dig esempio.it NS # nameserver autoritativi
dig -x 104.21.1.1 # reverse lookup
dig +short esempio.it # output compatto
dig +trace esempio.it # ricostruisce l'intera catena, dai root server in giù
dig +dnssec esempio.it # verifica la firma DNSSEC
Il punto chiave, spesso sottovalutato: dig ignora completamente /etc/nsswitch.conf e /etc/hosts. Parla direttamente con un server DNS. Questo lo rende perfetto per isolare i problemi, ma pericoloso se usato come unico strumento diagnostico: dig può funzionare perfettamente mentre l’applicazione continua a fallire, perché il problema è nel percorso NSS (Name Service Switch), non nel DNS.
Per replicare esattamente quello che fa un’applicazione, si usa getent:
getent hosts esempio.it
Se dig funziona ma getent no, il problema non è di rete: è nella configurazione NSS, in /etc/hosts, o nel modulo myhostname. È una distinzione che vale la pena memorizzare, perché sposta immediatamente l’indagine nella direzione giusta.
Un metodo, non solo comandi: la checklist di troubleshooting
Di fronte a un errore di risoluzione, seguire un ordine preciso evita di girare a vuoto:
- Controllare che
/etc/resolv.confcontenga un nameserver valido e capire chi lo gestisce (ls -la). - Verificare che
/etc/nsswitch.confincludadnsnella rigahosts. - Testare un resolver pubblico direttamente:
dig @1.1.1.1 google.com. Se funziona, la rete verso l’esterno è a posto. - Testare il resolver locale:
dig google.com. Se qui fallisce ma il passo precedente no, il problema è nella configurazione locale (systemd-resolved, NetworkManager, o un resolver aziendale irraggiungibile). - Controllare lo stato del servizio:
systemctl status systemd-resolved. - Guardare gli assegnamenti DNS per interfaccia con
resolvectl status— particolarmente utile in scenari con VPN e split-DNS. - Svuotare la cache con
resolvectl flush-cachesse si sospettano record stale. - Confrontare
digegetent: se divergono, il problema è nel percorso NSS. - Per fallimenti persistenti e inspiegabili,
dig +tracericostruisce l’intera catena di delega dai root server fino all’autoritativo, rivelando problemi come delegazioni NS rotte o glue record mancanti.
Split-DNS e VPN: un caso che confonde molti
Con una VPN aziendale attiva, resolvectl status mostra a quale interfaccia è associato ciascun dominio DNS. Se il dominio associato al link VPN è ~., quell’interfaccia diventa la route DNS predefinita per tutte le query. Se invece è qualcosa come ~interna.azienda.it, solo le query per quel dominio specifico vengono instradate sul tunnel — le altre continuano a passare per il resolver pubblico. Non riconoscere questa differenza è una causa frequente di “il sito interno non si risolve, ma internet funziona” o viceversa.
Fissare un DNS statico senza che venga sovrascritto
Su sistemi gestiti da NetworkManager, il modo corretto non è editare resolv.conf ma dire a NetworkManager di non sovrascrivere le impostazioni manuali:
nmcli con mod "Wired connection 1" ipv4.dns "1.1.1.1 8.8.8.8"
nmcli con mod "Wired connection 1" ipv4.ignore-auto-dns yes
nmcli con up "Wired connection 1"
Su sistemi con systemd-resolved, la via pulita è impostare DNS= e FallbackDNS= in resolved.conf, come visto sopra. Solo come ultima risorsa — ad esempio su container minimali senza questi servizi — ha senso rendere resolv.conf immutabile:
sudo chattr +i /etc/resolv.conf # blocca il file
sudo chattr -i /etc/resolv.conf # sblocca per un aggiornamento futuro
Quale resolver scegliere
Per server in produzione, affidarsi al solo router di casa/ufficio è rischioso: se il router si blocca o si riavvia, cade anche la risoluzione DNS di tutti i servizi a valle. Tra i resolver pubblici più usati in ambito professionale: Cloudflare (1.1.1.1 / 1.0.0.1, orientato a bassa latenza e privacy), Google (8.8.8.8 / 8.8.4.4, rete anycast molto ridondata) e Quad9 (9.9.9.9, che filtra domini noti per malware già a livello di resolver).
Conclusione
La risoluzione DNS su Linux non è un singolo componente ma una catena — NSS, resolv.conf, systemd-resolved o NetworkManager, e infine il resolver remoto. La maggior parte dei problemi “misteriosi” si risolve rapidamente se si segue la catena nell’ordine giusto invece di riavviare servizi a caso. Tenere a mente la differenza tra dig (parla direttamente col DNS) e getent (replica il percorso reale delle applicazioni) è probabilmente il singolo accorgimento che fa risparmiare più tempo in debug.
Fonte: Linux Nameservers and DNS Resolution — LinuxBlog.io