%%
%% Dispense Amministrazione di rete
%%
%% Copyright (C) 2003-2018 Simone Piccardi and Truelite Srl.
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%%
%% S. Piccardi Dec. 2005
%%
%% netdns.tex: Sezione sul DNS, separata dalla precedente sui servizi di base.
%%

\chapter{Il servizio DNS}
\label{cha:DNS}



\section{Introduzione al servizio DNS}
\label{sec:net_DNS_service}

In questa prima sezione ci occuperemo di illustrare i principali concetti ed
introdurre i meccanismi di funzionamento del servizio DNS, descrivendone le
caratteristiche generali ed una serie di programmi diagnostici usati appunto
per eseguire interrogazioni su questo servizio.


\subsection{Panoramica sul funzionamento del DNS}
\label{sec:net_DNS_intro}

Il DNS è uno dei protocolli fondamentali per il funzionamento di Internet,
consentendo di associare dei nomi simbolici agli indirizzi IP, e come già
accennato in sez.~\ref{sec:net_name_resolution} si tratta in sostanza di un
meccanismo che consente di realizzare un enorme database distribuito, i cui
dati sono gestiti da un gran numero di \textit{nameserver} (i server che
rispondono alle richieste del protocollo).

Alle origini, quando Internet era piccola e le macchine erano poche, la
risoluzione dei nomi era fatta scaricando su ogni macchina un singolo file (in
sostanza \texttt{/etc/hosts}) che conteneva \textsl{tutte} le corrispondenze
fra indirizzi IP e nomi. Col crescere della rete questo approccio è
rapidamente divenuto insostenibile, non tanto e non solo per le dimensioni
crescenti del file che doveva essere riscaricato ad ogni aggiornamento, quanto
per la quasi impossibilità di mantenere aggiornate in maniera puntuale le
corrispondenze stesse. Per questo è stato creato il protocollo del DNS, il cui
scopo principale era sia quello di poter distribuire il compito di mantenere
aggiornata l'associazione fra nomi simbolici e indirizzi IP che quello di
poter eseguire la risoluzione in maniera veloce ed efficiente.

\itindbeg{Fully~Qualified~Domain~Name (FQDN)}

Il funzionamento del DNS è basato su una suddivisione gerarchica dello spazio
dei nomi nei cosiddetti \textsl{domini}, organizzati in \textsl{livelli} con
una struttura ad albero. I nomi vengono indicati in maniera generica da
stringhe separate da punti che costituiscono quello che viene chiamato il
cosiddetto \textsl{nome a dominio completo}, o FQDN (acronimo di \textit{Fully
  Qualified Domain Name}).  Si hanno così i domini di primo livello (i vari
\texttt{.com}, \texttt{.org}, \texttt{.it}, ecc.) quelli di secondo livello
(ad esempio \texttt{debian.org}, \texttt{gnulinux.it}, \texttt{truelite.it}) e
così via, come illustrato in fig.~\ref{fig:DNS_FQDN_herarchy}.

\itindend{Fully~Qualified~Domain~Name (FQDN)}

\begin{figure}[htb]
  \centering
  \includegraphics[width=12cm]{images/domain_hyer}
  \caption{Schema dell'organizzazione gerarchica dei \textsl{nomi a dominio}.}
  \label{fig:DNS_FQDN_herarchy}
\end{figure}

Per decentralizzare l'aggiornamento delle informazioni si sfrutta un
meccanismo chiamato \textsl{delegazione}. In generale il protocollo prevede
che per ciascun dominio di un certo livello ci debba essere un server DNS
responsabile della risoluzione di tutti i nomi del ramo di albero ad esso
sottostante, che per questo viene detto \textsl{autoritativo}. Grazie alla
struttura gerarchica dei nomi è però possibile che il server responsabile per
un dominio di un certo livello possa \textsl{delegare} altri server per la
risoluzione dei domini dei livelli successivi, che a quel punto diventeranno
\textsl{autoritativi} per tali sotto-domini.

In questo modo le richieste di risoluzione possono essere passate attraverso
una gerarchia di server in cui, in corrispondenza di ciascun livello su cui si
può dividere un nome a dominio, ci deve essere un server DNS che se anche non
è in grado di rispondere direttamente alla richiesta sa però qual'è il server
del livello successivo a cui inoltrarla, così da poter proseguire fino a che
non si incontra il server DNS autoritativo che conosce la risposta finale.

Perché il sistema possa funzionare occorre però anche poter distribuire il
carico delle richieste di risoluzione; se ciascuna macchina che si affaccia su
Internet dovesse effettuare tutte le sue richieste direttamente ai server
autoritativi si genererebbe infatti una enorme quantità di traffico. Per
questo motivo come visto in sez.~\ref{sec:net_resolver_intro}, il sistema del
\textit{resolver} consente di passare le richieste di risoluzione ad un server
DNS esterno che si incaricherà di eseguire le ricerche necessarie, fornendo
poi solo la risposta finale.

\itindbeg{recursive~query}

Perché questo funzioni entra in gioco un secondo meccanismo, denominato
\textsl{ricorsione}, che è quello che viene normalmente fornito dai server DNS
a cui si rivolge il \textit{resolver} (come quelli del proprio provider, che
per questo sono detti \textsl{ricorsivi}). Quando il \textit{resolver}
effettua una ricerca attiva un opportuno flag nel pacchetto di richiesta (il
flag \texttt{rd} mostrato anche nei risultati di \texttt{dig} in
sez.~\ref{sec:net_host}) per richiedere al server DNS una \textsl{ricerca
  ricorsiva} (\textit{recursive query}) che comporta una scansione dell'albero
dei domini come illustrato in fig.~\ref{fig:DNS_recursive_resolution}.

\begin{figure}[htb]
  \centering
  \includegraphics[height=6cm]{images/recursive-dns}
  \caption{Schema della risoluzione ricorsiva di un nome a dominio.}
  \label{fig:DNS_recursive_resolution}
\end{figure}

Se per esempio viene richiesta la risoluzione del nome
\texttt{www.truelite.it} ad un DNS ricorsivo, questi all'inizio contatterà un
\textit{root DNS} per sapere chi è il server autoritativo per il dominio di
primo livello \texttt{.it}. La lista degli indirizzi IP di questi DNS radice
ovviamente deve essere nota a priori, altrimenti non sarebbe possibile
iniziare la ricerca, ed è proprio per questo che vengono chiamati
``\textit{root DNS}''. La lista dei ``\textit{root DNS}'' è distribuita
pubblicamente, ed ogni server DNS ricorsivo deve averla all'interno della
propria configurazione.

I domini di primo livello sono definiti a livello internazionale dalla
cosiddetta \textit{naming authority}, la ICANN (\textit{Internet Corporation
  for Assigned Names and Numbers}), che gestisce i \textit{root DNS} e delega
i domini nazionali alle varie autorità locali. La lista dei DNS autoritativi
per i domini di primo livello è mantenuta direttamente nei \textit{root DNS}
che hanno effettuato la relativa delegazione.

Nel caso del nostro esempio una volta che questi avranno indicato al
richiedente chi è il server responsabile per i domini \texttt{.it} la
scansione proseguirà ripetendo la richiesta per \texttt{.truelite.it} al DNS,
uno di quelli del NIC italiano, appena trovato.\footnote{in realtà qui si è
  semplificato, a tutti i livelli i server autoritativi sono sempre più di uno
  e nelle risposte si ottiene una lista e non un singolo server, ma le
  richieste possono essere fatte ad uno qualunque ottenendo (configurazioni
  errate a parte) gli stessi dati.}  Essendo compito di questo server
conoscere (e delegare) tutti i domini di secondo livello, sarà in grado di
indicarvi qual'è il server DNS responsabile per \texttt{.truelite.it} a cui
rivolgersi in ultima istanza per chiedere la risoluzione di
\texttt{www.truelite.it}.

\itindend{recursive~query}

Un altro tassello del meccanismo è che in tutti i passaggi di una eventuale
ricorsione il server DNS che esegue la ricerca memorizza le varie informazioni
ottenute a ogni passo nella sua cache per poterle riutilizzare immediatamente.
Così nell'esempio precedente si potrà evitare una ulteriore richiesta ai
\textit{root DNS} per i \texttt{.it} se si deve risolvere
\texttt{.gnulinux.it}, oppure un'altra richiesta per \texttt{.truelite.it} se
si deve risolvere \texttt{labs.truelite.it}, e si potrà rispondere
direttamente senza ripetere nessuna ricerca ad una successiva richiesta di
\texttt{www.truelite.it}. 

Questo introduce però anche una distinzione fra le risposte, che sono dette
\textsl{autoritative} se provengono direttamente dal \textit{nameserver} che
ha l'autorità per il nome indicato nella richiesta, (in sostanza quello che è
titolare di quel dominio, torneremo sull'argomento in
sez.~\ref{sec:net_RR_zones}) e \textsl{non autoritative} se provengono dalla
cache di un altro server.

\itindbeg{iterative~query}

Si tenga presente inoltre che essendo quello della ricorsione un procedimento
oneroso, è sempre possibile configurare dei server DNS che rifiutino le
richieste ricorsive. In tal caso saranno comunque accettate le cosiddette
\textsl{richieste iterative} (\textit{iterative query}), chiamate così perché
in tal caso è il richiedente che deve eseguire la scansione illustrata in
fig.~\ref{fig:DNS_recursive_resolution} iterando le richieste.  Un server DNS
in questo caso fornirà delle risposte solo alle richieste per le quali è
autoritativo, o che ha in cache.

\itindend{iterative~query}

Con queste modalità di funzionamento il DNS permette di distribuire in maniera
efficace il compito di fornire le risposte e di mantenere aggiornata la
corrispondenza fra nomi ed indirizzi IP, in quanto alla fine è il responsabile
di ciascun dominio finale a dover mantenere un DNS che contenga le
informazioni relative alle sue macchine. Inoltre il meccanismo del
mantenimento in cache dei risultati permette di aumentare l'efficienza della
ricerca, evitando di ripetere più volte le stesse operazioni, riducendo il
traffico sulla rete ed il carico sui server autoritativi.

Ovviamente la memorizzazione dei risultati ha anche un costo, in quanto se
viene eseguito un cambiamento in una associazione fra nome a dominio e
indirizzo IP questo non verrà rilevato da un altro server DNS che ha nella
propria cache la precedente associazione.  Per questo motivo tutte le
informazioni del DNS sono corredate da un tempo di scadenza, denominato
\textit{time to live} (TTL), passato il quale l'informazione in cache scade e
deve essere richiesta nuovamente.  Questo tempo deve essere scelto in maniera
opportuna a seconda della frequenza con cui possono cambiare le informazioni:
più è breve più frequentemente si riceveranno richieste, aumentando il carico
ed il traffico di rete, ma ottenendo una propagazione molto
veloce;\footnote{sempre che gli altri server DNS siano configurati
  correttamente per onorare un TTL molto breve, cosa che non avviene sempre,
  dato che alcuni provider preferiscono risparmiare sulla banda e mantenere il
  più a lungo possibile le informazioni in cache, per cui i loro server DNS
  ignorano le indicazioni di scadenza fornite.} più è lungo minori saranno il
carico ed il traffico, ma più lenta sarà la propagazione di un cambiamento.


\subsection{I \textit{Resorce Record} e le \textsl{zone di autorità}}
\label{sec:net_RR_zones}

\itindbeg{Resource~Record}

Finora abbiamo sempre parlato di risoluzione di un nome a dominio in un
indirizzo IP, ma un server DNS è in grado di mantenere diversi tipi di
informazione associati ad un dominio, non solo quelli della risoluzione dei
nomi. Questi vengono chiamati, nel gergo del protocollo, \textit{resource
  record}, nome che viene spesso abbreviato nella documentazione in RR. Un
\textit{resource record} costituisce l'elemento di base dell'informazione
mantenuta dal DNS, in sostanza una voce del database distribuito.

I \textit{resource record} vengono classificati secondo la ``\textsl{classe}''
di dati a cui il loro contenuto fa riferimento e per il ``\textsl{tipo}'' dei
dati stessi. In genere si parla di classe di indirizzi, in quanto i dati del
DNS fanno comunque riferimento alla risoluzione di nomi. A ciascuna classe e a
ciascun tipo viene in genere associata una stringa identificativa, ma oggi
praticamente la sola classe in uso è quella degli indirizzi Internet,
identificata dal nome \texttt{IN}.

