Projet

Général

Profil

Installation et configuration de bind

Principe général

Un serveur de nom primaire pour une zone est un serveur hébergeant la zone déclarée en type « master » et étant déclaré en tant que « NS » pour cette zone.

Un serveur de nom secondaire pour une zone est un serveur hébergeant la zone déclarée en type « slave » et étant déclaré en tant que « NS » pour cette zone.

Du point de vue du client DNS, celui qui interroge le serveur pour résoudre un nom, il n'y a pas de notion de primaire ou secondaire. Tous les serveurs déclarés sur une zone seront interrogés tour à tout avec du round-robin pour répartir la charge.

    temps          primaire              secondaire
      |               |                      |
      |    [modification d'une zone]         |
      |               |                      |
      |               |-----notificaiton---->|
      |               |        NOTIFY        |
      |               |                      |
      |               |<---téléchargement----|
      |               |      AXFR/IXFR       |
      |               |                      |
      |               |                      |
      |               |                      |
      |               |              [expiration du TTL]
      |               |                      |
      |               |<---téléchargement----|
      |               |      AXFR/IXFR       |
      |               |                      |
      v               v                      v

Le serveur secondaire télécharge la zone depuis le primaire dans deux cas :

  • La zone a été modifiée sur le primaire. Celui-ci notifie alors le secondaire de la présence d'une nouvelle version de la zone. Le secondaire initie le téléchargement par une requête AXFR (transfert de la zone complète) ou IXFR (transfert incrémental).
  • Le TTL (Time To Live) expire sur le serveur secondaire. Celui-ci récupère une version fraîche de la zone depuis le primaire (idem, AXFR ou IXFR).

Il est possible de forcer l'envoi d'une notification depuis le primaire afin de mettre à jour les zones sur tous les secondaires configurés. Cela est utile dans le cas où le(s) secondaire(s) étaient inaccessibles au moment de la mise à jour d'une zone. Cela permet de ne pas avoir à attendre l'expiration du TTL sur les secondaires.

Dans le cas d'un transfert incrémental (IXFR), le serveur secondaire indique au primaire le numéro de série de la zone qu'il connaît et le serveur primaire retourne uniquement les différences avec la zone active.

Installation de bind « chrooté »

Installation

Debian stable (actuellement squeeze) n'est pas très à jour niveau mise à jour de sécurité de bind. Personnellement, je préfère installer la version « testing » (wheezy) dans un environnement « chrooté ».

# aptitude -t wheezy install bind

Création de l'environnement chrooté

# mkdir -p /var/bind9/chroot/{etc,dev,var/named/pri,var/named/sec,var/run/named}
# mknod /var/bind9/chroot/dev/null c 1 3
# mknod /var/bind9/chroot/dev/random c 1 8
# chmod 660 /var/bind9/chroot/dev/{null,random}
# mv /etc/bind /var/bind9/chroot/etc/bind
# ln -sv /var/bind9/chroot/etc/bind /etc/bind
# chown -R bind:bind /var/bind9/chroot/etc/bind
# chmod 775 /var/bind9/chroot/var/{named/pri,named/sec,run/named}
# chgrp bind /var/bind9/chroot/var/{named/pri,named/sec,run/named}

Configuration des scripts de démarrage de bind et de rsyslog

# sed -i -e 's/^OPTIONS=.*$/OPTIONS="-u bind -t \/var\/bind9\/chroot"/' /etc/default/bind9
# sed -i -e 's/^PIDFILE=.*$/PIDFILE=\/var\/bind9\/chroot\/var\/run\/named\/named.pid/' /etc/init.d/bind9
# echo "\$addUnixListenSocket /var/bind9/chroot/dev/log" > /etc/rsyslog.d/bind9-chrooted.conf

Configuration de bind

/etc/bind/named.conf : Fichier de configuration lu par le daemon au démarrage. Il est préférable de séparer la configuration par « activité ».

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/named.conf.zones";

/etc/bind/named.conf.options : Options du daemon.

options {
        directory "/var/named";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable
        // nameservers, you probably want to use them as forwarders.
        // Uncomment the following block, and insert the addresses replacing
        // the all-0's placeholder.

        // forwarders {
        //      0.0.0.0;
        // };

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
        transfer-source { 80.67.176.156; };
        transfer-source-v6 { 2001:910:109c:2::53; };
};

controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

include "/etc/bind/rndc.key";

Les paramètres transfer-source et transfer-source-v6 permette de définir l'adresse IP source utilisée lors de transferts de zones depuis le primaire vers le secondaire.
Par défaut, bind utilise l'interface qui a l'adresse IP la plus « proche » de celle du serveur secondaire (même subnet, en gros).
Ce paramètre est très utile dans le cas où un serveur primaire dispose de plusieurs interface réseau.

/etc/bind/named.conf.local : zones des reverses RFC1918. Le fichier /etc/bind/zones.rfc1918 est fourni par debian.

//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
include "/etc/bind/zones.rfc1918";

/etc/bind/named.conf.default-zones : zones par « défaut » (serveurs root, localhost, reverse 127.0.0.0/8), fichiers fournis par debian.

// prime the server with knowledge of the root servers
zone "." {
        type hint;
        file "/etc/bind/db.root";
};

// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

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

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};

