Indice
- Introduzione
- Risoluzione locale su UNIX
- Che cos'è e a che cosa serve il DNS
- Installazione
- Directory di configurazione
- Caching Nameserver e DNS autoritario
- Architettura di esempio
- Trasferimenti di zona, aggiornamenti di record e sicurezza
- DNS e crittografia a chiave pubblica
- Architettura dell'esempio
Introduzione
Questa guida spiega come configurare un server DNS.
Prima di cominciare vale la pena di spendere due parole sui requisiti di un server Web.
Tenete conto che probabilmente vi servirà hardware dedicato, se possibile scegliete una soluzione appositamente progettata per il servizio che dovrete ospitare.
Prendetevi il tempo necessario per pianificare un corretto partizionamento del disco.
Possibilmente dedicate una partizione apposita per /var/log ed una specifica per /var/cache/bind.
Risoluzione locale su UNIX
La Risoluzione dei nomi hosts viene generalmente affidata al file locale presente su ciascuna macchina, il file /etc/hosts. Questo file contiene il puntamento diretto delle macchine della rete.
Vantaggi: risoluzione immediata perché tutti gli hosts di una rete devono possedere lo stesso file /etc/hosts per comunicare.
Svantaggi: vulnerabilità perché se un host viene attaccato e viene violato il file /etc/hosts l'aggressore conoscerà tutte le macchine della rete.
Che cos'è e a che cosa serve il DNS
In una rete di computer ciascun nodo viene localizzato utilizzando il suo indirizzo IP, che è un numero formato da quattro ottetti separati da punti (ad esempio, 192.168.20.1).
Tale sistema di localizzazione non è conveniente per le persone, in quanto è molto più facile ricordare un nome piuttosto che un complicato numero formato dai quattro ottetti come indicato sopra.
A tal proposito è stato introdotto un servizio di nominazione dei nodi di una rete, servizio che consente di raggiungere un nodo conoscendone il nome.
Tale servizio tuttavia comporta la necessità di centralizzare il controllo dei nomi dei nodi di un sottoalbero di una rete su un singolo host (il nodo radice di quel sottoalbero).
Questo nodo radice contiene i nomi e gli indirizzi IP di tutti i nodi presenti nel sottoalbero e viene chiamato server dei nomi o DNS.
Naturalmente ogni nodo radice di un dato sottoalbero deve contenere un riferimento al nodo radice dell'intero albero della rete (il sevrer dei nomi globale), e questi conterrà gli indirizzi ed i nomi di tutti questi sottonodi radice dei vari sottoalberi.
Tutti i client (nodi di un sottoalbero) conterranno a loro volta l'indirizzo della radice (server DNS) del proprio sottoalbero di appartenenza.
In questo schema c'è anche posto per una configurazione ridondante, ovvero accanto al server DNS padre di un dato sottoalbero possono essere affiancati altri servers DNS in grado di supportare le richieste di risoluzione dei nomi provenienti dai clients nel caso in cui il DNS master (cioè il primario) non possa rispondere.
Tale configurazione prende il nome di fault tolerance, poichè l'intero servizio di risoluzione dei nomi non viene inficiato in caso di guasto di una delle macchine.
Installazione
Installare il software necessario per configurare i servizi DNS:
apt-get -y install bind9
Directory di configurazione
Come visto per il server Web la directory che contiene i file di configurazione del DNS è sotto la directory /etc e precisamente /etc/bind.
Sempre sotto /etc/bind si trovano tutti i file contenenti sia le zone di ricerca dirette ed inverse (ossia quelle che includono le corrispondenze fra indirizzi IP e nomi e fra nomi ed indirizzi IP) sia quelli relativi alle opzioni di configurazione del servizio stesso.
Tali opzioni sono specificate:
nel file /etc/bind/named.conf che contiene le direttive di configurazione generali del servizio:
nel file /etc/bind/named.conf.options che contiene le opzioni e le liste di controllo degli accessi per la configurazione generali del servizio;
nel file /etc/bind/named.conf.local che contiene le direttive di configurazione locali del servizio,ovvero la dichiarazione delle vostre zone locali (quelle servite dal vostro DNS).
Notare che su Ubuntu i file di zona hanno le forme seguenti:
/etc/bind/db.<dir_zone> /etc/bind/db.<rev_zone>
I file binari relativi al servizio DNS si trovano sotto la directory /usr/sbin ed è precisamente /usr/sbin/named.
La directory che contiene i log files relativi al servizio è /var/log. In particolare, qualsiasi problema durante l'avvio viene notificato nel file /var/log/syslog.
Caching Nameserver e DNS autoritario
Prima di configurare il nostro DNS occorre precisare che vi sono 2 tipi di DNS :
- caching
- autoritario
Un nameserver caching non contiene file di zona (corrispondenze fra indirizzi IP e nomi hosts) , ma contiene soltanto i riferimenti ai DNS padre dell'albero e pertanto delega ad essi qualsiasi risoluzione dei nomi , memorizzando nella propria memoria cache i risultati di tali ricerche in modo da velocizzare tutti gli accessi susseguenti al primo (che avvengono interrogando la memoria cache del server locale e non interrogando i root nameservers).
Un nameserver autoritario contiene le corrispondenze fra indirizzi IP e nomi hosts di tutti i clients della rete che serve , pertanto ha autorità di risoluzione diretta (non deve chiedere ad altri DNS quali sono i nomi o gli indirizzi dei computers).
Configurazione di un caching
Se volete soltanto snellire e velocizzare gli accessi ad Internet degli utenti della vostra LAN quello che vi occorre è un semplice caching nameserver.
Dopo aver installato il pacchetto bind9 basta semplicemente avviare il servizio immettendo al prompt dei comandi:
/etc/init.d/bind9 start
Se volete farlo partire in avvio create un link in /etc/rc2.d che punta alla directory /etc/init.d/bind9 eseguendo il comando:
ln -s /etc/init.d/bind9 /etc/rc2.d/bind9
(questo se il vostro runlevel di default è il 2).
Configurazione di un DNS autoritario
Se invece volete configurare un server DNS che possa supportare la risoluzione dei nomi dei clients della vostra LAN dovete innanzitutto pianificare l'intervento nel modo seguente:
- localizzare tutti i clients
- ottenere network e netmask
Dopo l'installazione di bind9 occorre modificare il file /etc/bind/named.conf.local aggiungendo le direttive di configiurazione delle vostre zone di ricerca diretta ed inversa come segue:
Zone "<nomezona>" { type [hint | master | slave]; file "<path_to_zone_file>"; forwarders { }; masters { }; allow-update {key <keyname>;}; };
La configurazione della zona di ricerca inversa di esempio è la seguente:
Zone "<nomezona>.in-addr.arpa" { type [hint | master | slave]; file "<path_to_zone_file>"; forwarders { }; masters { }; allow-update {key <keyname>;}; };
La direttiva type indica il tipo di DNS server che si sta configurando (master , slave o root NS).
La direttiva file indica in quale file è memorizzato il DB delle corrispondenze nome-indirzzo degli hosts della rete.
La direttiva forwarders indica se il vostro server DNS deve utilizzare un sevrer esterno per risolvere ricorsivamente le richieste di risoluzione DNS. Un forwarder altro non è che un grande caching namserver che si fa interamente carico della risoluzione di tutte le queries DNS dirette verso l'esterno. In un'azienda il forwarder generalmente viene usato per velocizzare le risoluzioni DNS di siti Internet.
La configurazione di un server slave (fault tolerance) prevede sempre la creazione delle direttive di zona nel file /etc/bind/named.conf.local come nell'esempio seguente:
zone "linux.bogus" { type slave; file "sz/linux.bogus"; masters { 192.168.196.2; }; };
Come vedete la direttiva masters contiene l'indirizzo IP del DNS master che possiede il DB con le corrispondenze fra IP e nomi hosts.
E' importante notare che mentre sul master tale database deve essere creato,ciò non deve essere fatto sullo slave, i cui file vengono automaticamente creati durante la sincronizzazione con il DNS master.
Architettura di esempio
Il sistema descritto è costituito da:
DNS master DNS slave
questo permette una configurazione di fault tolerance (il servizio è erogato anche quando uno dei 2 servers ha problemi).
Inoltre il trasferimento da zona master a slave avviene con il metodo della firma TSIG.
Configurazione del DNS master e dei suoi file di zona
Il file /etc/bind/named.conf.local:
include "/etc/bind/secret.key" zone "example.com" { type master; file "/etc/bind/db.example.com"; allow-transfer {key mykey;}; allow-update {key mykey;}; }; zone "77.168.192.in-addr.arpa" { type master; file "/etc/bind/db.77.168.192"; allow-transfer {key mykey;}; allow-update {key mykey;}; };
Il file /etc/bind/secret.key:
key chiave { secret "Np6emc4SFPeI5UXSetOEIA=="; algorithm "hmac-md5"; }; server 192.168.77.2 { keys {chiave;}; };
Il file secret.key non dovrebbe essere leggibile da tutti, pertanto assivuratevi che i suoi permessi siano -rw-r----- eseguendo il comando chmod 640 /etc/bind/secret.key.
Veniamo ora alla configurazione dei singoli file di zona di ricerca diretta ed inversa :
@ IN SOA wilcoyote.example.com. root.localhost. ( 2005112001 86400 207800 809650 86400 ); @ IN NS nome.dominio.com. @ IN MX 50 nome.dominio.com. nome.dominio.com. IN A 192.168.0.1 web IN CNAME nome.dominio.com mail IN CNAME nome.dominio.com proxy IN CNAME nome.dominio.com
Commentiamo le righe precedenti :
il simbolo @ è un alias per il nome del dominio DNS di questa zona di ricerca
la direttiva IN sta per Internet , e potrebbe essere omessa per una LAN (ma non nel caso di un server pubblico)
la prima riga dice che tutte le richieste di risoluzione dei nomi che riguardano la zona indicata da questo file (ed il cui nome è scritto nel file /etc/bind/named.conf.local) devono essere risolte dal server nome.dominio.com. Il . alla fine del nome completo è fondamentale, quindi non lo dimenticate!! L'indirizzo email dell'amministratore di tale zona è root@localhost (in questo caso il . finale viene autmaticamente tradotto nel simbolo @)-
- I parametri specificati dopo la parentesi tonda sono nell'ordine :
Serial: ID della zona (gli aggiornamenti di refresh tra DNS slave e DNS master avvengono soltanto se il seriale della zona sullo slave e diverso dal precedente valore con cui lo slave si era aggiornato!!)
Refresh Time: Tempo trascorso il quale un DNS slave aggiorna i record di una data zona con DNS master
Retry: Indica il tempo dopo il quale viene ritentato il trasferimento di zona se il DNS master non è al momento disponibile
Expire: Se il DNS slave non riesce a mettersi in contatto con il master per il tempo indicato dal valore Expire, la zona scade e deve essere rinnovata
TTL: Tempo per il quale i dati restano nella cache di un DNS (/var/cache/bind) prima che avvenga un nuovo aggiornamento. Il TTL indica il tempo di propagazione minimo dell'informazione fra record di zona (intervallo fra trasferimenti di zona e reloading)
la seconda riga dice che il server dei nomi autoritario per questa zona è nome.dominio.com (il tipo di record è NS)
@ IN MX 50 nome.dominio.com.: per questo dominio il server di posta con priorità 50 è wilcoyote.example.com. La priorità è inversamente proporzionale al numero indicato (i valori possibili sono da 1 a 100, 1 massima 100 minima)
nome.dominio.com. IN A 192.168.0.1: dice che nome.dominio.com ha l'indirizzo 192.168.0.1 (A sta per address)
web IN CNAME nome.dominio.com: questa riga dice che il nome web è un alias per nome.dominio.com, ovvero che nome.dominio.com può anche essere raggiunto richiedendo il nome web
Veniamo alla zona di ricerca inversa /etc/bind/db.0.168.192:
@ IN SOA nome.dominio.com. root.localhost. ( 2005112001 86400 207800 809650 86400 ); @ IN NS nome.dominio.com. 1 IN PTR nome.dominio.com.
Il significato delle righe elencate è analogo al precedente caso della zona di ricerca diretta, tranne che per la seguente riga :
1 IN PTR nome.dominio.com.: dice che l'host nome.dominio.com ha l'indirizzo 192.168.0.1 (come si osserva i primi 3 ottetti sono omessi e viene specificato soltanto l'ultimo ottetto , quello che differenzia fra loro tutti gli hosts della subnet 192.168.0.0/24)
Prima di proseguire nella sezione configurazioni avanzate occorre ricordare che quando si modifica un file di zona sul master bisogna sempre incrementare il numero seriale (SERIAL) affinchè nella successiva sincronizzazione lo slave possa rilevare la variazione del DB e le informazioni possano essere aggiornate. Ricordatelo bene, altrimenti vi potreste trovare con dei record aggiornati su un server e non su altri, con risultati totalmente imprevedibili...
Configurazione del DNS slave
Il file /etc/bind/named.conf.local:
include "/etc/bind/secret.key" zone "example.com" { type slave; file "/etc/bind/db.example.com"; masters {192.168.77.1;}; }; zone "77.168.192.in-addr.arpa" { type slave; file "/etc/bind/db.77.168.192"; masters {192.168.77.1;}; };
Il file /etc/bind/secret.key:
key chiave { secret "Np6emc4SFPeI5UXSetOEIA=="; algorithm "hmac-md5"; }; server 192.168.77.1 { keys {chiave;}; };
Come vedete qui non dobbiamo creare i database delle zone di ricerca, in quanto verranno automaticamente create al momento della sincronizzazione fra master e slave.
Il file secret.key non dovrebbe essere leggibile da tutti, pertanto assivuratevi che i suoi permessi siano -rw-r----- eseguendo il comando chmod 640 /etc/bind/secret.key.
Direttive di configurazione avanzate - ACL
Oltre alla firma TSIG , BIND possiede altre speciali direttive che permettono di controllare chi può effettuare richieste di risoluzione di nomi o indirizzi (queries) verso il nostro DNS e chi può effettuare trasferimenti di intere zone.
Le direttive sono le seguenti:
acl miarete {192.168.20.0/24;};
acl slave_miarete {192.168.20.102};
Come vedete queste due direttive specificano due liste di controllo degli accessi in base alla subnet di appartenenza di un host. Pertanto il controllo accessi supportato nativamente da BIND è host-based.
A questo punto occorre specificare il tipo di azione che il vostro DNS può fare in relazione alle ACL così definite.
In genere l'azione è sempre positiva , nel senso che si specifica sempre a quale ACL definita è permesso compiere determinate operazioni sul DNS (direttiva allow).
Questo viene fatto attraverso le direttive specificate nel file /etc/bind/named.conf.local nel modo seguente:
allow-query {miarete;};
questa dice al DNS di accettare le richieste di risoluzione dei nomi provenienti dai clients della rete 192.168.20.0/24allow-transfer {slave_miarete;};
questa dice al DNS master di permettere il trasferimento di un file di zona soltanto all'host con indirizzo IP 192.168.20.102
Come avrete già notato il file di configurazione standard del DNS /etc/bind/named.conf supporta le direttive di inclusione dei file, pertanto potrete anche creare le vostre personalizzate ACL ed includerle poi successivamente in questo file, oppure crearle direttamente in /etc/bind/named.conf.local per renderle relative soltanto alle zone da voi create.
Trasferimenti di zona, aggiornamenti di record e sicurezza
Come avrete notato il protocollo DNS non è intrinsecamente sicuro nè progettato per la sicurezza.
Un client malintenzionato può facilmente ottenere le informazioni riguardo all'architettura della vostra rete ed alle macchine che ne fanno parte.
Per ovviare a questo particolare è stato introdotto il supporto per gli aggiornamenti di record ed i trasferimenti di zone utilizzando sia la firma digitale TSIG che la crittografia a chiave pubblica.
Il supporto per la firma digitale TSIG è possibile usando il comando:
dnssec-keygen -a <algoritmo> -b <numero di bits delle chiavi> -n HOST <nome della zona>
questo comando genera una coppia di chiavi privata/publica che voi dovrete associare alla vostra zona per garantire una comunicazione protetta con i clients e con lo(gli) slave server. In particolare per garantire un aggiornamento sicuro usando il meccanismo a chiave privata il contenuto del file con estensione .private dovrebbe essere condiviso sia dal msater che dagli slave servers , in modo che il riconoscimento sia univoco ed esente da errori.
Spostatevi sul DNS master ed eseguite il comando:
dnssec-keygen -a HMAC-MD5 -b 128 -n HOST example.com
ora digitate il comando :
echo secret `grep Key *.private | awk {'print $2'}`; >> /etc/bind/named.conf.local
questo comando copierà il valore della chiave privata in coda al file /etc/bind/named.conf.local.
A questo punto editate il file /etc/bind/named.conf.local aggiungendo all'interno delle vostre zone le righe seguenti:
key mykey { secret "valore della chiave appena copiato"; algorithm hmac-md5; }; zone "vostrazona" { type master | slave; file "path_to_file"; allow-update {key mykey}; };
e questo va fatto per entrambe le zone di ricerca , sia diretta che inversa e sia sul master che sullo slave.
A questo punto basta riavviare e forzare una sincronizzaizone del DB per vedere se tutto va bene.
Questo è il metodo che usa una chiave privata.
DNS e crittografia a chiave pubblica
In questo paragrafo introduciamo l'uso della crittografia a chiave pubblica nella struttura ad albero del DNS allo scopo di garantire integrità e autenticità delle risposte alle queries e nei trasferimenti di zona.
Come noto la crittografia a chiave pubblica è il metodo più sicuro per la convalida di dati sensibili.
Per ciò che riguarda il DNS tali dati sono tutti quelli contenuti nei file delle zone di ricerca.
Questi dati possono essere protetti associando ad ogni dominio diretto ed inverso una coppia di chiavi privata/pubblica che li identifica univocamente.
Il server DNS deve prima generare la coppia di chiavi privata/pubblica. Poi deve generare una richiesta di firma della propria chiave pubblica da inviare al DNS del dominio padre (per esempio se il dominio è italia.com il DNS deve inviare una richiesta di firma della chiave pubblica da lui generata al DNS del dominio padre com). In questo modo il DNS padre può autenticare la chiave pubblica del DNS figlio con la sua firma.
Infine ricevuta la sua chiave pubblica controfirmata dal padre il DNS figlio può firmare finalmente i propri file di zona con la sua chiave privata.
Come osserviamo la crittografia a chiave pubblica garantisce pertanto che le risposte del DNS siano autenticate (appunto attraverso l'utilizzo delle chiavi), ovvero che i record provengano effettivamente da DNS di identità comprovata.
L'implementazione di questo metodo di protezione delle zone in UNIX è realizzata da DNSSEC.
Ovviamente tutto il sistema si fonda su una trusted-chain (ovvero catena di validazioni), per cui quando il client DNS del dominio italia.edu effettua una query per l'individuazione del record A dell' host pippo esso riceve la risposta dal server DNS del dominio italia.edu e può essere confidente che tale risposta sia quella corretta (la zona è firmata dal server DNS del dominio italia.edu e la chiave usata per la firma è autenticata dal DNS del dominio padre edu).
L'implementazione di DNSSEC su UNIX possiede anche alcune features che vanno al di là dello standard DNSSSEC.
Vediamo ora attraverso un esempio qual è il procedimento da seguire per realizzare DNSSEC su un server DNS Ubuntu.
Architettura dell'esempio
Il nostro sistema è configurato come segue:
DNS master (hostname '''eolo''') che gestisce il dominio '''roma.com'''
Per generare la coppia di chiavi usiamo il comando
dnssec-keygen -a DSA -b 768 -n ZONE roma.com
dove le opzioni hanno i seguenti significati :
-a DSA specifica il tipo di algoritmo utilizzato (RSA,DSA)
-b 768 indica il numero di bits della chiave
-n ZONE indica che le chiavi generate saranno utilizzate per firmare file di zona
roma.com è il nome del dominio
Ora per creare la richiesta di firma da inviare al dominio padre com usiamo il comando
#dnssec-makekeyset -t 86400 Kroma.com.+003+14481
Questo comando produce il file di output keyset-roma.com..
Ora inviamo il nostro file keyset-roma.com. al server DNS del dominio padre che lo firmerà utilizzando il comando
dnssec-signkey keyset-roma.com. Kcom.+003+56789
come vediamo ha usato la sua chiave pubblica...
Questo produce il file signedkey-roma.com. che dovremo farci spedire per poi poter firmare con esso le nostre zone.
Se non abbiamo dominio padre o non vogliamo inviare la nostra richiesta possiamo firmare noi stessi la richiesta utilizzando la nostra chiave con il comando
dnssec-signkey keyset-roma.com. Kroma.com.+003+14481
in questo modo è il DNS stesso del dominio roma.com ad autenticare con la propria chiave la richiesta (questo meccanismo è analogo al self-signing certificate che si usa con apache2-ssl-certificate).
Facciamoci dare dal server padre (o se abbiamo autenticato noi stessi la nostra richiesta l'avremo già nel nostro filesystem) il file signedkey-roma.com. ed inseriamolo con la direttiva $INCLUDE nei file delle zone di ricerca diretta ed inversa come segue
#/etc/bind/db.roma.com $TTL 864000 @ IN SOA ns.roma.com. root.localhost. (2005102501 86400 3600 212900 864000) $INCLUDE "/etc/bind/signedkey-roma.com." ...
#/etc/bind/db.77.168.192 $TTL 864000 @ IN SOA ns.roma.com. root.localhost. (2005102501 86400 3600 212900 864000) $INCLUDE "/etc/bind/signedkey-roma.com." ...
Prima di procedere alla firma delle nostre zone ricordiamoci di modificare i permessi del file signedkey-roma.com. come segue
chmod 644 /etc/bind/signedkey-roma.com.
Ora siamo pronti per firmare le nostre zone con il comando
dnssec-signzone -o roma.com /etc/bind/db.roma.com dnssec-signzone -o roma.com /etc/bind/db.77.168.192
Questo produrrà come output i 2 file /etc/bind/db.roma.com.signed e /etc/bind/db.77.168.192.signed che dovranno essere inclusi nel file /etc/bind/named.conf.local per usare DNSSEC.
Pertanto ora il nostro file /etc/bind/named.conf.local sarà fatto nel modo seguente
zone "roma.com" { type master; file "/etc/bind/db.roma.com.signed } zone "77.168.192.in-addr.arpa" { type master; file "/etc/bind/db.77.168.192.signed" }
Ora riavviamo e testiamo il tutto.
La propagazione delle informazioni
A tal proposito si riporta il seguente esempio:
- Scenario:
- DNS1 master
- DNS2 slave
- DNS3 caching
DNS3 (caching NS) aggiorna la sua cache alle 16:30:05 da DNS2 (slave) e rileva un TTL di 24 ore nel file di zona.
In base al tempo di refresh DNS2 aggiorna la sua zona alle 16:31:03 da DNS1.
Se il refresh time di DNS2 è 3 ore, il tempo dopo il quale una modifica ad un record di zona di DNS1 si propaga fino a DNS3 è: TTL(DNS2) + TRefresh(DNS2).
Come si vede il tempo di propagazione di una modifica dipende dall'architettura della rete oltre che dalle condizioni inziali del problema.