Esistono invece molti \textsl{tipi} diversi di \textit{resource record},
alcuni dei quali hanno un significato specifico rilevante per il funzionamento
di alcuni protocolli: ad esempio i \textit{record} \texttt{MX} vengono usati
dai server di posta come previsto nel protocollo SMTP, mentre i
\textit{record} \texttt{NS} vengono usati dal DNS stesso per gestire la
delegazione. Un elenco dei principali \textsl{tipi} è riportato in
tab.~\ref{tab:net_DNS_record_type}, l'elenco completo viene mantenuto dalla
IANA nella lista dei parametri del DNS, che è pubblicata sulla pagina web
\url{http://www.iana.org/assignments/dns-parameters}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Tipo} &\textbf{Descrizione}\\
    \hline
    \hline
     \texttt{A}    & corrispondenza fra nome a dominio e indirizzo IP.\\
     \texttt{NS}   & \textit{nameserver} autoritativo per il dominio.\\
     \texttt{CNAME}& nome alternativo (un alias ad un altro nome nel dominio).\\
     \texttt{SOA}  & dati dell'inizio della zona di autorità.\\
     \texttt{PTR}  & corrispondenza fra indirizzo IP e nome a dominio.\\
     \texttt{MX}   & server di posta per il dominio.\\
     \texttt{TXT}  & un commento o altro testo associato al nome a dominio.\\
     \texttt{AAAA} & corrispondenza fra nome a dominio e indirizzo IPv6.\\
     \texttt{SRV}  & locazione di un servizio sul dominio.\\
     \texttt{HINFO}& informazione su una stazione.\\
     \texttt{KEY}  & chiave crittografica.\\%(vedi sez.~\ref{sec:bind_dnssec}).\\
     \texttt{SIG}  & firma digitale.\\% (vedi sez.~\ref{sec:bind_dnssec}).\\
    \hline    
  \end{tabular}
  \caption{Identificativo e relativa descrizione dei principali tipi di
    \textit{resource record}.}
  \label{tab:net_DNS_record_type}
\end{table}

\itindend{Resource~Record}

\index{zona~di~autorità|(}
I vari dati relativi ad un certo dominio vengono raccolti in quella che nel
protocollo viene chiamata una \textsl{zona di autorità}; questa rappresenta in
sostanza quella parte dello spazio dei nomi di dominio per i quali un singolo
\textit{nameserver} è responsabile di gestire le informazioni, sia fornendo
direttamente le risposte, che delegando eventualmente ad un altro server la
risoluzione di un dominio di livello inferiore (che a quel punto riceverà il
compito di gestire la \textsl{zona di autorità} ad esso relativa).

In ogni caso il server al quale sia stata delegata una \textsl{zona di
  autorità} deve fornire le risposte, che in questo caso saranno quelle
autoritative, per qualunque nome all'interno di quel dominio; non si può cioè
delegare la risoluzione dei nomi relativi al dominio sul proprio livello, ma
solo quelli di un dominio del livello successivo. La delegazione è comunque
facoltativa, si possono risolvere anche tutti gli eventuali sottodomini (o
solo alcuni di essi) all'interno di un'unica \textsl{zona di autorità},
inserendo direttamente nella stessa anche i \textit{record} per i nomi dei
livelli successivi.

Il contenuto di una \textsl{zona di autorità} viene normalmente descritto
tramite file di testo chiamati \textsl{file di zona} (su cui torneremo in
sez.~\ref{sec:net_DNS_domain}) in cui vengono raccolte le varie informazioni
associate ai nomi in essa definiti, e le richieste di informazioni effettuate
presso un server DNS sono in genere nella forma in cui si richiede il valore
di un qualche \textit{resource record} associato alla sua zona (vale a dire
per un nome del relativo dominio).

\index{zona~di~autorità|)}

Alle zone di autorità viene inoltre dedicata una parte del protocollo,
utilizzata per consentire la distribuzione dei loro dati nella gestione dei
cosiddetti DNS secondari. Questo viene fatto attraverso quello che viene
chiamato un \textsl{trasferimento di zona}, in cui tutti i contenuti di una
zona possono essere passati da un server ad un altro. Per questo sono state
introdotte delle specifiche tipologie di richieste DNS non più attinenti alla
risoluzione di un singolo nome. Inizialmente esisteva un solo tipo di
richiesta, per il trasferimento in blocco di tutti i dati di una zona,
denominata AXFR, le versioni più recenti del protocollo supportano anche
un altro tipo di richiesta, denominata IXFR, che consente un trasferimento
incrementale. Tratteremo questi aspetti in sez.~\ref{sec:bind_secondary_tsig}.


\subsection{I comandi \texttt{host} e \texttt{dig}}
\label{sec:net_host}

Per effettuare una richiesta di risoluzione di un indirizzo IP normalmente non
è necessario nessun programma specifico, basta un qualunque programma che usi
il \textit{resolver}, si può ad esempio usare \texttt{ping} con un nome a
dominio che, come visto in sez.~\ref{sec:net_ping}, prima di iniziare le sue
operazioni ne scrive sul terminale la risoluzione. In questo caso però si
risolve solo l'indirizzo IP mentre come appena detto un server DNS mantiene
anche informazioni diverse. Per questo sono stati realizzati vari programmi in
grado di eseguire interrogazioni generiche, in sostanza dei client per questo
servizio.

Si tenga presente però che i suddetti programmi non usano il \textit{resolver}
ma parlano direttamente con un server DNS usando il relativo protocollo, anche
per effettuare la normale risoluzione dei nomi a dominio in indirizzi IP; per
questo motivo non è detto che i risultati di una richiesta siano gli stessi
che si potrebbero ottenere con gli ordinari client di rete (come
\texttt{ping}) per i quali la risoluzione del nome potrebbe anche essere stata
ottenuta da fonti alternative come \texttt{/etc/hosts} (si ricordi quanto
detto in sez.~\ref{sec:net_name_resolution}) che in questo caso non sarebbero
prese in considerazione.

Questo tipo di programmi può essere usato per verificare che l'impostazione
della configurazione del \textit{resolver} per l'uso dei DNS esterni funzioni
correttamente, può accadere infatti che la rete sia configurata correttamente,
ma non si riesca a fare nulla perché gli indirizzi simbolici non vengono
risolti, ad esempio perché si è sbagliato ad indicare l'indirizzo del DNS in
\texttt{resolv.conf}. L'uso più comune però è quello di controllare il
funzionamento effettivo del proprio server DNS, e verificarne le informazioni.

Il primo comando che prenderemo in considerazione è
\index{comando!\texttt{host}} \texttt{host}. Se invocato senza argomenti il
comando stampa la sua sintassi, ma in genere lo si usa passandogli come
argomento un nome a dominio che si vuole risolvere, di cui stampa la
risoluzione con le informazioni ottenute dal server DNS; un esempio del suo
utilizzo è:
\begin{Console}
piccardi@hain:~$ \textbf{host www.penciclopedia.it}
www.penciclopedia.it is an alias for gordon.penciclopedia.it.
gordon.penciclopedia.it has address 78.46.114.60
\end{Console}
%$

Il comando riporta in forma discorsiva che il nome
\texttt{www.penciclopedia.it} è stato risolto come corrispondente all'IP
\texttt{78.46.114.60}, ma la risposta ci mostra anche che in questo caso la
corrispondenza del nome indicata è stata effettuata inizialmente con un
\textit{alias} ad un altro nome (cioè con un \textit{record} di tipo
\texttt{CNAME}, vedi tab.~\ref{tab:net_DNS_record_type}) che reinvia al nome
principale della macchina, \texttt{gordon.penciclopedia.it}, che è quello per
cui si ha invece la corrispondenza diretta con un indirizzo IP (cioè un
\textit{record} di tipo \texttt{A}).

Il comando funziona anche alla rovescia, si può cioè chiedere quale nome a
dominio corrisponde ad un certo indirizzo IP (la cosiddetta
\textsl{risoluzione inversa}) indicando quest'ultimo come argomento, con:
\begin{Console}
piccardi@hain:~$ \textbf{host 78.46.114.60}
60.114.46.78.in-addr.arpa domain name pointer gordon.truelite.it.
\end{Console}
%$
e si noti come in questo caso la risoluzione non corrisponda al nome associato
in precedenza all'indirizzo IP. É infatti possibile che ci siano più nomi a
dominio che corrispondono allo stesso indirizzo IP, ad esempio:
\begin{Console}
piccardi@hain:~$ \textbf{host piccardi.gnulinux.it}
piccardi.gnulinux.it has address 78.46.114.60
\end{Console}
%$
ci mostra ancora un altro nome a dominio associato allo stesso indirizzo;
infatti nella risoluzione inversa (che si effettua con la richiesta di un
\textit{record} \texttt{PTR}) ad un indirizzo IP può essere associato un solo
nome.

Il comando \texttt{host} permette di richiedere esplicitamente anche gli altri
tipi di record usando l'opzione \texttt{-t}, che prende come parametro il tipo
di record voluto indicato secondo i valori riportati in
tab.~\ref{tab:net_DNS_record_type}.  Ad esempio se vogliamo trovare il server
incaricato della ricezione della posta per il dominio \texttt{truelite.it}
possiamo usare:
\begin{Console}
piccardi@hain:~$ \textbf{host -t MX truelite.it}
truelite.it mail is handled by 30 mail3.truelite.it.
truelite.it mail is handled by 10 mail.truelite.it.
truelite.it mail is handled by 20 mail2.truelite.it.
\end{Console}
%$
che ci risponde restituendo i \textit{record} \texttt{MX}. L'opzione supporta
anche l'uso del valore speciale \texttt{ANY}, che richiede l'invio di tutti i
\textit{record} associati al nome. 

Il comando effettua le sue richieste interrogando i server DNS elencati in
\texttt{/etc/resolv.conf}, ma gli si può indicare una lista di server
alternativi da utilizzare passando gli stessi come argomenti successivi al
primo, e li si possono indicare anche per nome a dominio, ed in questo caso la
risoluzione verrà effettuata dal \textit{resolver}. Per le altre opzioni e
tutti i dettagli si consulti la pagina di manuale.

Il secondo comando utilizzato per le interrogazioni ai DNS è
\index{comando!\texttt{dig}}\texttt{dig}; le sue funzionalità sono
sostanzialmente le stesse di \texttt{host}, ma a differenza di questo è
pensato come strumento di analisi delle risposte dei server DNS, e riporta i
risultati in un formato meno discorsivo ma molto più preciso, indicando tutti
i dettagli relativi alle richieste fatte ed ai dati ottenuti, usando per i
risultati lo stesso formato dei file di zona che vedremo in maggiore dettaglio
in sez.~\ref{sec:net_DNS_base}.

Il comando richiede che si passi come argomento il nome a dominio di cui si
vuole la risoluzione, ma in questo caso se non si indica nulla, il comando
chiede la risoluzione per la radice dell'albero dei domini (cioè per il nome
``\texttt{.}'') stampando in sostanza l'elenco degli indirizzi dei
\textit{root server}. 

Benché la lettura dell'output del comando sia più complessa, le informazioni
sono molto più dettagliate e consentono di effettuare richieste in maniera
molto più sofisticata, un esempio di risultato del comando è il seguente:
\begin{Console}
piccardi@hain:~$ \textbf{dig piccardi.gnulinux.it}

; <<>> DiG 9.7.0-P1 <<>> piccardi.gnulinux.it
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38026
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;piccardi.gnulinux.it.          IN      A

;; ANSWER SECTION:
piccardi.gnulinux.it.   84656   IN      A       78.46.114.60

;; AUTHORITY SECTION:
gnulinux.it.            84657   IN      NS      ns.gnulinux.it.
gnulinux.it.            84657   IN      NS      ns2.gnulinux.it.

;; ADDITIONAL SECTION:
ns.gnulinux.it.         84657   IN      A       62.48.34.25
ns2.gnulinux.it.        84657   IN      A       217.133.96.194

;; Query time: 6 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Fri Mar 18 01:46:49 2011
;; MSG SIZE  rcvd: 121
\end{Console}
%$#$$

L'output prevede una stampa iniziale dei dettagli della richiesta effettuata,
e riporta (nella sezione etichettata \texttt{QUESTION}) i dettagli della
domanda di risoluzione effettuata, a cui seguono una serie di sezioni che
oltre alla risposta alla richiesta stessa (nella sezione \texttt{ANSWER})
riporta ulteriori dati relativi a chi è responsabile per la risoluzione (i
\textit{record} \texttt{NS} della sezione \texttt{AUTHORITY}) e eventuali dati
addizionali (gli indirizzi dei suddetti DNS nella sezione
\texttt{ADDITIONAL}). Infine si noti come in coda al comando siano riportate
informazioni aggiuntive sul server contattato e sulla tempistica delle
risposte.

Il comando consente di indicare come \texttt{host} la richiesta di tipi di
record diversi con l'opzione \texttt{-t}, ma in generale questi (ed una
eventuale classe diversa dal default di \texttt{IN}) possono essere indicati
dagli argomenti successivi della riga di comando.  Un esempio di invocazione
di questo tipo è la seguente, che consente di ottenere la versione del server
DNS che si sta usando, facendo riferimento alla classe di indirizzi
\texttt{CH} che ormai è presente solo in un caso come questo:
\begin{Console}
piccardi@hain:~$ \textbf{dig version.bind CH TXT}

; <<>> DiG 9.7.0-P1 <<>> version.bind CH TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46522
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;version.bind.			CH	TXT

;; ANSWER SECTION:
version.bind.		0	CH	TXT	"9.7.3"

;; AUTHORITY SECTION:
version.bind.		0	CH	NS	version.bind.

;; Query time: 4 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Fri Mar 18 02:10:11 2011
;; MSG SIZE  rcvd: 63
\end{Console}
%$#$$


Come per \texttt{host} il programma di default interroga i server DNS elencati
in \texttt{/etc/resolv.conf}, ma si può indicare esplicitamente a quale server
rivolgersi passandogli un argomento nella forma \texttt{@server}.  Inoltre
\texttt{dig} può essere usato in modalità non interattiva con l'opzione
\texttt{-f}, che permette di effettuare le ricerche leggendo i comandi da un
file, passato come argomento dell'opzione.

Occorre inoltre una accortezza quando si vuole effettuare una risoluzione
inversa, il comando infatti, a differenza di \texttt{host}, tratta sempre il
suo primo argomento come un nome a dominio, anche se si scrive un indirizzo
IP, se si vuole che venga chiesto il record \texttt{PTR} per quell'indirizzo
occorre dirlo esplicitamente specificando l'opzione \texttt{-x}.


\section{Gestione di base di un server DNS}
\label{sec:net_DNS_management}

In questa sezione prenderemo in esame le basi della gestione di un server DNS,
concentrandoci in particolare su una implementazione particolare, quella di
\textit{BIND}, che detiene comunque la stragrande maggioranza delle
installazioni dei server DNS su Internet.


