Qualche giorno fa mi sono imbattuto in un comportamento a dir poco bizzarro sulla mia macchina Ubuntu: digitando nel browser un domain name completamente a caso, tipo http://mememem.it/ o http://nxdomain1.it/ (il nome è voluto: NXDOMAIN è il codice DNS che indica “Non-eXistent Domain“, cioè un dominio che non esiste), mi ritrovavo puntualmente sulla home page del mio Apache locale.
Sommario
Controlli
Il primo sospetto è caduto sul file /etc/hosts, che avevo configurato con qualche entry personalizzata:
127.0.0.1 localhost 127.0.1.1 bombelli 127.0.0.1 organizer.test
Ma qui c’è un dettaglio tecnico che va chiarito subito: /etc/hosts non supporta wildcard. Può mappare singoli nomi esatti a un IP, non può intercettare “qualsiasi dominio non trovato” e reindirizzarlo altrove. Quindi il colpevole doveva essere altrove.
Primo controllo: è un proxy?
Un comportamento “catch-all” di questo tipo è tipico anche di un proxy HTTP mal configurato, quindi ho controllato le variabili d’ambiente e le impostazioni di sistema (GNOME/NetworkManager):
$ env | grep -i proxy $ gsettings get org.gnome.system.proxy mode 'none'
Nessun proxy attivo. Pista scartata.
Secondo controllo: il DNS risponde correttamente?
A questo punto ho interrogato direttamente il server DNS con dig, per vedere cosa risponde davvero:
$ dig mememem.it ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 17331 ;; AUTHORITY SECTION: it. 3600 IN SOA dns.nic.it. hostmaster.nic.it. ...
Il DNS risponde correttamente NXDOMAIN, con tanto di risposta autoritativa dal registro .it. Quindi il DNS “puro” funziona benissimo. Ma se il DNS dice che il dominio non esiste, perché il browser mi porta comunque su Apache locale?
Terzo controllo: cosa vede davvero il browser (curl -v)
Qui è arrivato l’indizio decisivo. Ho ripetuto la richiesta con curl -v, che a differenza di dig segue lo stesso percorso di risoluzione usato dal browser (tramite le librerie di sistema, non un’interrogazione DNS “grezza”):
$ curl -v http://mememem.it/ * Host mememem.it:80 was resolved. * IPv4: 127.0.0.1 * Trying 127.0.0.1:80... * Connected to mememem.it (127.0.0.1) port 80 < HTTP/1.1 200 OK < Server: Apache/2.4.58 (Ubuntu)
curl risolveva mememem.it a 127.0.0.1, mentre dig diceva NXDOMAIN. Due strumenti, due risultati opposti sullo stesso nome: la discrepanza andava capita lì.
Quarto controllo: getent, per vedere il nome “vero” risolto
Ho quindi usato getent, che interroga il resolver esattamente come fanno le applicazioni (tramite getaddrinfo):
$ getent hosts mememem.it 127.0.0.1 mememem.it.homenet.telecomitalia.it
Ed eccola, la chiave di volta: il sistema non stava affatto risolvendo mememem.it, bensì mememem.it.homenet.telecomitalia.it. Qualcosa, a livello di libreria di sistema, appendeva automaticamente un suffisso al nome prima di interrogare il DNS.
Quinto controllo: da dove arriva quel suffisso
Un’occhiata a /etc/resolv.conf ha chiarito tutto:
nameserver 127.0.0.53 search homenet.telecomitalia.it
homenet.telecomitalia.it è il dominio di ricerca (search domain) che il modem/router TIM annuncia via DHCP a tutti i dispositivi della rete locale. Il meccanismo di risoluzione di glibc, quando un nome non è “pienamente qualificato”, prova ad appendere automaticamente i domini presenti in search prima di arrendersi. Nel mio caso, quel dominio ha una risposta di tipo wildcard gestita dal router stesso, che punta a 127.0.0.1 — dove, guarda caso, gira il mio Apache locale.
Per completezza, ho anche controllato resolvectl query, che invece restituiva “not found”: conferma che il meccanismo di espansione del suffisso avviene a livello di libreria NSS (nsswitch.conf → modulo dns), non nel motore di systemd-resolved interrogato direttamente.
La causa, in sintesi
- Il DNS pubblico funziona correttamente e risponde NXDOMAIN per domini inesistenti.
- Il router locale, tramite DHCP, imposta
homenet.telecomitalia.itcome dominio di ricerca. - Le applicazioni (browser, curl, ecc.) tentano automaticamente
<nome>.homenet.telecomitalia.itquando il nome “semplice” fallisce. - Il router risponde con un wildcard su quella zona, restituendo
127.0.0.1. - Apache, in ascolto su
127.0.0.1, accetta la richiesta e risponde con la pagina di default — qualunque fosse il dominio digitato.
La soluzione
Ho eliminato il dominio di ricerca automatico a livello di connessione di rete, così i nomi non vengono più espansi con il suffisso della LAN:
sudo nmcli connection modify "<nome-connessione>" ipv4.dns-search "" sudo nmcli connection modify "<nome-connessione>" ipv4.ignore-auto-dns yes sudo systemctl restart NetworkManager
Da quel momento, digitare un dominio inesistente mostra correttamente l’errore del browser, e Apache locale risponde solo alle richieste che gli spettano davvero (es. organizer.test, configurato esplicitamente in /etc/hosts).
Morale
Quando DNS e “quello che vede il browser” non coincidono, il sospetto principale non è quasi mai il DNS server in sé, ma come il resolver di sistema costruisce il nome prima di interrogarlo. dig interroga il nome esatto; curl, il browser e qualsiasi altra applicazione passano invece per getaddrinfo(), che applica anche la logica di search domain definita in resolv.conf. Vale sempre la pena confrontare i due, prima di dare per scontato che “il DNS è rotto”.
Tra l’altro: il problema non si presentava se utilizzavo il mio smartphone come router. Questo poteva essere un altro indizio utile perla diagnosi.
Bibliografia
getentman pageresolvectlman page- With a little help from my friend Claude

Commenti recenti