Traduction(s): English - French

(!) ?Discussion

Présentation

La mise en place d'un serveur DNS sur un réseau permet de remplacer les adresses IP des machines par un nom. Ainsi, il est même possible d'associer plusieurs noms à la même machine pour mettre en évidence les différents services possibles. Du coup, www.example.com et pop.example.com, peuvent pointer sur le serveur principal où sont présents le serveur de mail et l'intranet de l'entreprise dont le domaine serait example.com. C'est tout de même plus facile que de se rappeler que ces deux services tournent sur la machine dont l'adresse IP est 192.168.0.1.

Imaginez maintenant, que l'administrateur de notre entreprise décide pour une raison ou une autre de déplacer le serveur de mail sur la machine 192.168.0.11. Il n'y a rien à faire du tout sauf modifier le fichier de configuration du serveur DNS. Il vous reste toujours la possibilité d'aller modifier le fichier hosts de tous les utilisateurs, mais cela risque de prendre du temps et d'embêter certaines personnes.

Définitions

Disposition réseau

Nous disposons d'un accès Internet via une xxxbox (192.168.1.1), de deux serveurs DNS fournis par notre FAI (80.10.249.2, 80.10.246.129). En fait, ces deux derniers ne seront jamais mentionnés dans la configuration car la xxxbox va se charger de faire la résolution de noms si elle ne connaît pas l'adresse de destination des paquets. Par conséquent, je considère la xxxbox comme le serveur primaire hors de notre domaine. Le serveur "sid" (192.168.1.10) est connecté à la xxxbox via sa première carte réseau. Il est aussi connecté au lan (192.168.0.0/24) via sa seconde interface réseau (192.168.0.1). C'est sur celui-ci que nous allons installer le serveur DNS primaire pour notre domaine example.com (RFC 2606) Tous les ordinateurs du LAN se voient attribuer une adresse IP automatiquement via le service DHCP. Ce dernier fournira aussi l'adresse du serveur DNS primaire situé sur notre domaine, et mettra à jour les noms d'hôtes pour la zone example.com auxquels il aura attribué une adresse IP.

Gestion du serveur

Installation

On va utiliser le paquet bind9 pour faire tout ça.

# apt-get install bind9 

et puis si vous voulez installer en plus la documentation, (très utile) :

# apt-get install bind9-doc

Configuration

Après l'installation, on va voir un peu du coté des fichiers de configuration. Ils sont placés dans le répertoire /etc/bind/

Signature TSIG

Cette signature a pour but d'authentifier les transactions avec BIND. Ainsi, le serveur DHCP ne pourra mettre à jour le domaine example.com que s'il dispose de cette clef. On recopie une clef existante :

# cd /etc/bind/
# cat rndc.key
key "rndc-key" {
        algorithm hmac-md5;
        secret "QJc08cnP1xkoF4a/eSZZbw==";
};

# cp rndc.key ns-example-com_rndc-key

On génère une nouvelle clef avec les options suivantes :

dnssec-keygen -a HMAC-MD5 -b 512 -n USER ns-example-com_rndc-key
Kns-example-com_rndc-key.+157+53334

Le footprint associé à la clef est 53334. On obtient alors deux fichiers, l'un avec une extension key et l'autre avec une extension private. On substitue la clef présente dans le fichier ns-example-com_rndc-key par celle présente dans un de ces derniers.

# cat Kns-example-com_rndc-key.+157+53334.private
Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: LZ5m+L/HAmtc9rs9OU2RGstsg+Ud0TMXOT+C4rK7+YNUo3vNxKx/197o2Z80t6gA34AEaAf3F+hEodV4K+SWvA==
Bits: AAA=

# cat ns-example-com_rndc-key
key "ns-example-com_rndc-key" {
        algorithm hmac-md5;
        secret "LZ5m+L/HAmtc9rs9OU2RGstsg+Ud0TMXOT+C4rK7+YNUo3vNxKx/197o2Z80t6gA34AEaAf3F+hEodV4K+SWvA==";
};

Le fichier ns-example-com_rndc-key ne doit pas être world-readable, afin de garantir la sécurité. Celui-ci sera inséré dans la configuration de bind via une directive include car la configuration de bind est quant à elle world-readable. On pensera aussi à supprimer les fichiers key et private précédemment générés.

Fichier /etc/bind/named.conf

Ce fichier est le fichier de configuration principal du serveur DNS.

// Gérer les acls
acl internals { 127.0.0.0/8; 192.168.0.0/24; };

// Charger les options
include "/etc/bind/named.conf.options";

// Déclaration de la clef TSIG utilisée pour la mise à jour dynamique
include "/etc/bind/ns-example-com_rndc-key";

// Configurer le canal de communication pour administrer BIND9 avec rndc
// Par défaut, la clef est située dans le fichier rndc.key et utilisée par
// rndc et bind9 sur localhost
controls {
        inet 127.0.0.1 port 953 allow { 127.0.0.1; };
};

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


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

Note : Dans Debian Jessie la partie 'zone "." {...}' est dans le fichier "named.conf.default-zones". Inutile de l'ajouter dans le fichier "named.conf"