\subsection{Il server \textit{BIND}}
\label{sec:net_DNS_server}

Essendo un servizio di rete implementato a livello di applicazione, il
servizio del DNS viene fornito attraverso un opportuno demone, e la porta
standard assegnata al servizio è la 53, sia UDP che TCP.  Il server DNS più
diffuso è \textit{BIND} (acronimo di \textit{Berkeley Internet Name Domain}),
anche se il nome del programma eseguito è
\index{demone!\texttt{named}}\texttt{named}.  Il programma venne rilasciato
originariamente come parte di BSD, e mantenuto in seguito dall'Internet
Software Consortium; attualmente è giunto alla versione 9.

L'installazione del programma da pacchetto è prevista da tutte le maggiori
distribuzioni (nel caso di Debian il pacchetto è \texttt{bind9}, nel caso di
RedHat/CentOS è semplicemente \texttt{bind}) e una volta installato viene
lanciato direttamente negli script di avvio. Inoltre in genere si prevede che
al programma venga dedicato un utente apposito (\texttt{bind} per Debian,
\texttt{named} per RedHat), in modo da poterlo far eseguire con privilegi
ridotti.

Come accennato in genere \texttt{named} viene lanciato direttamente in fase di
avvio; qualora si debbano effettuare delle prove lo si può anche eseguire
direttamente ed in tal caso normalmente si usa l'opzione \texttt{-f} per
mantenerlo associato al terminale, o \texttt{-g} se oltre a questo si vuole
anche vederne i messaggi d'errore (l'opzione ne forza la scrittura sullo
\textit{standard error}).  Questi ultimi vengono controllati dall'opzione
\texttt{-d} seguita da un valore numerico che indica il livello di debug. Si
può poi specificare un file di configurazione alternativo al default con
l'opzione \texttt{-c}.

Di norma il programma viene eseguito usando l'opzione \texttt{-u}, che
permette di indicare un utente dedicato, senza privilegi speciali, per conto
del quale il programma sarà eseguito dopo aver effettuato l'inizializzazione
del server per le normali operazioni del DNS.\footnote{dovendo porsi in
  ascolto sulla porta 53, che è una delle porte riservate, è necessario avere
  inizialmente i privilegi di amministratore che nel corso delle ulteriori
  operazioni non sono più necessari.}  L'utente usato dipende in genere dalla
distribuzione e dall'installazione che si è effettuata, ed ogni distribuzione
consente di personalizzare le opzioni con cui avvia il servizio tramite gli
opportuni file di configurazione (ad esempio \texttt{/etc/default/bind9} per
Debian e \texttt{/etc/sysconfig/named} per RedHat).

Un'altra opzione che in alcuni casi può essere d'aiuto è \texttt{-4} che forza
l'uso di IPv4 anche quando la macchina è in grado di supportare IPv6; accade
infatti che anche se localmente il protocollo è supportato, alcuni provider
non lo inoltrino o che le richieste di risoluzione falliscano, per questo si
può richiedere l'utilizzo esclusivo di IPv4.  Per le altre opzioni a riga di
comando si rimanda al solito alla pagina di manuale.

A partire della versione 9 insieme a \texttt{named} viene fornito anche un
apposito programma di controllo, \index{comando!\texttt{rndc}} \texttt{rndc},
che consente di eseguire, oltre alle classiche azioni di avvio, ripartenza e
rilettura delle configurazioni, anche operazioni più avanzate, come il
controllo delle zone gestite dal server e le operazioni di gestione della
cache.  Il programma comunica direttamente con il server tramite una
connessione TCP su una porta dedicata (il default è la 953) su cui invia i
comandi che sono autenticati attraverso l'uso di una chiave condivisa analoga
a quella usata (tratteremo l'argomento in sez.~\ref{sec:bind_secondary_tsig})
per autenticare i trasferimenti di zona fra server. Se non è presente nessun
file di configurazione il programma si collega sul \textit{localhost} ed usa
la chiave mantenuta nel file \texttt{rndc.key} (in genere posto sotto
\texttt{/etc/bind}).

In generale \texttt{rndc} utilizza un file di configurazione
(\texttt{rndc.conf}) che consente di indicare più chiavi e più server a cui
collegarsi, ma nell'uso ordinario, in cui si opera sul server installato
localmente, questo non è necessario, dato che l'uso di \texttt{rndc.key} e
l'accesso in locale è il default anche per \texttt{named}, per cui è
sufficiente generare questo file (come fa ad esempio il pacchetto installato
da Debian). Si possono cambiare i file a cui fare riferimento, il server, la
porta da contattare ecc. con le opportune opzioni, ma visto lo scarso utilizzo
delle stesse, si rimandano gli interessati alla pagina di manuale.

Qualora si vogliano cambiare i parametri di default o usare una nuova chiave è
possibile generare una configurazione con
\index{comando!\texttt{rndc-confgen}} \texttt{rndc-confgen}, che è pure il
comando che, usato con l'opzione \texttt{-a}, genera \texttt{rndc.key}. Se
usato normalmente invece stampa un contenuto standard per \texttt{rndc.conf},
insieme alle modifiche da apportare alla configurazione di \texttt{named}. Il
comando inoltre prevede varie opzioni per impostare altre caratteristiche
della configurazione (come porte o indirizzi remoti del server nel file
generato) per le quali si rimanda alla pagina di manuale.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Comando} &\textbf{Descrizione}\\
    \hline
    \hline
     \texttt{reload}  & forza la rilettura della configurazione e dei file
                        di zona, si può forzare la rilettura di una
                        specifica zona passata come secondo argomento.\\
     \texttt{retransfer}& forza il trasferimento della zona, senza controllare
                          se è cambiato il numero di versione.\\
     \texttt{stats}   & stampa le statistiche di uso del server.\\
     \texttt{stop}    & ferma il servizio.\\
     \texttt{status}  & stampa lo stato del server.\\
     \texttt{flush}   & cancella il contenuto della cache del server.\\
%     \texttt{reconfig}  & .\\
%     \texttt{addzone}& .\\
%     \texttt{delzone}& .\\
%     \texttt{freeze} & .\\
%     \texttt{thaw}   &  .\\
    \hline    
  \end{tabular}
  \caption{I principali comandi utilizzabili con \texttt{rndc}.}
  \label{tab:rndc_commands}
\end{table}

Se invocato senza argomenti \texttt{rndc} stampa una lista di tutti i comandi
disponibili, di cui si sono riportati i più significativi in
tab.~\ref{tab:rndc_commands}, altrimenti il comando deve essere indicato come
primo argomento. I comandi più comuni sono \texttt{start} e \texttt{stop}, di
ovvio significato, e \texttt{reload} che consente far di ricaricare le
configurazioni ed i dati delle zone al server, in questo caso si può indicare
anche la zona stessa (con il relativo nome a dominio) per ricaricare solo
quella. 


\subsection{Il file \texttt{named.conf}}
\label{sec:net_named_conf}

Il file di configurazione principale di \texttt{named} è
\index{configurazione!\texttt{named.conf}} \texttt{named.conf}, che di solito
viene installato a seconda delle distribuzioni o sotto \texttt{/etc/named} o
sotto \texttt{/etc/bind}, se non direttamente sotto \texttt{/etc}. Il file ha
una sintassi abbastanza complessa e simile a quella dei programmi in C; da un
punto di vista puramente ``\textit{grammaticale}'' esso consiste di una serie
di direttive, alcune delle quali a loro volta possono contenere blocchi di
ulteriori direttive o valori racchiusi fra parentesi graffe.

Ogni direttiva deve essere terminata con il carattere ``\texttt{;}'' che ne
indica la conclusione, pertanto si possono scrivere le impostazioni di una
direttiva su più righe senza nessuna sintassi particolare. Se la direttiva
prevede un valore semplice questo deve essere specificato di seguito
all'identificativo della direttiva separato da spaziatura, se la direttiva
prevede valori multipli o altre direttive questi devono essere indicati
all'interno di un blocco separati dal solito ``\texttt{;}'' di
terminazione. Si tenga presente che una direttiva inserita dentro un'altra
potrebbe a sua volta richiedere un blocco con altre direttive e così via.

Ad ogni parentesi graffa aperta, che indica l'inizio di un blocco, deve
corrispondere una parentesi graffa chiusa seguita dal ``\texttt{;}'' di
terminazione che ne indicano la fine.  Alcune direttive che richiedono un
blocco possono richiedere un ulteriore argomento singolo da indicare prima del
blocco (nel caso separato da spazi).  I commenti possono essere introdotti
dall'usuale carattere ``\texttt{\#}'', ma viene utilizzata anche la sintassi
del C e del C++, con blocchi delimitati da ``\texttt{/* */}'' o inizianti per
``\texttt{//}''.

Anche se la sintassi utilizzata da tutte le direttive è sostanzialmente la
stessa, alcune di esse, che chiameremo ``\textsl{primarie}'', sono più
importanti, dato che vanno a costituire la struttura di \texttt{named.conf}
controllando i vari aspetti della configurazione del server. Queste direttive
sono quelle che vengono usate direttamente all'interno del file senza far
parte del contenuto di un'altra direttiva. Chiameremo invece
``\textsl{secondarie}'' tutte le altre direttive che possono comparire solo
all'interno di un blocco di una direttiva primaria, e che consentono di
configurare gli aspetti gestiti all'interno di quest'ultima.

Sfugge a questa suddivisione la direttiva \texttt{include}, che non esegue
nessuna impostazione ma consente semplicemente di includere il contenuto di un
altro file. In questo modo diventa possibile dividere le varie configurazioni
(ad esempio le zone per diversi domini, o le configurazioni generiche) e
mantenere separatamente le varie parti.  Una lista delle direttive primarie
più rilevanti, con una breve spiegazione del loro significato generico, è la
seguente:
\begin{basedescript}{\desclabelwidth{1.7cm}}
\item[\texttt{acl}] definisce una \textit{Access Control List} per raggruppare
  macchine, reti o ``\textsl{utenti}'' (quest'ultimi identificati da chiavi
  definite da \texttt{key}) a cui fare riferimento all'interno di altre
  direttive.
\item[\texttt{controls}] definisce i canali di controllo del demone usati per
  l'amministrazione remota (gli accessi per le operazioni effettuate dal
  comando \texttt{rndc}). Può essere omessa ed in tal caso si applica comunque
  una configurazione di default che prevede l'accesso solo da
  \texttt{localhost} sulla porta 953, utilizzando la chiave posta nel file
  \texttt{rndc.key}.
\item[\texttt{key}] definisce una chiave crittografica
  condivisa,\footnote{\textit{BIND} supporta solo crittografia a chiave
    simmetrica (vedi sez.~1.2.2 di \cite{SGL}.} usata per autenticare le
  comunicazioni (per i canali di controllo definiti con \texttt{controls} o le
  \textit{transition signature} che vedremo in
  sez.~\ref{sec:bind_secondary_tsig}). Per l'uso di \texttt{rndc} è previsto
  l'uso della direttiva in un file separato \texttt{rndc.key} (nella stessa
  directory di \texttt{named.conf} e con la stessa sintassi) che con Debian
  viene creato automaticamente all'installazione del pacchetto.
\item[\texttt{logging}] definisce le modalità con cui le varie informazioni
  vengono inviate sui file di log o al sistema del \textit{syslog}.
\item[\texttt{options}] permette di impostare alcune proprietà generali del
  server ed i default per le altre direttive. Conviene inserirla in un file a
  parte (ad esempio in Debian è mantenuta in
  \texttt{/etc/bind/named.conf.options}) da includere con \texttt{include}.
\item[\texttt{view}] definisca una \textsl{vista} del DNS, che consente di
  modificare risposte e comportamento del server a seconda degli indirizzi da
  cui arrivano le richieste.
\item[\texttt{zone}] definisce una \textsl{zona} del DNS e le modalità con cui
  vengono utilizzate le relative informazioni. La definizione di una
  \textsl{zona} serve ad identificare quella sezione dell'albero dei nomi a
  dominio per il quale il server deve eseguire delle azioni specifiche.
\end{basedescript}

Si tenga presente che le due direttive \texttt{logging} e \texttt{options}
possono comparire soltanto una volta. Torneremo su buona parte delle altre più
avanti, quando tratteremo le funzionalità che forniscono, l'unica che
prenderemo in esame subito è \texttt{acl}, in quanto utilizza una sintassi
usata anche in altri contesti.  La direttiva richiede come primo argomento una
stringa identificativa, da utilizzare per fare riferimento alla ACL che
definisce, seguita dalla lista degli elementi che ne fanno parte; questa deve
essere espressa con quella che viene chiamata una \textit{address match list},
un tipo di argomento che consente di ``\textsl{selezionare}'' un insieme di
indirizzi di rete, e che viene usato anche con molte altre direttive.

Nella sua forma più elementare una \textit{address match list} è proprio una
lista di indirizzi, sia IPv4 che IPv6, sia singoli che, espressi con la
notazione CIDR, di rete. Ma si può usare come elemento anche l'identificativo
di un'altra ACL, nel qual caso si aggiungeranno alla lista gli elementi in
essa definiti. A tale scopo esistono alcune ACL predefinite, come
\texttt{localhost} (di ovvio significato), \texttt{localnets} che identifica
le reti locali (quelle su cui si ha un indirizzo IP assegnato), \texttt{any},
che identifica un indirizzo qualunque e \texttt{none} che identifica la
selezione nulla.

