Introduzione
Come ben sappiamo, le reti (tra cui ovviamente anche Internet) sono un insieme più o meno numeroso di dispositivi interconnessi tra di loro; ciascuno di questi dispositivi, per essere raggiungibile, deve possedere un indirizzo IP univoco che lo identifica all’interno della rete. Un indirizzo IP, dunque, può appartenere ad un unico dispositivo della rete; non vale il viceversa, in quanto un singolo dispositivo può avere più di un indirizzo IP. Semplificando, si potrebbe dire che vale una corrispondenza 1:1 tra indirizzi IP e interfacce di rete, ma nella realtà sappiamo che ad una singola interfaccia di rete (fisica) possono essere associati più indirizzi IP differenti. Ad ogni modo, se vogliamo connetterci ad un dato dispositivo, ne dobbiamo conoscere l’indirizzo IP; il protocollo IP è quello che permette il funzionamento dell’intera rete Internet e di tutte le reti che utilizzano questo protocollo di rete. I router, ovvero i dispositivi intermedi che consentono l’interconnessione di reti IP tra loro, inoltrano e veicolano i pacchetti di rete in base all’indirizzo IP di destinazione; sulla base di tale indirizzo e della tabella di routing, stabiliscono in quale direzione inoltrare un dato pacchetto.
In un mondo di macchine non c’è bisogno di altro, se non dell’indirizzo IP, per individuare un certo dispositivo; questo perché la struttura degli indirizzi IP si presta in maniera particolare all’elaborazione automatica. Il problema sorge quando sono gli esseri umani a doversi interfacciare con i vari host della rete, perché gli indirizzi IP non sono particolarmente facili da ricordare e non hanno un “significato” direttamente intellegibile da parte di una persona. Per gli uomini è molto più semplice ricordare nomi, ovvero sequenze di caratteri alfanumerici, piuttosto che numeri. Per questo motivo è pratica comune assegnare ad un dispositivo di rete un nome identificativo più o meno facile da ricordare, che abbia anche un significato pratico. Ad esempio il nome “smtp.dis.uniroma1.it” è di facile interpretazione: si riferisce ad un ipotetico server SMTP del dipartimento di informatica e sistemistica dell’università Sapienza; a tale nome corrisponde l’indirizzo IP 151.100.59.100, che per un utente atto a configurare il proprio programma di posta elettronica può essere sicuramente meno semplice da ricordare a memoria. Anche per quanto riguarda i nomi (hostname), vale la regola che ad un nome, o più precisamente ad un FQDN (Fully Qualified Domain Name), può corrispondere un unico dispositivo, ma non vale il viceversa: un dispositivo può avere più di un nome che lo identifica all’interno di una rete.
In passato, quando Internet era formata da un numero relativamente piccolo di dispositivi, le corrispondenze tra i nomi dei dispositivi ed i relativi indirizzi IP erano memorizzate all’interno di un unico file di testo (il file hosts); ogni dispositivo aveva perciò una copia di questo file, ed ogni aggiornamento comportava la redistribuzione del file stesso tra tutti gli host della rete. Al crescere del numero di host connessi ad Internet, questo sistema non poteva più essere utilizzato perché affatto scalabile; per questo motivo è stato sviluppato il DNS, Domain Name System, che definisce un database distribuito di corrispondenze tra hostname e indirizzi IP, nonché il protocollo utilizzato dai dispositivi per interrogare il database stesso. Ovviamente, per reti locali (LAN) di piccole dimensioni (qualche decina di dispositivi), il vecchio sistema del file hosts è ancora largamente utilizzato.
Il DNS, comunque, fornisce anche ulteriori funzioni e servizi, oltre alla semplice corrispondenza tra hostname e IP. Ad esempio può contribuire a distribuire il carico di un server web, fare l’aliasing di un host e di un server di posta. L’aliasing consiste nell’associare ad un nome host particolarmente complicato un nome più semplice da ricordare; se ad esempio il server stat1.debian.lab.verolinux.org esegue un server web su cui viene ospitato un sito pubblico, è opportuno rendere accessibile tale sito attraverso un nome più facile, come ad esempio www.verolinux.org. Un discorso analogo vale per il nome di un server di posta. Per quanto riguarda la distribuzione del carico, senza entrare troppo nel dettaglio, basti sapere che ad una particolare interrogazione un DNS può rispondere fornendo una lista di più indirizzi IP, ruotandone l’ordine dopo ogni interrogazione. Poiché il client che riceve la risposta utilizza gli IP nell’ordine dato, se un’azienda ha un server web replicato su più macchine, il DNS fa in modo che il traffico sia distribuito (più o meno uniformemente) sulle diverse macchine. Vedrò ora di illustrare, in maniera relativamente sintetica, come funziona il DNS.
Traduzione da hostname a indirizzo IP

