DNS autorevoli ridondati con BIND 9: primary, secondary, TSIG e DNSSEC

Come rendere ridondante il DNS autorevole: server primary/secondary su reti diverse, AXFR/IXFR, NOTIFY, TSIG, firewall, verifica con dig e ruolo distinto di DNSSEC.

Se gestiamo in autonomia il DNS autorevole di un dominio, la disponibilità del sito, della posta e di molti altri servizi dipende prima ancora dalla possibilità di risolverne i nomi. Un web server perfettamente funzionante è poco utile se nessun resolver riesce a scoprire il suo indirizzo perché l’unico nameserver autorevole è irraggiungibile.

La soluzione classica è avere almeno due server DNS autorevoli indipendenti. In BIND 9 uno mantiene la copia principale della zona, il primary; uno o più server secondary ricevono automaticamente i dati tramite zone transfer e rispondono alle query con la stessa autorevolezza del primary.

Primary e secondary non significano “prima scelta” e “seconda scelta”

Dal punto di vista di un resolver, entrambi i nameserver sono autorevoli. Il secondary non è un server di emergenza che rimane inutilizzato finché il primary non cade: può ricevere query normalmente anche quando tutto funziona.

La distinzione riguarda la provenienza dei dati. Il primary legge la zona dalla propria configurazione; il secondary la ottiene dal primary tramite AXFR, cioè trasferimento completo, oppure IXFR, trasferimento incrementale quando supportato.

Ridondanza vera significa separare i domini di guasto

Configurare ns1.example.net e ns2.example.net sullo stesso server non crea ridondanza. Usare due IP sulla stessa macchina migliora ancora meno. Anche due server nella stessa rete, dietro lo stesso router e la stessa connessione, condividono gran parte dei possibili guasti.

Quando possibile, primary e secondary dovrebbero quindi stare su infrastrutture differenti: indirizzi pubblici distinti, reti differenti e idealmente provider o sedi differenti. In questo modo un guasto locale non rende irraggiungibile l’intera delegazione DNS.

Scenario della guida

Zona: example.net

Primary:
ns1.example.net
192.0.2.53

Secondary:
ns2.example.net
198.51.100.53

Gli indirizzi appartengono alle reti riservate alla documentazione. Sostituiamoli con quelli reali.

1. Configurare la zona sul primary

Una zona BIND primaria può essere definita così:

zone "example.net" {
    type primary;
    file "/etc/bind/zones/db.example.net";
};

Nel file di zona devono comparire entrambi i nameserver:

$TTL 3600

@ IN SOA ns1.example.net. hostmaster.example.net. (
    2026092401 ; serial
    3600       ; refresh
    900        ; retry
    1209600    ; expire
    300        ; negative cache TTL
)

  IN NS ns1.example.net.
  IN NS ns2.example.net.

ns1 IN A 192.0.2.53
ns2 IN A 198.51.100.53

@   IN A 203.0.113.20
www IN A 203.0.113.20

Il serial del record SOA deve aumentare quando cambiamo la zona. Il formato YYYYMMDDNN non è obbligatorio, ma è leggibile e comodo da amministrare.

2. Proteggere i trasferimenti con TSIG

Consentire AXFR a chiunque significa permettere a un client arbitrario di scaricare l’intera zona. È molto meglio autorizzare il secondary esplicitamente e autenticare il trasferimento con una chiave TSIG condivisa.

install -d -m 0750 /etc/bind/keys

tsig-keygen -a hmac-sha256 xfr-example-net   > /etc/bind/keys/xfr-example-net.key

chown root:bind /etc/bind/keys/xfr-example-net.key
chmod 0640 /etc/bind/keys/xfr-example-net.key

Copiamo il file della chiave sul secondary attraverso un canale amministrativo sicuro. Non deve essere pubblicato nel DNS.

3. Limitare AXFR/IXFR e inviare NOTIFY

Sul primary includiamo la chiave e autorizziamo i trasferimenti soltanto con quella credenziale:

include "/etc/bind/keys/xfr-example-net.key";