Infine si può usare come elemento anche l'identificativo di una chiave
preposto dalla parola chiave \texttt{key}: in tal caso verranno aggiunte alla
lista gli indirizzi delle macchine che usano quella chiave per comunicare col
server. Come ulteriore elemento della sintassi di una \textit{address match
  list} si può usare il carattere ``\texttt{!}'', anteponendolo ad un
qualunque elemento, per invertire la selezione agli indirizzi che non
corrispondono allo stesso.  Un esempio di ACL potrebbe essere:
\begin{Example}
acl internals { 
      127.0.0.1; localnets; 192.168.1.0/24; ! key external-key;
};
\end{Example}
il cui significato è usare il \textit{localhost}, tutte le reti su cui la
macchina si affaccia direttamente, la rete \texttt{192.168.1.0/24} e tutte le
macchine che non usano la chiave \texttt{external-key} per comunicare col
server.

La lista completa delle direttive primarie, con il sommario delle ulteriori
direttive utilizzabili al loro interno e dei relativi argomenti, è riportata
nella pagina di manuale accessibile con \texttt{man named.conf}.  Per una
descrizione completa del significato delle varie direttive occorre però fare
riferimento alla documentazione di \textit{BIND}, che è molto estesa e può
essere consultata in linea all'indirizzo
\url{http://www.isc.org/software/bind/documentation}, dove sono rese
disponibili anche delle versioni in PDF del manuale di riferimento del
programma.

Un esempio del contenuto del file \texttt{named.conf}, ripreso dal file
installato dal pacchetto \texttt{bind} su una distribuzione Debian Squeeze, è
riportato di seguito:
\begin{FileExample}[label=named.conf]
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the 
// structure of BIND configuration files in Debian, *BEFORE* you customize 
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
\end{FileExample}
in cui semplicemente viene adottata una pratica abbastanza comune, in cui si
suddivide la configurazione su una serie di altri file.

% Se poi andiamo a vedere il primo di questi 
% si noti come in questo caso viene incluso un file a parte che contiene
% l'impostazione delle opzioni con il comando \texttt{options}, e poi viene
% usato il comando \texttt{logging} per bloccare la scrittura nei log di alcuni
% tipi di messaggi. Vedremo il resto del file in seguito, in relazione a diverse
% configurazioni.


\subsection{La configurazione di base del server}
\label{sec:net_DNS_base}

Le modalità di utilizzo di un server DNS possono essere le più diverse a
seconda delle esigenze che esso deve soddisfare, la più semplice è però quella
del cosiddetto \textit{caching nameserver} in cui si usa il server come
intermediario per le macchine di una rete locale per evitare di ripetere per
ciascuna di esse le richieste di risoluzione dei nomi su Internet. 

In genere installando il pacchetto di \textit{BIND} fornito da una
distribuzione si ottiene appunto una configurazione di questo tipo, con una
serie di impostazioni di base, che risulteranno utili anche in caso di altre
modalità di utilizzo. Come accennato in sez.~\ref{sec:net_named_conf} le
opzioni generali per il server vengono sempre effettuate con la direttiva
\texttt{options}, un estratto della configurazione installata di default con
una Debian Wheezy è il seguente:
\begin{FileExample}[label=named.conf]
options {
	directory "/var/cache/bind";
	dnssec-validation auto;
	auth-nxdomain no;    # conform to RFC1035
	listen-on-v6 { any; };
};
\end{FileExample}

In questo esempio la direttiva principale è \texttt{directory}, che imposta la
directory di lavoro del programma, usata per risolvere i \textit{pathname}
relativi nelle configurazioni e per i file prodotti internamente dal
server. Le altre direttive più rilevanti disponibili in questa sezione, in
sostanza quelle che consentono di regolare le risposte del server ai vari tipi
di richieste, e quelle relative alle modalità con cui si pone in ascolto sulla
rete, qui non compaiono (con l'eccezione di \texttt{listen-on-v6}) in quanto
per un \textit{caching nameserver} sono validi i valori preimpostati, le si
sono comunque riassunte in tab.~\ref{tab:bind_options_subdirectives}.


\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Descrizione}\\
    \hline
    \hline
    \texttt{allow-query}    & indica chi può effettuare richieste (iterative)
                              al server, prende come argomento una
                              \textit{address match list} ed il default è
                              chiunque.\\ 
    \texttt{allow-recursion}& indica chi può effettuare richieste ricorsive,
                              prende come argomento una \textit{address match
                              list} ed il default è il \textit{localhost} e
                              gli indirizzi della rete locale.\\
    \texttt{allow-transfer} & indica chi può effettuare richieste di
                              trasferimento di zona, prende come argomento una
                              \textit{address match list} ed il default è
                              chiunque.\\
    \texttt{directory}      & indica la directory di lavoro del server
                              (richiede un \textit{pathname} assoluto).\\
    \texttt{dnssec-enable}  & abilita il DNSSEC (vedi
                              sez.~\ref{sec:bind_dnssec}).\\ 
    \texttt{dnssec-validation}& abilita la validazione con il DNSSEC (vedi
                                sez.~\ref{sec:bind_dnssec}).\\
    \texttt{forwarders}     & indica un gruppo di server DNS (da indicare con
                              una lista di indirizzi IP) cui inoltrare le
                              richieste.\\ 
    \texttt{listen-on}      & indica su quale indirizzo IPv4 (ed eventualmente
                              su quale porta con la ulteriore sintassi
                              \texttt{port  \textsl{NN}}) mettersi in ascolto,
                              da indicare con una \textit{address match list},
                              il default sono tutti gli indirizzi definiti
                              sulla macchina.\\ 
    \texttt{listen-on-v6}   & analogo di \texttt{listen-on} per IPv6.\\
    \texttt{query-source}   & indica indirizzo IPv4 (ed eventuale porta) da
                              usare nelle richieste fatte verso l'esterno, da
                              indicare nella forma \texttt{address
                              \textsl{N.N.N.N} port \textsl{N}}, il default è
                              usare l'indirizzo generico ed una porta
                              effimera.\\ 
    \texttt{query-source-v6}& analogo di \texttt{query-source} per IPv6.\\
%     \texttt{}   &  .\\
    \hline    
  \end{tabular}
  \caption{Le principali direttive secondarie di una \texttt{options}.}
  \label{tab:bind_options_subdirectives}
\end{table}


Di default \texttt{named} si pone in ascolto sulla porta 53 in maniera
separata per ciascun indirizzo IPv4 definito sulla propria macchina. Si può
modificare questo comportamento con la direttiva \texttt{listen-on} con cui si
può anche indicare una porta diversa con la sintassi \texttt{port \textsl{NN}}
da scrivere prima di specificare gli indirizzi con una \textit{address match
  list}. L'utilizzo più comune di questa istruzione è forzare l'ascolto solo
su alcuni degli indirizzi IP della propria macchina: se ad esempio si volesse
utilizzare il server solo in locale si potrebbe usare il default installato su
RedHat/CentOS, con:
\begin{FileExample}[label=named.conf]
options {
        ...
        listen-on port 53 { 127.0.0.1; };
        ...
};
\end{FileExample}

Nell'esempio precedente si è usato come argomento di \texttt{listen-on} un
singolo indirizzo, ma l'istruzione prevede che questo sia una \textit{address
  match list}, di cui verranno utilizzati solo gli indirizzi attualmente
presenti sul server che vi corrispondono. Inoltre con l'uso di \texttt{any},
come nel caso di \texttt{listen-on-v6} dell'esempio precedente, si indica di
ascoltare sull'indirizzo generico (e non singolarmente su ogni indirizzo
assegnato). Se invece si usa \texttt{none} si indica semplicemente di non
mettersi in ascolto per quel protocollo.

La configurazione di default prevede che il server accetti richieste iterative
da qualunque indirizzo e richieste ricorsive solo dalla rete locale e dal
\textit{localhost}. Le due direttive che consentono di modificare questo
comportamento sono \texttt{allow-query} per le richieste iterative ed
\texttt{allow-recursion} per quelle ricorsive, ed entrambe usano come
argomento una \textit{address match list}.

In generale non ci sono motivi per restringere le richieste iterative per cui
non ha molto senso usare \texttt{allow-query} a meno che non si voglia
bloccare completamente l'uso del proprio server da parte di qualcuno, ma le
restrizioni per \texttt{allow-recursion} possono risultare eccessive. Se ad
esempio si fosse installato BIND sulla macchina \texttt{hogen} di
fig.~\ref{fig:net_schema_rete} per agire come \textit{caching nameserver} per
tutta la rete, con la configurazione di default le macchine della sotto-rete
\texttt{192.168.168.0} non potrebbero usarlo (nel senso di inserirlo come
\texttt{nameserver} in \texttt{resolv.conf}). In tal caso infatti
\texttt{named} rifiuterebbe le richieste ricorsive, dato che provengono da una
rete su cui non si affaccia; per consentirne l'utilizzo si sarebbe dovuto
aggiungere alla configurazione qualcosa del tipo:
\begin{FileExample}[label=named.conf]
options {
        ...
        allow-recursion { localnets; localhost; 192.168.168.0/24; };
        ...
};
\end{FileExample}
e si noti come sia necessario indicare anche i valori del default
(\texttt{localnets; localhost;}) altrimenti si abiliterebbero le richieste
ricorsive \textsl{solo} dalla nuova rete.

Normalmente è cura di un server DNS effettuare il procedimento di scansione
ricorsiva illustrato in sez.~\ref{sec:net_DNS_intro}. Ma abbiamo già fatto
notare come questo sia un procedimento oneroso che può richiedere varie
interrogazioni. Nel caso si voglia fornire un servizio di \textit{caching
  nameserver} per una rete locale si possono limitare ulteriormente le
richieste delegando questo compito al \textit{nameserver} del proprio provider
a cui si può semplicemente inoltrare la richiesta per farsi dare solo il
risultato finale. Questo comportamento viene abilitato con la direttiva
\texttt{forwarders} che prende come argomento una lista di altri server. La
sintassi prevede solo una lista di indirizzi (non una \textit{address match
  list}) per ciascuno dei quali si può indicare, separato da uno spazio, una
porta, se diversa dalla 53. Un esempio di questa configurazione è il seguente:
\begin{FileExample}[label=named.conf]
options {
        ...
        forwarders {
                213.234.128.211;
                213.234.132.130;
        };
        ...
};
\end{FileExample}
ed in questo caso ogni richiesta verrà inoltrata verso i due server DNS
indicati; e solo in caso di fallimento di questi verrà tentata una risoluzione
diretta.