Fichier /etc/bind/named.conf.default-zones

Note : depuis Debian 7 « Wheezy » bind9 embarque un fichier contenant les zones par défaut forward, reverse, et broadcast.

// 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";
};

Fichier /etc/bind/named.conf.options

Ce fichier contient l'ensemble des options de configuration du serveur DNS.

options {
        directory "/var/cache/bind";

        // Port d'échange entre les serveurs DNS
        query-source address * port *;

        // Transmettre les requêtes à 192.168.1.1 si ce serveur ne sait pas résoudre ces adresses.
        // On pourrait aussi bien renseigner les serveurs DNS du FAI plutôt que de renseigner
        // l'adresse IP du routeur (xxxbox)
        forward only;
        forwarders { 192.168.1.1; };

        auth-nxdomain no;    # conform to RFC1035

        // Ecouter sur les interfaces locales uniquement (IPV4)
        listen-on-v6 { none; };
        listen-on { 127.0.0.1; 192.168.0.1; };

        // Ne pas transférer les informations de zones aux DNS secondaires
        allow-transfer { none; };

        // Accepter les requêtes pour le réseau interne uniquement
        allow-query { internals; };

        // Autoriser les requêtes récursives pour les hôtes locaux
        allow-recursion { internals; };

        // Ne pas rendre publique la version de BIND
        version none;
};

Le port associé à l'option query-source ne doit en aucun cas être figé car il fragilise les transactions DNS dans le cas d'un résolveur.

M. Rash a écrit un article intéressant à propos de cela et comment forcer le port source de manière aléatoire par le biais d'iptables :Mitigating DNS Cache Poisoning Attacks with iptables

Afin de diminuer la temporisation de timeout pour les connexions UDP, et ainsi mettre en évidence la randomization qui par défaut est de 30s par tuple, il suffit de mettre à jour le paramètre net.netfilter.nf_conntrack_udp_timeout

# sysctl -w net.netfilter.nf_conntrack_udp_timeout=10

pour obtenir un timeout à 10s.

Fichier /etc/bind/named.conf.local

Ce fichier contient la configuration local du serveur DNS, on y déclare les zones associées au domaine.

// Gérer les fichiers de logs
include "/etc/bind/named.conf.log";

// Gestion du domaine example.com
// ------------------------------
//  - Le serveur est défini comme maître sur ce domaine
//  - Il n'y a aucun forwarder pour ce domaine car nous avons la main mise dessus.
//    Pour tous les autres domaines, nous utiliserons le forwarder mentionné dans *named.conf.options*
//  - Les entrees sur le domaine peuvent être ajoutées dynamiquement avec le clef ns-example-com_rndc-key
zone "example.com" {
        type master;
        file "/var/cache/bind/db.example.com";
        forwarders {};
        allow-update { key ns-example-com_rndc-key; };
};
zone "0.168.192.in-addr.arpa" {
        type master;
        file "/var/cache/bind/db.example.com.inv";
        forwarders {};
        allow-update { key ns-example-com_rndc-key; };
};

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

Fichier /etc/bind/named.conf.log

Sous Debian Jessie, ce fichier est à créer dans /etc/bind

logging {
        channel update_debug {
                file "/var/log/update_debug.log" versions 3 size 100k;
                severity debug;
                print-severity  yes;
                print-time      yes;
        };
        channel security_info {
                file "/var/log/security_info.log" versions 1 size 100k;
                severity info;
                print-severity  yes;
                print-time      yes;
        };
        channel bind_log {
                file "/var/log/bind.log" versions 3 size 1m;
                severity info;
                print-category  yes;
                print-severity  yes;
                print-time      yes;
        };

        category default { bind_log; };
        category lame-servers { null; };
        category update { update_debug; };
        category update-security { update_debug; };
        category security { security_info; };
};

On définit ici les différentes méthodes de log pour les différentes catégories. La première catégorie est comme son nom l'indique la catégorie par défaut qui est habituellement affectée au syslog. Toute catégorie non mentionnée, est assimilée à la catégorie default. Pour obtenir une liste des différentes catégories, consulterle manuel de référence de l'administrateur pour bind9. Pour ce qui est des lame-servers, on ignore tous les logs qui leur sont associés.

Les Ressources Records (RR)

Un DNS est constitué de plusieurs enregistrements, les RR ou Ressources Records, définissant les diverses informations relatives au domaine. Le premier enregistrement est consacré à la résolution de noms, dans notre cas, il s'agit du fichier db.example.com. Le second sera quant à lui en rapport avec la résolution de noms inverses ; il s'agit du fichier db.example.com.inv.

Les fichiers dans var/cache/bind/

$TTL    3600
@       IN      SOA     sid.example.com. root.example.com. (
                   2007010401           ; Serial
                         3600           ; Refresh [1h]
                          600           ; Retry   [10m]
                        86400           ; Expire  [1d]
                          600 )         ; Negative Cache TTL [1h]
;
@       IN      NS      sid.example.com.
@       IN      MX      10 sid.example.com.

sid     IN      A       192.168.0.1
etch    IN      A       192.168.0.2