Esempio richiesta HTTP GET
Supponiamo che un client HTTP, ad esempio un browser web, abbia necessità di collegarsi al sito web www.google.it per recupearne la home page; ad una prima analisi grossolana, sembrerebbe che il client “chieda” al server web dal nome “www.google.it” la risorsa “/”; ad essere precisi, però, quello che succede è leggermente diverso. Il client, da solo, non ha idea di come poter raggiungere il server web per effettuare la richiesta, perché l’utente ha specificato un nome host e non un IP. Pertanto il client HTTP deve effettuare un passaggio intermedio: deve chiedere ad un server DNS di “risolvere” il nome host “www.google.it”; l’indirizzo IP del server DNS fa parte della configurazione di rete dell’host client, eseguita manualmente dall’utente (che deve sapere quale IP indicare per il DNS) oppure tramite DHCP, pertanto è direttamente raggiungibile. Il client web, dunque, invia una richiesta al server DNS chiedendo a quale IP corrisponda il nome host “www.google.it”; il server risponderà col valore dell’IP corretto. A questo punto, il client può finalmente inviare la sua richiesta al server web. Dal punto di vista del client, il DNS si comporta come una scatola nera: il client chiede, il server dei nomi risponde. Anche questa descrizione, però, non è del tutto corrispondente alla realtà. Come detto in precedenza, infatti, il DNS è un database distribuito, dunque non tutti i server DNS sono a conoscenza di tutte le corrispondenze hostname/IP di tutti gli host al mondo; i nomi, ed i server che li risolvono, sono organizzati secondo una struttura ad albero che ricalca la gerarchia dei nomi. I motivi di questa organizzazione, piuttosto che l’esistenza di un singolo server mondiale con tutte le corrispondenze, sono molteplici:
- il malfunzionamento dell’unico nameserver farebbe crollare l’intero sistema
- un singolo server dovrebbe rispondere a tutte le richieste di tutti i client del mondo
- il server non potrebbe essere fisicamente vicino a tutti i client, quindi ci sarebbe una notevole latenza delle risposte per i client più lontani
- mantenere aggiornato un server di questo tipo sarebbe impraticabile, data la quantità di nomi host esistenti e la frequenza con cui vengono aggiunti/modificati
Per risolvere i problemi elencati, dunque, si ricorre ad una gerarchia di server, ciascuno dei quali responsabile di una porzione dell’intero database dei nomi.
Struttura gerarchica del database e dei server
Ad una prima approssimazione, esistono tre classi di server DNS: i server radice (root server), i server per i domini di primo livello (top level domain) ed i server di competenza. Al mondo esistono 13 root server (in realtà si tratta di cluster di server replicati e non di singole macchine), etichettati da A ad M e localizzati prevalentemente in Nord America. Tutti questi server conoscono gli IP di tutti i server TLD; questi ultimi gestiscono i domini di alto livello come .com, .org, .it, ecc. Più in basso nella gerarchia ci sono i server di competenza, che si occupano dei nomi a dominio di secondo livello e i cui IP sono noti ai server TLD. Vi sono poi i cosiddetti server locali, che non fanno strettamente parte della gerarchia ma contribuiscono al funzionamento efficiente del sistema DNS.