In sez.~\ref{sec:net_DNS_intro} abbiamo visto come per poter effettuare la
risoluzione di un indirizzo generico un DNS debba essere in grado di
contattare i \textit{root DNS} per avere la risoluzione della radice
dell'albero dei domini. La direttiva che consente di dichiarare le modalità di
risoluzione di una qualunque zona da parte del server è \texttt{zone}, la cui
sintassi generale prevede che essa sia seguita, fra virgolette (\verb|"|), dal
nome a dominio della zona a cui si fa riferimento e da un blocco di istruzioni
che specificano le modalità con cui questa verrà risolta.

Pertanto per il funzionamento del server è necessario definire la zona del
dominio radice ``\texttt{.}'' fornendo una configurazione che ne consenta la
risoluzione. Questo viene fatto inserendo in \texttt{named.conf} una opportuna
dichiarazione della stessa, con una sezione del tipo di:
\begin{FileExample}[label=named.conf]
zone "." {
        type hint;
        file "/etc/bind/db.root";
};
\end{FileExample}

Le modalità di risoluzione della zona vengono decise dalla direttiva
\texttt{type}, che richiede come argomento una stringa che indica il
``\textsl{tipo}'' di zona, vedremo più avanti altri possibili tipi, come
\texttt{master} o \texttt{slave}, e come questo comporti una diversa modalità
di gestione della stessa.

Nel caso specifico la zona è dichiarata di tipo \texttt{hint}, che dice
semplicemente che si ha un ``\textsl{suggerimento}'' diretto sui contenuti
della stessa, che quindi non è necessario richiedere altrove, nel file
dichiarato dalla successiva direttiva \texttt{file}. Questa specifica qual è
file da cui prendere le informazioni, che può essere indicato in forma
assoluta, come nell'esempio, o in forma relativa rispetto alla directory di
lavoro del server definita con la direttiva \texttt{directory} all'interno di
\texttt{options}.

In questo caso il file è \texttt{/etc/bind/db.root} che contiene l'elenco dei
\textit{root DNS}, il cui contenuto può essere ottenuto con il comando
\texttt{dig} (vedi sez.~\ref{sec:net_host}) o scaricato direttamente
all'indirizzo \url{ftp://ftp.internic.net/domain/named.root}, ma che in genere
viene fornito con l'installazione del programma. Nel caso di Debian i file di
configurazione di \textit{BIND} installati col pacchetto prevedono una sezione
di questo tipo (l'esempio precedente è estratto da uno di questi).

In generale, oltre alla zona per i \textit{root DNS}, quando si installa il
pacchetto di \textit{BIND}, i file di configurazione impostano anche la
risoluzione del \textit{localhost}. Vedremo i dettagli al riguardo in
sez.~\ref{sec:net_DNS_domain}, quando tratteremo la configurazione per la
risoluzione di un dominio locale. Per verificare il funzionamento del nostro
\textit{caching nameserver} basterà fare una richiesta per un indirizzo fino
ad allora non usato; la prima volta avremo che:
\begin{Console}
piccardi@hain:~$ \textbf{dig gapil.gnulinux.it}
; <<>> DiG 9.7.3 <<>> gapil.gnulinux.it
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29931
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;gapil.gnulinux.it.             IN      A

;; ANSWER SECTION:
gapil.gnulinux.it.      600     IN      A       78.46.114.62

;; AUTHORITY SECTION:
gnulinux.it.            600     IN      NS      ns.gnulinux.it.
gnulinux.it.            600     IN      NS      ns2.gnulinux.it.

;; ADDITIONAL SECTION:
ns.gnulinux.it.         600     IN      A       62.48.34.25
ns2.gnulinux.it.        600     IN      A       217.133.96.194

;; Query time: 233 msec
;; SERVER: 62.48.34.25#53(62.48.34.25)
;; WHEN: Fri Aug 24 16:33:15 2012
;; MSG SIZE  rcvd: 118
\end{Console}
%$
in cui la richiesta effettuata viene soddisfatta in 233~ms, ma se subito dopo
si ripete una seconda interrogazione otterremo:
\begin{Console}
piccardi@hain:~$ \textbf{dig gapil.gnulinux.it}
; <<>> DiG 9.7.3 <<>> gapil.gnulinux.it
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8480
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;gapil.gnulinux.it.             IN      A

;; ANSWER SECTION:
gapil.gnulinux.it.      600     IN      A       78.46.114.62

;; AUTHORITY SECTION:
gnulinux.it.            600     IN      NS      ns.gnulinux.it.
gnulinux.it.            600     IN      NS      ns2.gnulinux.it.

;; ADDITIONAL SECTION:
ns.gnulinux.it.         600     IN      A       62.48.34.25
ns2.gnulinux.it.        600     IN      A       217.133.96.194

;; Query time: 1 msec
;; SERVER: 62.48.34.25#53(62.48.34.25)
;; WHEN: Fri Aug 24 16:33:17 2012
;; MSG SIZE  rcvd: 118
\end{Console}
%$#$$
con i tempi che si riducono drasticamente a 1~ms, che ci mostra nella
maniera più evidente che il nostro \textit{caching nameserver} sta
funzionando.


\subsection{La configurazione di un dominio locale e i file di zona}
\label{sec:net_DNS_domain}

Per illustrare con maggiore dettaglio il funzionamento di \textit{BIND}
vedremo in questa sezione come configurare un proprio dominio. Definiremo un
dominio locale, usabile ad esempio per la risoluzione dei nomi delle macchine
all'interno di una rete locale, ma quanto illustrato si può applicare anche
alla configurazione di un dominio pubblico.  

Per semplicità useremo un dominio completamente astratto,
\texttt{earthsea.ea}, ma definiremo anche la risoluzione inversa per le
macchine della nostra rete. Come in precedenza per il dominio radice, dovremo
usare la direttiva \texttt{zone} per dichiarare le rispettive zone, si
dovranno quindi aggiungere al file di configurazione le direttive:
\begin{FileExample}[label=named.conf]
zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea";
};

zone "168.192.in-addr.arpa" {
        type master;
        file "/etc/bind/db.192.168";
};
\end{FileExample}

Si noti però come questa volta si sia usato come tipo \texttt{master}, in
quanto vogliamo che sia il nostro server ad essere il responsabile della
risoluzione del dominio. La differenza con il precedente tipo \texttt{hint} è
che con \texttt{master} ci si dichiara ``\textsl{padroni}'' del dominio, per
cui le risposte relative ad esso saranno autoritative. Questo significa che
nel file indicato dalla direttiva \texttt{file} dovranno comparire ulteriori
informazioni rispetto a quelle di un elenco di nomi per i quali non è
necessario richiedere all'esterno. 

In genere, per una migliore organizzazione, si tende a mantenere le
definizioni delle zone locali su un file a parte, da includere dal file
principale con la direttiva \texttt{include}, come nell'esempio mostrato in
sez.~\ref{sec:net_named_conf}.  Si noti come si siano definite due zone: una
per la risoluzione diretta, relativa al dominio che abbiamo scelto, ed una per
la risoluzione inversa degli indirizzi privati che stiamo usando (nel nostro
caso le reti \texttt{192.168.0.0} e \texttt{192.168.168.0}) sui nomi del
suddetto dominio.

Per la risoluzione inversa si usa una zona all'interno del dominio
\texttt{in-addr.arpa} che è riservato a questo scopo, in cui si traduce
l'indirizzo IP del quale si vuole effettuare la risoluzione in un nome,
esprimendolo in forma \textit{dotted decimal} con le cifre in ordine
rovesciato.  La richiesta della risoluzione di un indirizzo IP viene così
trasformata in quella di un nome a dominio, ed ovviamente i livelli più bassi
dello stesso corrisponderanno alla parte più significativa del valore numerico
dell'indirizzo.

Abbiamo accennato al paragrafo precedente come nella installazione di
\textit{BIND} sia normalmente prevista la configurazione per la risoluzione in
locale del \textit{localhost}. Questo comporta la presenza dentro
\texttt{named.conf} (o in uno dei file da esso inclusi) di due zone anche per
il dominio \texttt{localhost}, ad esempio dentro la configurazione installata
su una Debian Squeeze si troverà qualcosa del tipo:
\begin{FileExample}[label=named.conf]
zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};
\end{FileExample}