pop     IN      CNAME   sid
www     IN      CNAME   sid
mail    IN      CNAME   sid

@ IN SOA        sid.example.com. root.example.com. (
                   2007010401           ; Serial
                         3600           ; Refresh [1h]
                          600           ; Retry   [10m]
                        86400           ; Expire  [1d]
                          600 )         ; Negative Cache TTL [1h]
;
@       IN      NS      sid.example.com.

1       IN      PTR     sid.example.com.
2       IN      PTR     etch.example.com.

Quelques explications :

$TTL : (Time To Live) exprime la duree (en secondes) de validité, par défaut, des informations que contiennent les RRs. Une fois ce délai expiré, il est nécessaire de vérifier à nouveau les données. Les différents types :

Les classes : IN determine l'association a la classe Internet. D'autres classes sont disponibles (CH et HS). Pour de plus amples informations vous pouvez consulter laRFC 1035

Fichier /etc/resolv.conf

search example.com

Il est pas des plus compliqué celui-la !

Chroot de bind

Par défaut, la configuration de bind emploie l'utilisateur bind pour exécuter le démon named.

Ainsi, on retrouve cette option dans /etc/default/bind9 (NOTE : cela n'est pas valide pour Debian Jessie qui utilise systemd) :

OPTIONS="-u bind"

Le script de démarrage de bind /etc/init.d/bind9 lit ce fichier de configuration quand le service est lancé.

Démarrer bind en tant que simple utilisateur est une bonne pratique mais pour lancer le démon dans un environnement chroot, nous devons également spécifier le répertoire chroot. Cela se fait en utilisant la même variable OPTIONS dans /etc/default/bind9.

Pour commencer, stoppez le service bind :

/etc/init.d/bind9 stop

Ensuite, éditez /etc/default/bind9 (pas pour Debian Jessie) :

OPTIONS="-u bind -t /var/bind9/chroot"

Pour Jessie, créez le fichier /etc/systemd/system/bind9.service avec les options "-t /var/bind9/chroot" :

[Unit]
Description=BIND Domain Name Server
Documentation=man:named(8)
After=network.target

[Service]
ExecStart=/usr/sbin/named -f -u bind -t /var/bind9/chroot
ExecReload=/usr/sbin/rndc reload
ExecStop=/usr/sbin/rndc stop

[Install]
WantedBy=multi-user.target

Pour Jessie, après avoir créé le fichier ci-dessus, mettez à jour le lien symbolique vers le fichier avec :

systemctl reenable bind9

Maintenant, créez la structure de répertoire de chroot :

mkdir -p /var/bind9/chroot/{etc,dev,var/cache/bind,var/run/named}

Créez les fichiers spéciaux de périphérique requis et définissez les permissions appropriées :

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}

Déplacez le répertoire de configuration actuel dans le nouveau répertoire chroot :

mv /etc/bind /var/bind9/chroot/etc

Créez maintenant un lien symbolique dans /etc pour une compatibilité :

ln -s /var/bind9/chroot/etc/bind /etc/bind 

Si vous voulez utiliser la timezone locale dans le chroot (par exemple, pour syslog) :

cp /etc/localtime /var/bind9/chroot/etc/

Changez le propriétaire sur les fichiers que vous venez de déplacer dessus et le reste de la structure de répertoire du chroot nouvellement créé :

chown bind:bind /var/bind9/chroot/etc/bind/rndc.key
chmod 775 /var/bind9/chroot/var/{cache/bind,run/named}
chgrp bind /var/bind9/chroot/var/{cache/bind,run/named}

Éditez la variable PIDFILE dans /etc/init.d/bind9 vers le chemin correct :

PIDFILE=/var/bind9/chroot/var/run/named/named.pid

Enfin, indiquez à rsyslog d'écouter les journaux (logs) de bind dans le bon endroit :

echo "\$AddUnixListenSocket /var/bind9/chroot/dev/log" > /etc/rsyslog.d/bind-chroot.conf

Redémarrez rsyslog et démarrez bind :

/etc/init.d/rsyslog restart; /etc/init.d/bind9 start

Gestion des clients

Comme je l'ai mentionné au début, l'attribution des adresses IP sur le réseau local est effectué par le serveur DHCP. Ainsi, pour définir notre serveur DNS aux différents clients, il est nécessaire d'ajouter au fichier de configuration DHCP les deux lignes suivantes :

option domain-name "example.com"

option domain-name-server sid.example.com

Il faut ajouter aux fichiers (je pense) les zones pour lesquelles DHCP devrait effectuer automatiquement des mises à jour.

Syntaxe (paramètres "=>" commentaires) :

zone [name.of.the.zone.] {

}

Exemples de [name.of.the.zone.] (avec le "." à la fin) :

- example.com. : pour la zone directe de cet objet,

- 0.168.192.in-addr.arpa. : pour la zone inverse de cet objet.

Pour de plus amples informations sur la mise en place de la mise à jour dynamique des enregistrements DNS via DHCP voir ici

Les outils de tests

Liens et Ressources


/!\ ?ToDos