zone "example.net" {
    type primary;
    file "/etc/bind/zones/db.example.net";

    allow-transfer {
        key "xfr-example-net";
    };

    also-notify {
        198.51.100.53 key "xfr-example-net";
    };
};

Il secondary controlla periodicamente il SOA e confronta il serial. NOTIFY riduce l’attesa: appena il primary ricarica una nuova versione della zona avvisa il secondary, che può verificare immediatamente se sia necessario un trasferimento.

4. Configurare il secondary

include "/etc/bind/keys/xfr-example-net.key";

zone "example.net" {
    type secondary;

    primaries {
        192.0.2.53 key "xfr-example-net";
    };

    file "/var/cache/bind/db.example.net";
};

Il file sul secondary è una copia locale della zona trasferita. Non va modificato manualmente: la fonte autorevole dei dati resta il primary.

5. Validare prima del reload

# Primary
named-checkconf
named-checkzone example.net /etc/bind/zones/db.example.net

# Secondary
named-checkconf

# Ricarica
rndc reload example.net

Se cambiamo il serial e ricarichiamo la zona sul primary, il secondary dovrebbe ricevere il NOTIFY e aggiornarsi tramite IXFR o AXFR.

6. Verificare entrambi i server con dig

dig @192.0.2.53 example.net SOA +norecurse
dig @198.51.100.53 example.net SOA +norecurse

dig @192.0.2.53 example.net NS +norecurse
dig @198.51.100.53 www.example.net A +norecurse

I serial SOA devono convergere. Entrambi i server devono restituire risposte autorevoli, riconoscibili dal flag aa.

Per forzare un nuovo trasferimento sul secondary:

rndc retransfer example.net

journalctl -u bind9 -f
# oppure, a seconda della distribuzione:
journalctl -u named -f

7. Firewall

Un server DNS autorevole pubblico deve poter ricevere query UDP e TCP sulla porta 53. I zone transfer usano TCP. Limitare TCP/53 pensando che “DNS è UDP” rompe trasferimenti e può rompere anche normali risposte DNS di grandi dimensioni o fallback.

Sul primary possiamo inoltre limitare amministrativamente i trasferimenti al secondary, ma la vera autorizzazione applicativa resta in BIND con allow-transfer e TSIG.

8. Delegazione presso il registrar e glue record

Configurare BIND non basta. Il parent della zona deve delegare il dominio ai nameserver corretti. Se i nameserver appartengono allo stesso dominio che stanno servendo, per esempio ns1.example.net per example.net, il registrar deve normalmente registrare anche i relativi indirizzi come glue record.

dig example.net NS
dig +trace example.net

Una configurazione locale perfetta ma una delegazione parent sbagliata produce comunque un DNS pubblico rotto.

9. TSIG e DNSSEC risolvono problemi differenti

È importante non confonderli. TSIG autentica una comunicazione tra server, per esempio un zone transfer o un NOTIFY. DNSSEC firma invece i dati DNS affinché i resolver validanti possano verificare che una risposta autentica non sia stata alterata.

Le firme DNSSEC e le chiavi pubbliche fanno parte della zona e possono essere replicate al secondary; le chiavi private di firma devono rimanere protette sull’infrastruttura che gestisce la firma. Un secondary DNS non rende automaticamente la zona “DNSSEC”: sono due livelli separati della progettazione.

10. Testare anche il guasto

La ridondanza non è dimostrata dal fatto che entrambi rispondano oggi. Fermiamo temporaneamente BIND sul primary in una finestra di test e interroghiamo direttamente il secondary. Poi controlliamo la risoluzione attraverso resolver esterni e verifichiamo che il servizio continui a essere raggiungibile.

Naturalmente la disponibilità DNS non rende automaticamente ridondante il servizio finale: se tutti i record puntano a un unico web server e quel server cade, i nomi continueranno a risolversi perfettamente verso un servizio indisponibile.

Riferimenti

BIND 9 ARM: authoritative primary/secondary servers · BIND 9 configuration reference.