\index{file di zona|(}

I file inclusi con questo tipo di configurazione, che contengono i dati che il
server deve fornire quando viene interrogato (i \textit{resource record} di
cui abbiamo già parlato in sez.~\ref{sec:net_RR_zones}), sono detti
``\textit{file di zona}'' ed hanno un formato standardizzato, definito in
alcune sezioni degli \href{http://www.ietf.org/rfc/rfc1034.txt}{RFC 1034} e
\href{http://www.ietf.org/rfc/rfc1035.txt}{RFC 1035}. Come punto di partenza
per illustrarlo possiamo prendere in considerazione quello usato per il
\texttt{localhost}, così come viene installato su una Debian Wheezy:
\begin{FileExample}[label=db.local]
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
@       IN      A       127.0.0.1
\end{FileExample}
%$

Un primo elemento della sintassi dei file di zona, presente sulla prima riga
dell'esempio precedente, è la possibilità di inserire alcune direttive,
caratterizzate dalla presenza del carattere ``\texttt{\$}'' preposto ad una
parola chiave.  Anche le direttive disponibili sono standardizzate; il loro
elenco, con il rispettivo RFC di definizione, è riportato in
tab.~\ref{tab:zone_file_directives}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} &\textbf{Descrizione}\\
    \hline
    \hline
     \texttt{\$TTL}   & imposta il valore di default del \textit{time to
                          live}, da indicare come argomento; usualmente
                        viene specificato in secondi
                        (\href{http://www.ietf.org/rfc/2308.txt}{RFC
                        2308}).\\ 
     \texttt{\$ORIGIN}& imposta il dominio di base del file di zona
                        (\href{http://www.ietf.org/rfc/rfc1035.txt}{RFC
                        1035}), in genere non la si usa essendo questo già
                        determinato nella dichiarazione della zona.\\ 
     \texttt{\$INCLUDE}& consente di includere il contenuto di un altro file,
                         da indicare come argomento
                         (\href{http://www.ietf.org/rfc/rfc1035.txt}{RFC
                         1035}).\\ 
%     \texttt{}    & .\\
    \hline    
  \end{tabular}
  \caption{Le direttive utilizzabili nei file di zona.}
  \label{tab:zone_file_directives}
\end{table}

Normalmente viene usata solo \texttt{\$TTL}, che permette di impostare, per
tutti i record seguenti, il cosiddetto \textit{time to live}, cioè il tempo
massimo di validità del record nella cache di un \textit{nameserver} (si
ricordi quanto detto al proposito in sez.~\ref{sec:net_DNS_intro}). La
direttiva deve essere necessariamente usata all'inizio del file, prima della
definizione di qualunque \textit{resource record}.  Nel nostro esempio il
tempo è stato specificato in secondi, e corrisponde ad una settimana.  Il
formato con cui può essere specificato un tempo all'interno di un file di
zona, valido in generale e non solo per la direttiva \texttt{\$TTL}, oltre
alla indicazione numerica semplice che indica i secondi, prevede anche l'uso
dei suffissi \texttt{H, D, W} per indicare rispettivamente ore, giorni e
settimane.

Alle eventuali direttive iniziali seguono poi i vari \textit{resource record},
in genere uno per riga, formati da campi separati da spazi o tabulazioni. Il
primo campo deve iniziare dal primo carattere della riga, altrimenti verrà
considerato vuoto. Se necessario si possono specificare i campi su più righe,
racchiudendoli fra parentesi tonde. Infine si possono inserire commenti
ovunque precedendoli con il carattere ``\texttt{;}''. Il formato dei vari
record è simile, e la sintassi generale è la seguente:
\begin{Example}
{<domain>|@|<blank>} [<ttl>] [<class>] <type> <rdata> [<comment>]
\end{Example}

Il primo campo indica il nome di dominio che viene ricercato; esso può essere
immesso esplicitamente, ma se il campo è vuoto (rappresentato nella sintassi
come \texttt{<blank>}) viene usato il nome immesso nella prima riga precedente
non vuota. Infine si può usare il carattere speciale ``\verb|@|'', che viene
automaticamente espanso nel nome della zona indicato dalla dichiarazione
\texttt{zone} che fa riferimento al file. Questa è la cosiddetta
``\textsl{origine}'' che può essere modificata nel corso del file con la
direttiva \texttt{\$ORIGIN}.

Il campo \texttt{ttl} viene di norma omesso, in quanto di solito si usa la
direttiva \texttt{\$TTL} per specificarlo una volta per tutte all'inizio del
file. Il campo \texttt{<class>} indica la classe dei dati del record; nel
nostro caso usando indirizzi Internet sarà sempre \texttt{IN} per tutti i vari
tipi di record, dato che le altre classi non vengono usate. Segue il campo
\texttt{<type>} che definisce il tipo di record e deve essere sempre
specificato usando uno dei valori di tab.~\ref{tab:net_DNS_record_type},
infine segue il campo (o i campi) \texttt{<rdata>} con i dati da inviare in
risposta alle richieste relative al record, il cui formato dipende dal tipo
dello stesso.

L'ordine in cui si dichiarano i vari record non è essenziale, ma è necessario
specificare sempre per primo un record di tipo \texttt{SOA}, che dichiara che
il nostro \textit{nameserver} è \textsl{autoritativo} per quel dominio. Dato
che non ce ne può essere più di uno per file, questo significa anche la
necessità di un file separato per ogni dominio che si vuole definire, che è
comunque una buona pratica di gestione.  In genere poi si prosegue con la
dichiarazione dei record di tipo \texttt{NS} che definiscono i
\textit{nameserver} per il dominio in questione, a cui fanno seguito gli altri
tipi di record.

La prima colonna di un record \texttt{SOA} è il nome del dominio per il quale
si dichiara di avere autorità, nel caso in esempio è stato usato il carattere
speciale ``\verb|@|'', altrimenti si sarebbe dovuto specificare il nome del
dominio completo nella forma \texttt{localhost.}, con il ``\texttt{.}'' finale
in quanto per il \texttt{SOA} i nomi vanno dichiarati in forma assoluta
(facendo riferimento alla radice che è appunto ``\texttt{.}'') segue la
classe, \texttt{IN}, ed il tipo, \texttt{SOA}.  Nel caso di un record
\texttt{SOA} i dati prevedono che si indichi il nome del server che farà da
\textit{nameserver} principale per il dominio e l'indirizzo e-mail del
responsabile, con il ``\texttt{.}'' al posto dell'ordinaria ``\verb|@|''
(nell'esempio riportato l'indirizzo corrisponde a \verb|root@localhost|).

Le restanti informazioni, inserite nell'esempio fra parentesi tonde per
poterle dividere su più righe, sono usate nella replicazione dei dati fra
\textit{nameserver} primario e suoi secondari. Questa è una funzionalità del
protocollo che consente di mantenere delle repliche automatizzate dei dati di
un \textit{nameserver}, aggiornate secondo quanto stabilito da questi
parametri; tratteremo l'argomento in sez.~\ref{sec:bind_secondary_tsig}, dove
esamineremo in dettaglio il significato di questi campi aggiuntivi. Di norma
l'unica informazione da modificare è quella identificata nell'esempio dal
commento \texttt{serial} che indica un numero seriale (crescente) da
aggiornare tutte le volte che si effettua una modifica ai dati della zona.

\index{file di zona|)}

Tornando all'esempio nella riga successiva si dichiara, usando un record
\texttt{NS}, la macchina nel dominio che fa da \textit{nameserver} per lo
stesso, questo richiede il nome della stessa (nome che può essere anche fuori
dal dominio) per il quale però deve esistere una risoluzione diretta con un
record \texttt{A}. In questo nel caso il server DNS viene identificato dal
nome del dominio stesso, ed il suo indirizzo IP viene specificato con un
record \texttt{A} nella riga seguente.

Vista la particolarità del dominio \texttt{localhost}, che ci è servito per
introdurre la sintassi dei file di zona, vediamo un esempio più significativo
su come impostare un dominio per risolvere i nomi delle macchine di una rete
locale. In questo caso si è scelto il dominio \texttt{earthsea.ea} per la rete
\texttt{192.168.0.0/24} e si sono inseriti i relativi dati in un file
\texttt{db.earthsea}, il cui contenuto è:
\begin{FileExample}[label=db.earthsea]
$TTL 86400
@ IN SOA havnor.earthsea.ea. piccardi.earthsea.ea. (
                        2       ; serial
                        10800   ; refresh after 3 hour
                        3600    ; retry after 1 hour
                        604800  ; expire after 1 week
                        86400 ) ; negative cache TTL 1 day
; DNS
@               IN      NS      havnor.earthsea.ea.
; Posta elettronica
                        MX      10 havnor
                        MX      20 gont
; Indirizzi 
ns              IN      CNAME   havnor
www             IN      CNAME   havnor
havnor          IN      A       192.168.0.234
hogen           IN      A       192.168.0.10
lorbaner        IN      A       192.168.0.243
karego-at       IN      A       192.168.0.242
gont            IN      A       192.168.168.10
oppish          IN      A       192.168.168.11
localhost       IN      A       127.0.0.1
\end{FileExample}
%$

Di nuovo si è cominciato con un record di tipo \texttt{SOA} che dichiara
l'autorità per \texttt{earthsea.ea}, in questo caso il \textit{nameserver} è
la macchina \texttt{havnor.earhsea.ea.}, anch'essa identificata dal suo nome
di dominio assoluto. Si tenga conto che se non si usa il nome assoluto al nome
viene sempre aggiunta l'\textsl{origine} della zona, per cui o si usa questa
notazione o si specifica il \textit{nameserver} semplicemente con
\texttt{havnor}. Per l'amministratore del dominio si è indicato che la posta
venga inviata all'indirizzo \texttt{piccardi@earthsea.ea}.

Il secondo record definisce il \textit{nameserver}, cioè
``\texttt{havnor.earthsea.ea.}'' con il punto finale in quanto lo si è scritto
per esteso. Si noti che di nuovo non lo si è definito con l'indirizzo IP
corrispondente, si deve usare un nome che corrisponda ad un record di tipo
\texttt{A}. Nel caso si è specificato un solo record \texttt{NS}, ma se ne
possono definire più di uno se si dispone di più DNS e l'informazione sarà
passata nelle richieste di risoluzione, che potranno essere rivolte ad uno
qualunque dei server della lista. Occorrerà ovviamente che questi forniscano
risposte coerenti, e vedremo come si può ottenere questo in
sez.~\ref{sec:bind_secondary_tsig}.

Il record successivo, di tipo \texttt{MX}, serve a definire a quale macchina
viene inviata la posta per il dominio \texttt{earthsea.ea}, di nuovo si è
specificato \texttt{havnor}, ma stavolta, per dare un esempio di come si possono
scrivere le cose in maniera più compatta, non si è dichiarato il dominio, che
essendo \texttt{blank} corrisponde a quello precedente, e cioè sempre
\texttt{earthsea.ea}, si è tralasciata la classe \texttt{IN} che essendo
quella di default può non essere specificata esplicitamente, ed infine si è
indicato \texttt{gont} senza usare il nome assoluto. Il valore \texttt{10}
inserito prima del nome indica la priorità del server di posta, è possibile
infatti specificare più di un server di posta, con valori diversi, in questo
modo verrà sempre contattato per primo quello con il valore più basso,
passando ai successivi solo in caso di fallimento dei precedenti. Si tenga
presente che anche questi record è opportuno facciano riferimento a nomi
associati a dei record di tipo \texttt{A}.

Infine si sono inseriti i vari record di tipo \texttt{A} contenenti gli
indirizzi associati ai nomi, ed i record di tipo \texttt{CNAME} che
definiscono dei nomi alternativi per le stesse macchine. Per quanto visto
finora il formato di questi record è evidente. Si noti che anche qui si sono
espressi i normi in forma relativa, sfruttando il fatto che il dominio viene
aggiunto automaticamente. 

Una volta analizzato il file di zona per il dominio \texttt{earthsea.ea}
passiamo ad esaminare quello per la risoluzione inversa, che nell'esempio si è
chiamato \texttt{db.192.168}; il suo contenuto è il seguente:
\begin{FileExample}[label=db.192.168]
$TTL 86400
@ IN SOA havnor.earthsea.ea. piccardi.earthsea.ea. (
                        2       ; serial
                        10800   ; refresh after 3 hour
                        3600    ; retry after 1 hour
                        604800  ; expire after 1 week
                        86400 ) ; negative cache TTL 1 day
; DNS
@               IN      NS      havnor.earthsea.ea.
; Indirizzi 
10.0            IN      PTR     hogen.earthsea.ea.
234.0           IN      PTR     havnor.earthsea.ea.
242.0           IN      PTR     karegoat.earthsea.ea.
243.0           IN      PTR     lorbaner.earthsea.ea.
10.168          IN      PTR     gont.earthsea.ea.
11.168          IN      PTR     oppish.earthsea.ea.
\end{FileExample}
%$

Di nuovo si comincia con un record di tipo \texttt{SOA}, sostanzialmente
identico al precedente dato che \textit{nameserver} e amministratore sono gli
stessi.  Si deve definire anche il \textit{nameserver} per questo dominio
inverso, che è sempre \texttt{havnor.earthsea.ea.} ma a differenza del caso
precedente qui specificare \texttt{havnor} non avrebbe funzionato, dato che
siamo in una zona diversa, l'indirizzo assoluto invece funziona in quanto il
dominio è stato già definito nell'altro file.

In questo caso il contenuto del file è costituito da record di tipo
\texttt{PTR} che contengono il nome delle singole macchine, gli indirizzi
devono corrispondere ad un solo nome, quello canonico, e contrariamente a
prima non si possono associare più nomi allo stesso indirizzo. Anche se è
possibile associare due nomi allo stesso IP molti sistemi non sono preparati a
questa evenienza, è bene pertanto escluderla a priori onde evitare
comportamenti inattesi. Inoltre si deve sempre ricordare, se si hanno come
nell'esempio più sottoreti, che i numeri degli indirizzi IP vanno invertiti. 

Una volta aggiunte queste ulteriori configurazioni potremo usare \texttt{host}
per interrogare il server e verificare la correttezza delle risposte:
\begin{Console}
piccardi@gont~$ \textbf{host -t any earthsea.ea}
earthsea.ea has SOA record havnor.earthsea.ea. piccardi.earthsea.ea. 2 10800
 3600 604800 86400
earthsea.ea name server havnor.earthsea.ea.
earthsea.ea mail is handled by 10 havnor.earthsea.ea.
earthsea.ea mail is handled by 20 gont.earthsea.ea.
\end{Console}
%$
ottenendo il risultato voluto, possiamo provare a risolvere un'altra macchina:
\begin{Console}
piccardi@gont~$ \textbf{host lorbaner.earthsea.ea}
lorbaner.earthsea.ea has address 192.168.0.243
\end{Console}
%$
ed infine provare con la risoluzione inversa, ottenendo:
\begin{Console}
piccardi@gont~$ \textbf{host 192.168.0.242}
242.0.168.192.in-addr.arpa domain name pointer karegoat.earthsea.ea.
\end{Console}
%$

Si tenga presente che nonostante negli esempi fatti finora si sia fatto
riferimento ad un dominio locale per una rete privata, le stesse direttive e
lo stesso formato dei file di zona si possono utilizzare qualora di abbia a
che fare con indirizzi IP pubblici e nomi a dominio correttamente registrati,
la configurazione è esattamente la stessa.

La differenza è che mentre per il dominio \texttt{earthsea.ea} non è possibile
ottenere una delegazione, dato che i \textit{Root DNS} non riconoscono il
dominio di primo livello \texttt{.ea}, per cui anche se il nostro DNS risponde
correttamente, nessuno dall'esterno potrà raggiungerlo dato dalla radice
dell'albero dei nomi non esiste nessun percorso per raggiungerlo. Se avessimo
usato \texttt{fountainpen.it} invece, essendo questo registrato presso il
server del NIC italiano che risponde per i \texttt{.it}, i dati della nostra
zona sarebbero diventati accessibili a chiunque li avesse richiesti con una
interrogazione diretta verso questo dominio.


\section{Configurazioni avanzate}
\label{sec:net_adv_bind}

Tratteremo in questa sezione alcune configurazioni più avanzate di
\textit{BIND}, come la gestione della delegazione di una zona ad un altro DNS,
la gestione di server secondari e l'uso delle chiavi per la comunicazione fra
diversi server, l'uso delle viste per fornire risposte diverse a seconda di
chi effettua le richieste e la gestione della sicurezza con le estensioni
DNSSEC.


\subsection{La delegazione di una zona}
\label{sec:net_bind_delagation}

Come illustrato in sez.~\ref{sec:net_DNS_intro} una delle caratteristiche
fondamentali del funzionamento del DNS è la possibilità di \textsl{delegare}
la risoluzione di parti dell'albero dei nomi a dominio ad altri server, in
modo da distribuire sia il carico di rete che quello amministrativo. La
delegazione consiste semplicemente nel dire, sul server DNS autoritativo per
il dominio di un certo livello, quale sarà il server DNS da usare per un suo
sottodominio, in sostanza si tratta di definire in maniera opportuna dei record
\texttt{NS} e configurare le risposte per i DNS interessati.

Il problema deve ovviamente essere affrontato da due lati, quello del server
DNS che esegue la delega, e quello del server che viene delegato. Per
quest'ultimo come accennato la configurazione sarà una analoga a quella già
illustrata in sez.~\ref{sec:net_DNS_domain}, in cui invece di usare un dominio
interno per la propria zona locale senza curarsi di cosa può stare al di
sopra, si userà quello che viene delegato dal primo server.  L'unica
accortezza in questo caso è assicurarsi che all'interno di detto dominio
vengano indicati dei record \texttt{NS} con una risoluzione coerente con
quella indicata dal server che effettua la delega.

\itindbeg{glue~records}

Per questo motivo la \textsl{delegazione} attiene sostanzialmente alla
configurazione del server responsabile per un certo dominio, che potrà
effettuarla solo per un suo sottodominio. Si tenga presente inoltre che una
volta che si delega un sottodominio i nomi al suo interno non possono più
essere inseriti nello stesso file di zona in cui si è eseguita la delega,
andando a far parte di una \textsl{zona di autorità} diversa. Fanno eccezione
a questa regola i cosiddetti \textit{glue records}, che permettono di evitare
una dipendenza circolare quando si delega una zona usando per i relativi DNS
dei nomi in quella zona.

Ad esempio se \texttt{ns.truelite.it} è il server DNS della zona
\texttt{truelite.it}, c'è il problema di come avere l'IP con cui contattarlo
per ottenere la sua risoluzione, dato che è lui che dovrebbe fornirlo. Questo
problema viene superato fornendo al DNS che effettua la delegazione di
\texttt{truelite.it} non solo il record \texttt{NS} per \texttt{truelite.it},
ma anche il record \texttt{A} per \texttt{ns.truelite.it}, ed è questo che
viene chiamato \textit{glue record}, in quanto fornisce la ``colla'' fra i due
livelli.

\itindend{glue~records}

La configurazione effettiva della delegazione di una zona è pertanto da
eseguire nel DNS che gestisce il dominio di livello superiore rispetto a
quello che si intende delegare. Non esistono direttive specifiche per
\texttt{named} al riguardo, dato che, come appena illustrato, si tratta solo
di creare gli opportuni record nella zona ``\textsl{delegante}''.  Supponiamo
allora di avere il controllo del dominio \texttt{.trl} e di voler delegare le
zone \texttt{fi.trl} e \texttt{bz.trl}; in questo caso il file di zona
relativo a \texttt{.trl} sarà qualcosa del tipo:
\begin{FileExample}[label=db.trl]
$TTL    604800
@       IN      SOA     ns.trl. sistemi.truelite.it. (
                     2006061601         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@               IN      NS      ns
ns              IN      A       192.168.1.2
; delegazione
fi              IN      NS      ns.fi.trl.
ns.fi.trl.      IN      A       192.168.1.2
bz              IN      NS      ns.bz.trl.
ns.bz.trl.      IN      A       192.168.3.42
\end{FileExample}
%$

Come si può notare la delegazione si esegue semplicemente definendo due record
\texttt{NS} con i nomi dei server DNS delle due zone delegate, in questo caso
si sono anche specificati come \textit{glue record} i due record \texttt{A}
per i nomi \texttt{ns.bz.trl} e \texttt{ns.fi.trl}; se si fossero usati nomi
relativi ad una zona diversa da quella delegata (ad esempio
\texttt{nsfi.truelite.it} o \texttt{nsbz.truelite.it}) questo non sarebbe
stato necessario.

Una volta eseguita questa impostazione basterà configurare le due zone
\texttt{fi.trl} e \texttt{bz.trl} sui server DNS indicati dai record
\texttt{A}, ed il gioco è fatto. Di nuovo non è necessaria nessuna direttiva
specifica, basterà dichiarare le zone e utilizzare valori coerenti con quelli
indicati nel precedente esempio.


\subsection{La gestione dei secondari e le \textit{transition signature}}
\label{sec:bind_secondary_tsig}

Una delle caratteristiche più interessanti del DNS è quella che il protocollo
consente di gestire la distribuzione di carico e la ridondanza.  Come
accennato in sez.~\ref{sec:net_DNS_domain} è possibile dichiarare in una zona
più di un \textit{nameserver} ed il protocollo prevede che ad ogni richiesta
venga fornita la lista di tutti \textit{nameserver}, ruotandone però
l'ordinamento, in modo che ogni volta si abbia come primo riferimento un
server diverso. Dato che i client usano la lista in sequenza, iniziando dal
primo server elencato, il risultato è che il carico verrà distribuito su tutti
i componenti.

Ovviamente perché ciò funzioni correttamente occorre che le risposte di tutti
i \textit{nameserver} siano coerenti fra loro; ed anche se è sempre possibile
installare dei server con configurazioni identiche, sin dalla nascita del
protocollo sono stati previsti dei meccanismi per mantenere coerenti ed
aggiornati i dati attraverso la replicazione di tutte le informazioni di una
zona.

\index{trasferimento di zona|(}

Come accennato in sez.~\ref{sec:net_RR_zones} il protocollo DNS prevede un
meccanismo, chiamato \textsl{trasferimento di zona}, realizzato con delle
specifiche richieste (AXFR e IXFR) che consentono ad un server, detto
\textsl{secondario}, di ottenere tutti i dati di una zona interrogando un
altro server, detto \textsl{primario} che fa da riferimento per la stessa. In
questo modo i dati della zona possono essere gestiti solo sul server
\textsl{primario} ed i vari \textsl{secondari} verranno sincronizzati
automaticamente.

Il protocollo prevede che siano sempre i secondari richiedere i dati al
primario. Inizialmente questo avveniva ad intervalli fissi, secondo quanto
indicato nei dati del record \texttt{SOA} di cui ora possiamo approfondire il
significato. Se riprendiamo l'esempio di sez.~\ref{sec:net_DNS_domain} per il
dominio \texttt{earthsea.ea}, usando stavolta due \textit{nameserver}, avremo:
\begin{FileExample}[label=db.earthsea]
@ IN SOA havnor.earthsea.ea. piccardi.earthsea.ea. (
                        3       ; serial
                        10800   ; refresh after 3 hour
                        3600    ; retry after 1 hour
                        604800  ; expire after 1 week
                        86400 ) ; negative cache TTL 1 day
; DNS
@               IN      NS      havnor.earthsea.ea.
@               IN      NS      hogen.earthsea.ea.
...
\end{FileExample}

Come avevamo detto il primo argomento del record \texttt{SOA} indica il
\textit{nameserver} principale della zona; ora possiamo essere più precisi e
specificare che deve essere il nome del server \textsl{primario} per il
dominio. Il campo successivo, che indica l'email dell'amministratore non è
rilevante per la gestione dei secondari, lo sono invece i campi successivi,
che si sono scritti uno per riga, identificandoli nei commenti con il nome che
hanno nelle definizioni del protocollo.

Il terzo campo è il cosiddetto \textsl{seriale}, da esprimersi con un intero a
32 bit, che serve da numero di versione dei dati della zona. Si tratta di un
campo fondamentale perché un secondario inizierà un trasferimento di zona
soltanto se il valore di questo campo, che ottiene interrogando il primario, è
maggiore di quello presente nei dati di cui già dispone. Probabilmente
l'errore di configurazione più comune nella gestione dei DNS è quello di
dimenticarsi di aumentare il seriale dopo aver modificato i dati di una zona:
se non lo si fa i secondari non si aggiorneranno mai.

L'unico requisito al riguardo è usare un valore crescente ad ogni
modifica;\footnote{in realtà il confronto viene fatto con una aritmetica
  modulare piuttosto complessa descritta in dettaglio
  nell'\href{http://www.ietf.org/rfc/rfc1982.txt}{RFC 1982}, usando questa
  aritmetica aumentare il valore del seriale di più di $2^{31}-1$ significa
  ottenere un valore \textsl{più piccolo} di quello da cui si è partiti;
  benché con i valori che si usano normalmente il confronto coincida con il
  normale ordinamento numerico, si tenga presente la possibilità di avere casi
  in cui ciò non avviene.} anche se si può usare un semplice progressivo, è
invalso l'uso di scriverlo come numero di dieci cifre nella forma
\texttt{AAAAMMGGVV} per tracciare la data (con le ultime due cifre da usare
con un progressivo se vi sono più modifiche nello stesso giorno) dei
cambiamenti fatti.

Il quarto campo, \textit{refresh}, indica ogni quanto tempo un secondario deve
ricontattare il primario per chiedere aggiornamenti. Il quinto campo,
\textit{retry}, indica ogni quanti secondi ricontattare il primario in caso di
fallimento di una richiesta di aggiornamento, ed il sesto, \textit{expire}, il
tempo massimo per cui un secondario può continuare a considerare valide le
proprie informazioni nel caso non riesca più a ricontattare il primario;
passato questo tempo il secondario cesserà di rispondere per quella
zona. Infine l'ultimo campo, che non attiene alla gestione dei secondari,
indica il tempo per cui deve essere mantenuta in cache una risposta negativa
ad un tentativo di risoluzione. Tutti i tempi sono in secondi, ma il formato
dei file di zona supporta i suffissi visti per \texttt{\$TTL} per usare ore,
giorni e settimane.

Originariamente la tempistica di aggiornamento dei secondari era affidata
esclusivamente alle interrogazioni periodiche impostate con il campo
\textit{refresh} del \texttt{SOA}; oggi quel campo viene usato principalmente
per verificare che la comunicazione con il primario non si è interrotta mentre
la propagazione dei cambiamenti viene eseguita con il meccanismo del
\textit{notify}, introdotto con
l'\href{http://www.ietf.org/rfc/rfc1996.txt}{RFC 1996}, in cui è il server
primario che notifica ai secondari un possibile cambiamento di zona. Il
meccanismo prevede che nel caricare o ricaricare una zona un server primario
invii a tutti i server citati nei record \texttt{NS} della stessa (con
l'eccezione di quello riportato come DNS primario nel primo campo del record
\texttt{SOA}) un messaggio di \textit{notify}.  Alla ricezione del messaggio
di \textit{notify} sarà compito dei secondari richiedere il record
\texttt{SOA} al primario, verificare se il seriale è stato incrementato e nel
caso eseguire il trasferimento di zona.

\index{trasferimento di zona|)}

Questo comportamento di default può essere modificato utilizzando, nella
dichiarazione della zona, la direttiva \texttt{also-notify} che consente di
indicare una lista di server aggiuntivi (indicati per indirizzo IP) cui
inviare il messaggio di \textit{notify};\footnote{in realtà la direttiva si
  può usare anche dentro la direttiva \texttt{options} per definire una lista
  globale, ma la cosa non ha molto senso e di default è vuota.} in questo modo
si possono tenere aggiornati anche dei secondari ``\textsl{privati}'' non
dichiarati nei file di zona come \textit{nameserver} per la stessa.

Dato che le richieste di trasferimento di zona possono essere onerose per il
primario, che deve inviare tutti i dati, in genere si suggerisce di abilitarle
esplicitamente solo per i server che effettivamente si andranno ad
utilizzare. La direttiva che controlla chi può richiedere un trasferimento di
zona è \texttt{allow-transfer}, che prende come argomento una \textit{address
  match list}, e può essere indicata sia livello generale (all'interno di
\texttt{options}) che nella dichiarazione di una zona. Dato che il default
consente il trasferimento a chiunque occorrerà impostarla a \texttt{none}
dentro \texttt{options}, e poi abilitarla in maniera specifica in ciascuna
zona per i secondari della stessa.

Per questo se ad esempio vogliamo creare su \texttt{hogen} un secondario per
il dominio \texttt{earthsea.ea}, dovremo avere su \texttt{havnor}, che fa da
primario per lo stesso, una configurazione come la seguente:
\begin{FileExample}[label=named.conf]
options {
        ...
        allow-transfer { none; };
        ...
};
zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea";
        allow-transfer { 192.168.0.10; };
};
\end{FileExample}

Una volta predisposto il primario a consentire i trasferimenti di zona solo ai
secondari desiderati, si tratta di configurare questi ultimi. In questo caso
si tratta dichiarare una zona di tipo \texttt{slave} ed indicare nella stessa
quali sono i server a cui fare riferimento come primari.  Questo viene fatto
con la direttiva \texttt{masters} che prende come argomento una lista di
indirizzi o di nomi di chiavi (indicati con la parola chiave \texttt{key}) che
identificano i primari. 

Inoltre come un primario può decidere da quali secondari può accettare un
trasferimento di zona, anche un secondario può decidere da quali primari
accettare i messaggi di \textit{notify}. Questo viene fatto con la direttiva
\texttt{allow-notify} che di nuovo accetta come argomento una \textit{address
  match list}. In questo caso però normalmente non è necessario utilizzarla
dato che il default prevede che vengano accettati i messaggi solo dai server
dichiarati nella direttiva \texttt{masters}. 

Tornando all'esempio del dominio \texttt{earthsea.ea}, per impostare come 
secondario la macchina \texttt{hogen} dovremo inserire nel \texttt{named.conf}
della stessa una configurazione del tipo:
\begin{FileExample}[label=named.conf]
zone "earthsea.ea" {
        type slave;
        file "db.earthsea.ea";
        masters { 192.168.0.234; };
};
\end{FileExample}

Si noti come questo caso la zona venga dichiarata come di tipo \texttt{slave}
mentre l'istruzione \texttt{file} indica un file su cui verranno scritti i
dati della zona. La direttiva in questo caso non è necessaria, dato che BIND
può comunque richiedere i dati al primario e tenerli in memoria, ma la loro
registrazione su un file consente di averli già pronti in caso di riavvio del
servizio senza doverli riscaricare tutte le volte. Infine con
\texttt{masters} si è indicato l'indirizzo IP del primario.

Il contenuto del file su cui vengono salvati i dati in questo caso viene
generato direttamente da BIND (nel solito formato dei file di zona) e non deve
essere modificato esternamente.  Nelle versioni più recenti del server (a
partire dalla 9.9) per efficienza di default questi dati vengono salvati in un
formato binario che non è immediato da leggere, si può tornare però al veccho
default aggingendo la direttiva:
\begin{Example}[label=named.conf]
masterfile-format text;
\end{Example}

Alternativamente il comando \index{comando!\texttt{named-compilezone}}
\texttt{named-compilezone} può essere utilizzato per convertire il file
binario nel formato tradizionale. Il comando viene usato normalmente per
verificare la correttezza di un file di zona (come l'analogo
\index{comando!\texttt{named-checkzone}} \texttt{named-checkzone} che esegue
solo il controllo) generando al contempo un output normalizzato della stessa,
in un formato a scelta. Entrambi i comandi prendono come argomenti il nome
della zona ed quello di un file coi relativi dati di cui verificare la
sintassi; \texttt{named-checkzone} si limita alla verifica stampando un
messaggio di OK se è corretta o segnalando eventuali errori altrimenti,
\texttt{named-compilezone} richiede anche che si indichi, con l'opzione
\texttt{-o}, un file di output su cui salvarla, o \texttt{-} per stamparla
sullo \textit{standard output}.  Di default l'output di
\texttt{named-compilezone} è quello testuale classico, opportunamente
normalizzato in modo da essere identico per zone che esprimono gli stessi
contenuti. Ma con l'opzione \texttt{-f} si può indicare un formato diverso per
il file che contiene la zona (quello salvato nei secondari è \texttt{raw}, il
default è \texttt{text}), mentre con \texttt{-F} si può indicare un formato
diverso per il file generato in uscita.

Le configurazioni appena illustrate sono perfettamente funzionali, ma
soffrono, come del resto tutto il protocollo del DNS, di un fondamentale
problema di sicurezza dovuto al fatto che non esiste nessuna forma di verifica
o autenticazione delle informazioni. Questo significa ad esempio che chiunque
possa spacciarsi per un primario (falsificando l'indirizzo IP) potrebbe
fornire dati ``\textsl{opportunamente}'' sbagliati ad un secondario, col
risultato di compromettere completamente il contenuto di una zona.

Il problema è del tutto generale e riguarda anche la comunicazione di
eventuali risposte verso i client (vedremo in sez.~\ref{sec:bind_dnssec} come
si affronta in quel caso) ma la compromissione di una zona su un secondario è
un problema assai più serio (in quanto colpirà chiunque gli si rivolga) e la
soluzione è relativamente semplice, per cui la tratteremo immediatamente. 

\itindbeg{transition signature}

Per ovviare alla mancanza di sicurezza sulla autenticità dei dati in una
comunicazione come quella che avviene fra un primario ed un secondario, è
stata introdotta con l'\href{http://www.ietf.org/rfc/rfc2845.txt}{RFC 2845}
una estensione del protocollo, denominata \textit{transition signature}
(TSIG), che consente di firmare tutti i pacchetti scambiati fra due server,
facendo ricorso ad una chiave simmetrica condivisa, così da attestarne
l'autenticità.\footnote{in questo caso, essendo comunque scambiati dati
  pubblici, non interessa garantire la riservatezza della comunicazione, le
  \textit{transition signature} pertanto forniscono solo l'autenticazione.}

Le chiavi vengono definite con la direttiva primaria \texttt{key} già vista in
sez.~\ref{sec:net_named_conf}, ed oltre che per le \textit{transition
  signature} vengono usate anche per le comunicazioni sui canali di controllo
definiti con la direttiva \texttt{controls}; un esempio si trova proprio nel
file \texttt{rndc.key} citato in sez.~\ref{sec:net_DNS_management}. La
direttiva richiede un identificativo della chiave, che poi verrà utilizzato
per referenziarla, seguita da un blocco in cui si specifica l'algoritmo di
crittografia con cui deve essere usata (uno di quelli nella prima colonna di
tab.~\ref{tab:dnssec-keygen_algo_bits}) con la direttiva \texttt{algorithm},
ed il valore della chiave con la direttiva \texttt{secret}, quest'ultimo deve
essere espresso con una stringa codificata in \textit{base64}. Un esempio di
definizione potrebbe essere il seguente:
\begin{FileExample}[label=tsig.key]
key "transfer-key" {
    algorithm hmac-sha256;
    secret "0St2Hv5W9InKGqFCwYbwNXX/8At+EXyZ+5Z6o7G+x0k=";
};
\end{FileExample}


Dato che ogni chiave deve rispettare le dimensioni massime previste
dall'algoritmo, e deve essere il più casuale possibile, per generarle viene
fornito un apposito programma, \index{comando!\texttt{dnssec-keygen}}
\texttt{dnssec-keygen}, che serve anche per le chiavi che consentono di
firmare i dati di una zona, su cui torneremo in
sez.~\ref{sec:bind_dnssec}). Il comando richiede che indichi l'algoritmo
crittografico che si intende utilizzare con l'opzione \texttt{-a} e la
dimensione della chiave in bit con l'opzione \texttt{-b} (che non può
corrispondere a quella prevista dell'algoritmo crittografico scelto).  Nel
caso di chiavi da utilizzare per le \textit{transition signature} gli
algoritmi disponibili e le relative dimensioni sono illustrati in
tab.~\ref{tab:dnssec-keygen_algo_bits}. Si deve inoltre indicare con l'opzione
\texttt{-n} il tipo di chiave come \texttt{HOST} dato che servirà per
identificare delle macchine.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Algoritmo} &\textbf{Dimensione}\\
    \hline
    \hline
     \texttt{hmac-md5}   & 128\\
     \texttt{hmac-sha1}  & 160\\
     \texttt{hmac-sha224}& 224\\
     \texttt{hmac-sha256}& 256\\
     \texttt{hmac-sha384}& 384\\
     \texttt{hmac-sha512}& 512\\
    \hline    
  \end{tabular}
  \caption{Algoritmi utilizzabili e dimensioni massime delle chiavi per le
    \textit{transition signature}}. 
  \label{tab:dnssec-keygen_algo_bits}