Gerarchia parziale dei server DNS
Quella mostrata in figura è una gerarchia parziale del DNS; è parziale perché è mostrato solo un root server e solo alcuni server TLD e server di competenza. Come già detto, i root server sono 13 in tutto, distribuiti geograficamente e replicati su cluster; lo stesso vale per i server TLD. Alla luce di queste nuove informazioni, osserviamo in che modo avviene la risoluzione di un nome in seguito alla richiesta di un client che voglia contattare, ad esempio l’host chiamato voyage.lab.verolinux.org.
- il client interroga il server DNS locale, generalmente appartenente all’ISP cui il client è connesso oppure alla rete cui il client fa parte; il client “chiede” di sapere l’indirizzo IP dell’host voyage.lab.verolinux.org;
- il server DNS locale riceve la richiesta, quindi la inoltra a uno dei root server; il root server prende in considerazione soltanto l’ultima parte del nome, ovvero “.org”, e restituisce al server DNS locale una lista di IP di server DNS TLD che si occupano del dominio di primo livello .org;
- il server DNS locale invia la richiesta al primo server DNS TLD, il quale prende in considerazione la porzione di hostname “verolinux.org” e risponde inviando l’IP (o gli IP) del server DNS di competenza per verolinux.org;
- il server DNS locale interroga quindi tale server di competenza, il quale restituisce l’IP del nameserver di competenza per il dominio “lab.verolinux.org”;
- il server DNS locale interroga finalmente il nameserver competente per lab.verolinux.org, il quale risponde con l’IP dell’host voyage.lab.verolinux.org. Il risultato di questa interrogazione viene quindi inviato al client che ne aveva fatto iniziale richiesta.
Quello appena descritto è un esempio di query DNS iterativa, dove le richieste (tranne quella iniziale) vengono eseguite tutte dal server DNS locale. In alcuni casi le richieste sono ricorsive, nel senso che ogni server interrogato si preoccupa di portare a termine il resto della query per poi restituire il risultato a chi ne aveva fatto richiesta.
Caching DNS
Come si può osservare dall’esempio precedente, una singola query DNS per risolvere un hostname può comportare anche l’invio/ricezione di dieci messaggi, ovvero dieci pacchetti UDP (il protocollo di trasporto utilizzato per le query DNS) con conseguente latenza e possibilità di dover ripetere un’interrogazione nel caso un messaggio vada perduto. Per migliorare le prestazioni del DNS, quindi, si fa ampio uso del caching: il server DNS locale, dopo aver eseguito una query, ne conserva il risultato per un determinato periodo di tempo (stabilito dal server di competenza); in questo modo, successive query per lo stesso hostname vengono risolte immediatamente senza ripetere tutta la sequenza di messaggi per raggiungere il server di competenza. Il caching riguarda in genere anche gli IP dei server TLD, riducendo così il numero di interrogazioni ai root server.
Resource Record (RR)
L’unità di memorizzazione di informazioni all’interno del database distribuito realizzato dal DNS è il cosiddetto “record di risorsa” (resource record o RR). I messaggi di risposta ad una query DNS trasportano uno o più RR. Un RR è formato dai campi NAME, VALUE, TYPE e TTL. Il TTL è il valore che indica il periodo di validità del RR quando ne viene effettuato il caching. I valori di NAME e VALUE dipendono da TYPE, per il quale sono possibili i seguenti valori:
- NS: indica che NAME è un nome di dominio e VALUE è il nome del server DNS autoritativo per quel dominio;
- A: indica che NAME è il nome canonico del’host e VALUE il suo indirizzo IP;
- MX: indica che VALUE è il nome canonico del server di posta avente come alias NAME;
- CNAME: indica che VALUE è il nome canonico di un host il cui alias è NAME
Tralasciamo per il momento i dettagli relativi alla composizione di un messaggio DNS, ai campi che contiene e alla sua taglia. Questo argomento sarà trattato in maniera approfondita in un altro articolo.
Riferimenti
- Reti di Calcolatori e Internet, terza edizione – Kurose, Ross – Addison Wesley
- Linux, manuale per l’amministratore di sistema – Nemeth, Snyder, Hein – Prentice Hall