/etc/bind/named.conf.zones : Définition des zones primaires ou secondaires (voir plus loin) hébergées par le serveur.

zone "kafe-in.net" IN {
        type slave;
        file "sec/kafe-in.net.zone";
        allow-notify { 2001:910:109c:2::53/128; };
        masters { 2001:910:109c:2::53/128; };
};

zone "k-f.in" IN {
        type master;
        file "pri/k-f.in.zone";
        allow-transfer { 2001:910:109c:2::53/128; };
};

Pour que les modifications soient prises en compte, il faut redémarrer rsyslog et bind9.

# /etc/init.d/rsyslog restart
# /etc/init.d/bind9 restart

Configuration d'un serveur primaire

Example pour la zone k-f.in :

# cat /var/bind9/chroot/var/named/k-f.in.zone
$TTL 864000
@ IN SOA dns2.kafe-in.net. fab.kafe-in.net. (
                2012061701      ; serial
                3600            ; refresh
                900             ; retry
                1209600         ; expire
                43200           ; default_ttl
)

@                     IN NS     dns.kafe-in.net.
@                     IN NS     dns2.kafe-in.net.

@               28800 IN MX     10 mail.kafe-in.net.
@               28800 IN MX     20 mail2.kafe-in.net.

                28800 IN A      91.224.149.142
                28800 IN AAAA   2a01:6600:8081:8e00::fab

; FDN
roussane        28800 IN A      80.67.176.156
roussane        28800 IN AAAA   2001:910:109c:1::2

; Tetaneutral
muscat          28800 IN A      91.224.149.142
muscat          28800 IN AAAA   2a01:6600:8081:8e00::fab

; Services
www             28800 IN CNAME  muscat

Le serveur primaire est dns.kafe-in.net (80.67.176.156 et 2001:910:109c:2::53). Ce n'est pas forcément le premier « NS » défini qui est primaire. C'est celui qui héberge la zone avec un type « master » et qui est défini en « SOA » (« Start of Authority »).

Le zone k-f.in doit donc être déclarée de la façon suivante dans le fichier named.conf.zones du serveur primaire :

zone "k-f.in" IN {
        type master;
        file "pri/k-f.in.zone";
        allow-transfer { 2a01:6600:8081:8e00::fab/128; };
};

La zone k-f.in est de type « master » (serveur primaire) et seul le serveur secondaire 2a01:6600:8081:8e00::fab/128 est autorisé à la demander lors de mises à jour de la zone sur le primaire.

Configuration d'un serveur secondaire

La même zone k-f.in doit donc être déclarée de la façon suivante dans le fichier named.conf.zones du serveur secondaire :

zone "k-f.in" IN {
        type slave;
        file "sec/k-f.in.zone";
        allow-notify { 2001:910:109c:2::53/128; };
        masters { 2001:910:109c:2::53/128; };

};

La zone est de type « slave » (serveur secondaire) et seul le serveur primaire 2001:910:109c:2::53/128 est autorisé à notifier le serveur secondaire de la présence de modifications. Le serveur secondaire téléchargera la zone mise à jour sur le serveur 2001:910:109c:2::53/128 (ici le même, mais pas forcément).