\end{table}

Unico argomento del comando è un nome associato alla chiave, che in questo
caso può essere qualunque, ma si riflette comunque nei nomi dei due file su
cui verranno scritti i risultati, il cui prefisso viene stampato sullo
\textit{standard output}. Il comando infatti nasce per la gestione della firma
dei dati delle zone, che viene eseguita con crittografia a chiave asimmetrica,
per cui genera sempre un file \texttt{.key} ed un file \texttt{.private}
adatti a quello scopo, anche nel caso lo si usi per generare le chiavi
simmetriche per le \textit{transition signature}, per cui occorre estrarsi le
informazioni che servono per poterle inserire in una direttiva \texttt{key}.

La prima informazione è l'algoritmo crittografico, vale a dire il valore
passato all'opzione \texttt{-a}, il secondo è il valore della chiave, che può
essere ottenuto direttamente da uno qualunque dei due file (ad esempio viene
riportato nella terza riga del file \texttt{.private}, di seguito a
\texttt{Key:}). Ma in questo caso è probabilmente più chiaro un esempio; per
generare la chiave definita nell'estratto di file riportato in precedenza si è
usato il seguente comando:
\begin{Console}
root@hogen:~# \textbf{dnssec-keygen -a hmac-sha256 -b 256 -n HOST -r /dev/urandom prova}

Kprova.+163+44257
\end{Console}
che ha prodotto i due file \texttt{Kprova.+163+44257.key} e
\texttt{Kprova.+163+44257.secret}, ed in questo caso il valore della direttiva
\texttt{algorithm} è \texttt{hmac-sha256}, mentre il valore della direttiva
della direttiva \texttt{secret} si è preso dal file appena generato:
\begin{FileExample}[label=Kprova.+163+44257.private]
Private-key-format: v1.3
Algorithm: 163 (HMAC_SHA256)
Key: 0St2Hv5W9InKGqFCwYbwNXX/8At+EXyZ+5Z6o7G+x0k=
Bits: AAA=
Created: 20150306111524
Publish: 20150306111524
Activate: 20150306111524
\end{FileExample}

Una volta definita la chiave per utilizzarla è necessario indicare al proprio
server di usarla per le comunicazioni con un altro server usando la direttiva
\texttt{server}. Questa prevede come argomento l'indirizzo IP dell'altro
server con cui si vuole comunicare utilizzando le \textit{transition
  signature}, seguito dall'indicazione della chiave da usare, indicata nel
blocco seguente con la direttiva \texttt{keys}.\footnote{benché la sintassi
  della direttiva \texttt{keys} consenta di indicare più chiavi, soltanto la
  prima verrà utilizzata. } La direttiva si può indicare a livello globale, e
verrà utilizzata per tutte le comunicazione con quel corrispondente o a
livello di una vista (torneremo sull'argomento in sez.~\ref{sec:bind_view})
nel qual caso si applicherà solo alle comunicazioni coi client previsti in
detta vista.

\itindend{transition signature}

Nel caso di configurazione di un secondario questo significa che si dovrà
configurare quest'ultimo per indicare la chiave che userà per rivolgersi al
primario, e viceversa. Posto che su entrambi sia presente il file
\texttt{tsig.key} con la definizione della chiave (nei seguenti esempi si
suppone sotto \texttt{/etc/bind}) significa che si dovranno modificare le
configurazioni viste in precedenza per l'uso della chiave. Le modifiche più
semplici sono quelle sul secondario, basterà aggiungere qualcosa del tipo:
\begin{FileExample}[label=named.conf]
include "/etc/bind/tsig.key";
server 192.168.0.234 {
   keys { transfer-key; };
};
\end{FileExample}
lasciando invariata la dichiarazione della zona, mentre sul primario, oltre
alle direttive equivalenti, occorrerà anche indicare l'uso della chiave per
restringere l'accesso ai trasferimenti di zona con qualcosa del tipo:
\begin{FileExample}[label=named.conf]
include "/etc/bind/tsig.key";
server 192.168.0.10 {
   keys { transfer-key; };
};
zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea";
        allow-transfer { key transfer-key; };
};
\end{FileExample}
ed in questo caso si autorizzano in generale i trasferimenti indicando la
chiave, che, aggiungendo altrettante direttive \texttt{server}, potrà valere
anche nel caso di più di un secondario.


\subsection{La gestione delle \textsl{viste} del DNS}
\label{sec:bind_view}

Una esigenza molto comune, presente quando si ha una rete locale ed un insieme
di macchine pubbliche, è quella di poter usare il DNS per il proprio dominio
per poter risolvere le macchine interne senza che i relativi dati siano
pubblicati su Internet, e quella di poter fare avere una risoluzione diversa
dello stesso nome (ad esempio con un IP privato o con un IP pubblico) a
seconda della macchina da cui proviene l'interrogazione. 

Questa funzionalità è quella che in gergo viene chiamata \textit{split
  horizon} o \textit{split view}, e consente di presentare risoluzioni diverse
di un dominio a seconda di chi effettua l'interrogazione. Per realizzarla con
BIND è disponibile la direttiva primaria \texttt{view} che consente, con le
ulteriori sotto-direttive \texttt{match-clients} e \texttt{match-destinations}
di presentare diversi contenuti a seconda dell'indirizzo da cui proviene la
richiesta o a cui questa viene effettuata. 

Entrambe le direttive richiedono come argomento una \textit{address match
  list} e definiscono l'ambito di applicazione della direttiva \texttt{view}
che le contiene, con la prima si possono selezionare le risposte in funzione
dei client che effettuano la richiesta, con la seconda fornire risposte
diverse a seconda dell'IP del server a cui vengono fatte le richieste. Se usate
tutte e due in una stessa vista le richieste dovranno corrispondere a
entrambe.

Si tenga presente che quando si decide di utilizzare una configurazione che
prevede le viste, le zone possono essere dichiarate solo all'interno di una
vista. Questo significa che se si vuole presentare un contenuto indipendente
dalla vista occorrerà comunque definirne, in fondo alle altre, una generica
che comprenda tutti gli indirizzi possibili cui applicare le configurazioni di
default. Le viste infatti vengono processate nell'ordine in cui vengono
scritte nel file di configurazione, e per fornire una risposta viene
utilizzata la prima per cui si ha una corrispondenza.

Una volta definita una vista tutte le direttive di configurazione specificate
al suo interno verranno utilizzate solo per le richieste che corrispondono
alla selezione effettuata. Oltre alla definizione delle zone, si possono
utilizzare all'interno di \texttt{view} buona parte delle direttive di
\texttt{options}, e la direttiva \texttt{server} per impostare l'uso delle
\textit{transition signature}.

Il caso più comune di uso delle viste è quello per cui si usano risoluzioni
diverse a seconda che la richiesta provenga dalla propria rete locale, o dal
internet, in tal caso conviene sempre fare uso, per la gestione delle
richieste, di opportune ACL per definire le proprie reti. Se allora si
avessero nei file \texttt{earthsea.ea.int} ed \texttt{earthsea.ea.ext}
rispettivamente le risoluzioni interna ed esterna per il dominio
\texttt{earthsea.ea}, si potrebbe definire una \textit{split view} sul server
con qualcosa del tipo:
\begin{FileExample}[label=named.conf]
acl LANs { 192.168.0.0/24; 192.168.168.0/24; 127.0.0.1; }
view "internal" {
   match-clients { LANs; };
   recursion yes;
   zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea.int";
   };
};
view "internet" {
   match-clients { any; };
   recursion no;
   zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea.ext";
   };
};
\end{FileExample}

Un problema che si pone con la configurazione appena illustrata, è la
configurazione di un eventuale secondario, dato che questo otterrebbe una
comunque il contenuto di una delle due zone definite, a seconda che il suo IP
ricada o meno nell'elenco di reti definiti con la ACL \texttt{LANs} e non
potrebbe pertanto a sua volta gestire una \textit{split view}. Fintanto che la
selezione è fatta solo sulla base di indirizzi IP non esiste una soluzione a
questo problema, ma l'uso delle \textit{transition signature} viste in
sez.~\ref{sec:bind_secondary_tsig} ci consente di risolvere il problema.

La soluzione consiste nel fare usare ai server due chiavi separate, una per la
zona interna ed una per la zona esterna. In tal caso occorrerà usare la
direttiva \texttt{server} in ciascuna delle due viste per indicare l'uso della
rispettiva chiave, ed effettuare la selezione con \texttt{match-clients}
escludendo la chiave non voluta. Se pertanto si sono definite le due chiavi
\texttt{int-key} ed \texttt{ext-key} si potrà usare sul primario questa
configurazione:
\begin{FileExample}[label=named.conf]
acl LANs { 192.168.0.0/24; 192.168.168.0/24; 127.0.0.1; }
view "internal" {
   match-clients { key int-key; !key ext-key; LANs; };
   server "192.168.0.10" { keys int-key; };
   recursion yes;
   zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea.int";
   };
};
view "internet" {
   match-clients { key ext-key; !key int-key; any; };
   server "192.168.0.10" { keys ext-key; };
   recursion no;
   zone "earthsea.ea" {
        type master;
        file "/etc/bind/db.earthsea.ea.ext";
   };
};
\end{FileExample}
mentre per il secondario basterà applicare la corrispondente:
\begin{FileExample}[label=named.conf]
acl LANs { 192.168.0.0/24;  192.168.168.0/24; 127.0.0.1; }
view "internal" {
   match-clients { key int-key; !key ext-key; LANs; };
   server "192.168.0.234" { keys int-key; };
   recursion yes;
   zone "earthsea.ea" {
        type slave;
        file "db.earthsea.ea.int";
        masters { 192.168.0.234; };
   };
};
view "internet" {
   match-clients { key ext-key; !key int-key;  any; };
   server "192.168.0.234" { keys ext-key; };
   recursion no;
   zone "earthsea.ea" {
        type slave;
        file "db.earthsea.ea.ext";
        masters { 192.168.0.234; };
   };
};
\end{FileExample}



\subsection{Le estensioni DNSSEC}
\label{sec:bind_dnssec}


Il protocollo DNS, nonostante il suo ruolo essenziale per il funzionamento di
Internet, è da sempre soggetto ad alcuni problemi di sicurezza sostanzialmente
originati dal fatto che tutta l'informazione fornita dal servizio non è in
alcun modo autenticata. 


% LocalWords:  DNS sez nameserver com org it google softwarelibero truelite NS
% LocalWords:  cache root naming authority caching CNAME SOA PTR TXT AAAA IPv
% LocalWords:  SRV tab host dig querytype options name resolver resolv conf ANY
% LocalWords:  address type bind named UDP TCP Paul Vixie Consortium log acl
% LocalWords:  runlevel system RedHat Slackware debug logging syslog Sid This
% LocalWords:  is the primary configuration for please read information of and
% LocalWords:  structure files versions later BEFORE you customize this issues
% LocalWords:  verbosity outside our control category servers null cname proxy
% LocalWords:  hint localhost DiG global printcmd Got answer HEADER opcode qr
% LocalWords:  NOERROR flags aa rd ra ADDITIONAL QUESTION SECTION query error
% LocalWords:  consumattori msec WHEN MSG SIZE rcvd forwarders earthsea ea addr
% LocalWords:  dotted decimal resource RR TTL Refresh Retry Expire to live ttl
% LocalWords:  blank class rdata comment db refresh after hour retry expire ns
% LocalWords:  gont oppish hogen lorbaner karegoat any Wed allow transfer FQDN
% LocalWords:  masters fully qualified domain Debian gnulinux fig ICANN names
% LocalWords:  corporation assigned numbers trl DNSSEC NIC Resorce SMTP IANA CH
% LocalWords:  HINFO KEY SIG client domain has handled cmd version but debian
% LocalWords:  recursion requested not available rndc reload retransfer stats
% LocalWords:  reconfig addzone delzone local definitions here key controls
% LocalWords:  view Squeeze just adding zones please that RFC access list PDF
% LocalWords:  CentOS recursive glue records AXFR IXFR an Fri flush CIDR auth
% LocalWords:  localnets internals external Wheezy validation conform listen
% LocalWords:  pathname port source transition signatures signature havnor
% LocalWords:  fountainpen notify also TSIG algorithm hmac sha dnssec keygen
% LocalWords:  format keys split horizon clients destinations yes enable


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "corso"
%%% End: 