Gestion des logs

Par défaut, bind envoie tous les logs de l'application « en vrac » dans /dev/log. Charge au daemon syslog de les ranger comme on veut. Le problème est qu'il est très difficile de configurer un daemon syslog pour séparer ces logs en catégories afin de faciliter la résolution de problèmes.

Pour rediriger une catégorie de log, il faut d'abord définir un canal (channel) ayant pour destination un fichier puis il faut rediriger une categorie (category) dans ce canal.

Voilà un exemple de configuration séparant chaque catégorie de log dans des fichiers différents :

# Configuration des logs
logging {
        channel default_file { file "/var/log/named/default.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel general_file { file "/var/log/named/general.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel database_file { file "/var/log/named/database.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel security_file { file "/var/log/named/security.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel config_file { file "/var/log/named/config.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel resolver_file { file "/var/log/named/resolver.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel xfer-in_file { file "/var/log/named/xfer-in.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel xfer-out_file { file "/var/log/named/xfer-out.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel notify_file { file "/var/log/named/notify.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel client_file { file "/var/log/named/client.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel unmatched_file { file "/var/log/named/unmatched.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel queries_file { file "/var/log/named/queries.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel network_file { file "/var/log/named/network.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel update_file { file "/var/log/named/update.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel dispatch_file { file "/var/log/named/dispatch.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel dnssec_file { file "/var/log/named/dnssec.log" versions 3 size 5m; severity dynamic; print-time yes; };
        channel lame-servers_file { file "/var/log/named/lame-servers.log" versions 3 size 5m; severity dynamic; print-time yes; };

        category default { default_file; };
        category general { general_file; };
        category database { database_file; };
        category security { security_file; };
        category config { config_file; };
        category resolver { resolver_file; };
        category xfer-in { xfer-in_file; };
        category xfer-out { xfer-out_file; };
        category notify { notify_file; };
        category client { client_file; };
        category unmatched { unmatched_file; };
        category queries { queries_file; };
        category network { network_file; };
        category update { update_file; };
        category dispatch { dispatch_file; };
        category dnssec { dnssec_file; };
        category lame-servers { lame-servers_file; };
};

Gestion des zones

Forcer le transfert d'une zone depuis un serveur secondaire :

Le transfert d'une zone est généralement déclenché par le serveur primaire (envoi d'un NOTIFY à chaque modification du serial). Mais il est possible de forcer un téléchargement de la zone depuis le serveur secondaire avec la commande « rndc retransfert nom-de-la.zone ».

Sur le secondaire :

# rndc retransfer kafe-in.net
# tail /var/log/daemon.log
Jul 28 11:31:14 muscat named[22111]: received control channel command 'retransfer kafe-in.net'
Jul 28 11:31:14 muscat named[22111]: zone kafe-in.net/IN: Transfer started.
Jul 28 11:31:14 muscat named[22111]: transfer of 'kafe-in.net/IN' from 2001:910:109c:2::53#53: connected using 2a01:6600:8081:8e00::fab#46243
Jul 28 11:31:14 muscat named[22111]: zone kafe-in.net/IN: transferred serial 2012072701
Jul 28 11:31:14 muscat named[22111]: transfer of 'kafe-in.net/IN' from 2001:910:109c:2::53#53: Transfer completed: 1 messages, 30 records, 749 bytes, 0.105 secs (7133 bytes/sec)
Jul 28 11:31:14 muscat named[22111]: zone kafe-in.net/IN: sending notifies (serial 2012072701)

Sur le primaire :

Jul 28 11:31:14 ve-jail named[288]: client 2a01:6600:8081:8e00::fab#46243: view wan: transfer of 'kafe-in.net/IN': AXFR started
Jul 28 11:31:14 ve-jail named[288]: client 2a01:6600:8081:8e00::fab#46243: view wan: transfer of 'kafe-in.net/IN': AXFR ended

Forcer la notification d'une zone

Parfois, surtout pendant la mise en place des serveurs, il faut « forcer » le primaire à notifier les secondaires sur une zone particulière afin qu'ils la téléchargent. Cela se fait avec la commande « rndc notify nom-de-la.zone ».

Sur le primaire :

# rndc -k rndc.key notify kafe-in.net
zone notify queued
# tail /var/log/daemon.log
Jul 28 11:39:36 ve-jail named[288]: zone kafe-in.net/IN: sending notifies (serial 2012072701)

Sur le secondaire :

Jul 28 11:39:36 muscat named[22111]: client 2001:910:109c:2::53#41892: received notify for zone 'kafe-in.net'
Jul 28 11:39:36 muscat named[22111]: zone kafe-in.net/IN: notify from 2001:910:109c:2::53#41892: zone is up to date

Reverse

Version simple

Pour l'IPv4 91.224.149.XXX

Coté tetaneutral.net dans 149.224.91.in-addr.arpa.zone

XXX IN    NS    ns1.bidule.net.
XXX IN    NS    ns2.truc.net.
XXX IN    NS    ns3.machin.net.

Coté adherent :

zone "XXX.149.224.91.in-addr.arpa" {
    type master;
    allow-transfer { slaves; };
    file "/etc/bind/db.91.224.149.XXX";
};

Et /etc/bind/db.91.224.149.XXX :

$TTL 43200
@    IN    SOA ns.mon.dns.net.    mail.mon.dns.net.    (
        2014100701    ; Serial number
        8h        ; Refresh 8 hours
        30m        ; Retry 30 minutes
        7d        ; Expires 7 days
        1d )        ; Minimum 1 day

        IN    NS    ns1.bidule.net.
        IN    NS    ns2.truc.net.
        IN    NS    ns3.machin.net.

@    IN    PTR    mon.reverse.net.

Délégation d'un reverse « classless »

Historiquement, le protocole DNS ne permet pas la délégation de reverses (association IP->nom) pour des préfixes « classless » (autres que /8, /16 et /24). Toutefois, le RFC 2317 décrit une astuce permettant cela.

Le principe est plutôt simple : on définit un CNAME pour le reverse en question et il est parfaitement légitime de déléguer la résolution d'un CNAME à un autre NS. Le tour est joué.

Pour l'exemple, disons que tetaneutral.net délègue 91.224.149.142 à dns.kafe-in.net. La convention de nommage du CNAME est « dernier_digit IN CNAME dernier_digit.subnet/netmask ».

Ainsi pour déléguer 91.224.149.142/32 dans la zone 149.224.91.in-addr.arpa. :

142/32  IN NS    dns.kafe-in.net.
142     IN CNAME 142.142/32.149.224.91.in-addr.arpa.

Attention : le NS désigné (ici "dns.kafe-int.net") doit avoir un enregistrement A et AAAA et ne dois pas etre un CNAME.

Sur le serveur DNS de l'adhérent il suffit alors d'héberger une zone 142/32.149.224.91.in-addr.arpa. et d'y positionner le PTR désiré pour son IP.

Dans named.conf :

zone "142/32.149.224.91.in-addr.arpa" IN {
        type  master;
        file  "wan/142-32.149.224.91.in-addr.arpa.zone";
};

Et dans 142-32.149.224.91.in-addr.arpa.zone :

$ORIGIN .
$TTL 864000
142/32.149.224.91.in-addr.arpa IN SOA dns.kafe-in.net. fab.kafe-in.net. ( 
        2012071201 ; serial
        3600 ; refresh
        900 ; retry
        1209600 ; expire
        43200 ; default_ttl
) 

$ORIGIN 142/32.149.224.91.in-addr.arpa.
        IN NS   dns.kafe-in.net.
142     IN PTR  muscat.kafe-in.net.

Lors d'une résolution, cela done :

# dig +trace -x 91.224.149.142

; <<>> DiG 9.8.1-P1 <<>> +trace -x 91.224.149.142
;; global options: +cmd
.            136994    IN    NS    b.root-servers.net.
.            136994    IN    NS    k.root-servers.net.
.            136994    IN    NS    a.root-servers.net.
.            136994    IN    NS    l.root-servers.net.
.            136994    IN    NS    g.root-servers.net.
.            136994    IN    NS    f.root-servers.net.
.            136994    IN    NS    m.root-servers.net.
.            136994    IN    NS    i.root-servers.net.
.            136994    IN    NS    c.root-servers.net.
.            136994    IN    NS    d.root-servers.net.
.            136994    IN    NS    e.root-servers.net.
.            136994    IN    NS    h.root-servers.net.
.            136994    IN    NS    j.root-servers.net.
;; Received 512 bytes from 91.224.149.254#53(91.224.149.254) in 25 ms

in-addr.arpa.        172800    IN    NS    a.in-addr-servers.arpa.
in-addr.arpa.        172800    IN    NS    b.in-addr-servers.arpa.
in-addr.arpa.        172800    IN    NS    c.in-addr-servers.arpa.
in-addr.arpa.        172800    IN    NS    d.in-addr-servers.arpa.
in-addr.arpa.        172800    IN    NS    e.in-addr-servers.arpa.
in-addr.arpa.        172800    IN    NS    f.in-addr-servers.arpa.
;; Received 432 bytes from 128.63.2.53#53(128.63.2.53) in 131 ms

n-addr.arpa.    86400    IN    NS    ns3.nic.fr.
91.in-addr.arpa.    86400    IN    NS    pri.authdns.ripe.net.
91.in-addr.arpa.    86400    IN    NS    sec1.apnic.net.
91.in-addr.arpa.    86400    IN    NS    sec3.apnic.net.
91.in-addr.arpa.    86400    IN    NS    sns-pb.isc.org.
91.in-addr.arpa.    86400    IN    NS    tinnie.arin.net.
;; Received 201 bytes from 196.216.169.10#53(196.216.169.10) in 209 ms

149.224.91.in-addr.arpa. 172800    IN    NS    ns2.tetaneutral.net.
149.224.91.in-addr.arpa. 172800    IN    NS    ns1.tetaneutral.net.
;; Received 96 bytes from 2001:660:3006:1::1:1#53(2001:660:3006:1::1:1) in 17 ms

142.149.224.91.in-addr.arpa. 86400 IN    CNAME    142.142/149.224.91.in-addr.arpa.
142/32.149.224.91.in-addr.arpa. 86400 IN    NS    dns.kafe-in.net.
;; Received 213 bytes from 2a01:6600:8000::3#53(2a01:6600:8000::3) in 14 ms

# dig -x 91.224.149.142

; <<>> DiG 9.8.1-P1 <<>> -x 91.224.149.142
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7168
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;142.149.224.91.in-addr.arpa.    IN    PTR

;; ANSWER SECTION:
142.149.224.91.in-addr.arpa. 86359 IN    CNAME    142.142/32.224.91.in-addr.arpa.
142.142/32.224.91.in-addr.arpa. 172795 IN PTR muscat.kafe-in.net.

;; AUTHORITY SECTION:
142.142/32.224.91.in-addr.arpa. 172795 IN NS    dns.kafe-in.net.

;; ADDITIONAL SECTION:
dns.kafe-in.net.    6732    IN    A    80.67.176.156

;; Query time: 1 msec
;; SERVER: 91.224.149.254#53(91.224.149.254)
;; WHEN: Sat Aug  4 09:48:12 2012
;; MSG SIZE  rcvd: 229

IPv6

Dans /etc/bind/named.conf :

zone "4.5.1.8.0.8.0.0.6.6.1.0.a.2.ip6.arpa" IN {
        type  master;
        file  "/etc/bind/4.5.1.8.0.8.0.0.6.6.1.0.a.2.ip6.arpa.zone";
};

Dans /etc/bind/4.5.1.8.0.8.0.0.6.6.1.0.a.2.ip6.arpa.zone :

$ORIGIN 4.5.1.8.0.8.0.0.6.6.1.0.a.2.ip6.arpa.
$TTL 864000
@ SOA ipgsm.tetaneutral.net. root.ipgsm.tetaneutral.net. ( 
        2014081808 ; serial
        3600 ; refresh
        900 ; retry
        1209600 ; expire
        43200 ; default_ttl
) 

@       IN NS   ipgsm.tetaneutral.net.

$ORIGIN 0.0.4.5.1.8.0.8.0.0.6.6.1.0.a.2.ip6.arpa.

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR  bas1.toulouse-91-224-149.w31-84.abo.rev.ipgsm.net.

Dans /etc/bind/named.conf.options

options {
   ...

   allow-recursion { 127.0.0.1; };
};