(Modifié le 09/01/2019)

Résolveur DNS Unbound

DNS Unbound

Les serveurs DNS sont des machines discutant entre elles afin de se communiquer les correspondances entre nom de domaine et adresses IP.

Installer unbound

Passage en mode super utilisateur

sudo -s # ou su

Désinstaller bind

apt remove --purge bind* -y
rm -r /var/cache/bind/

Installation des outils dns et du paquet Unbound :

apt install dnsutils unbound -y

Serveurs DNS racines

Téléchargement de la liste des serveurs DNS racines :

cd /var/lib/unbound/ && wget ftp://ftp.internic.net/domain/named.cache

Mise en place de cette liste pour le serveur Unbound :

mv named.cache root.hints && chown unbound:unbound root.hints

Configurer unbound

Les fichiers de configuration sont situés sous /etc/unbound/unbound.conf.d/

root-auto-trust-anchor-file.conf est créé par défaut à l’installation

server:
    # The following line will configure unbound to perform cryptographic
    # DNSSEC validation using the root trust anchor.
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

qname-minimisation.conf est créé par défaut à l’installation

server:
    # Send minimum amount of information to upstream servers to enhance
    # privacy. Only sends minimum required labels of the QNAME and sets
    # QTYPE to NS when possible.

    # See RFC 7816 "DNS Query Name Minimisation to Improve Privacy" for
    # details.

    qname-minimisation: yes

Ajout d’un fichier de configuration dns-yan.conf

nano /etc/unbound/unbound.conf.d/dns-yan.conf
server:
 interface: 0.0.0.0                          # 0.0.0.0 unbound sur plusieurs interfaces
 interface: ::0
 access-control: 0.0.0.0/0 allow
 access-control: ::/0 allow
 root-hints: "/var/lib/unbound/root.hints"
 verbosity: 0                                # 0 messages (erreurs uniquement)
 #qname-minimisation: yes

 num-threads: 2
 msg-cache-slabs: 4
 rrset-cache-slabs: 4
 infra-cache-slabs: 4
 key-cache-slabs: 4
 rrset-cache-size: 100m
 msg-cache-size: 50m
 outgoing-range: 465
 so-rcvbuf: 4m
 so-sndbuf: 4m
 port: 53
 do-ip4: yes
 do-ip6: yes
 do-udp: yes
 do-tcp: yes
 do-daemonize: yes
 hide-identity: yes
 hide-version: yes
 harden-glue: yes
 harden-dnssec-stripped: yes
 harden-referral-path: yes
 use-caps-for-id: yes
 prefetch: yes

Pour vérifier si le fichier de configuration est valide

unbound-checkconf /etc/unbound/unbound.conf.d/dns-yan.conf

Démarrer et vérifier unbound

Redémarrer le service dnsunbound

systemctl restart unbound

Les commandes suivantes ne fonctionneront que si le paquet “dnsutils” est installé sur votre système Debian!

dig @127.0.0.1 afnic.fr +short +dnssec
192.134.5.25
A 8 2 600 20180406223409 20180307194345 64860 afnic.fr. lhw7AmNSkeZOtNN/9rJuGYxTdUcXSR3xlbsKz2xjNbFxQT5FwKILTW+E WWawrrbjo79uaG7kAvfMWrah4ijWtz9qGyd76qTr3XVdXB3+pbIsRr6X /I/ryQAy9w8tP3FvXHHU7IxihP+Ei2M5licCYitt1YZUyXuNFdNpdhq7 FRT+tq78yn1PEm121f32IRQ2Fjy9qZz9O0LU7roYZ6XFoPU9x3PU590J mpkywT9t6LpyeW5GK5zSL+Zb5eiFhfp33abkMf7b6Pc7xixcGN8h8SDQ Ry98Ne0EIqHKnyh/zzRszc1kBfP5kJXmcY/X3+4xLvKmvKNnBLT0dsn1 q1Hl1A==

Si la commande dig-command a fonctionné, vous pouvez maintenant définir Unbound comme premier résolveur DNS pour votre système de messagerie , paragraphe suivant

Résolution des noms avec resolvconf sous Linux Debian

En fonction du type de connexion utilisé, il est parfois nécessaire de faire appel à différents serveurs de noms (DNS). Par exemple, lors d’une connexion à son lieu de travail, il faut utiliser le serveur DNS de son réseau, mais lors d’une connexion à internet, il faut utiliser les serveurs DNS de son fournisseur d’accès. Dans ce cas, le paquet “resolvconf” sous Debian permet de résoudre ces problèmes.

Rappel sur l’utilité du fichier « /etc/resolv.conf »
Ce fichier permet d’indiquer le ou les domaines de recherche et les différents serveurs DNS à utiliser.

Par exemple, dans un réseau local, nous pourrions avoir un serveur DNS à l’adresse 192.168.0.1 chargé de gérer le domaine « mon-domaine.local ». En cas de défaillance du DNS local, nous pourrions faire appel aux serveurs DNS de notre fournisseur d’accès. Dans ce cas, le contenu du fichier « /etc/resolv.conf », pourrait ressembler à cela :

nameserver 192.168.0.1
nameserver 212.27.53.252
nameserver 212.27.52.252
search mon-domaine.local

La première ligne indique l’adresse du serveur DNS du réseau local. En cas de défaillance de ce serveur, les serveurs suivants seront utilisés (Serveurs du fournisseur d’accès à Internet).

La dernière ligne permet d’indiquer le nom du domaine géré par le serveur DNS local. Par exemple, si nous cherchons à contacter le serveur « MonServeur », le système cherchera en fait à contacter l’adresse complète « MonServeur.mon-domaine.local », car le nom du serveur indiqué ne comportait pas le domaine de recherche.

Présentation et installation de resolvconf
Le programme resolvconf garde la trace des informations du système sur les serveurs de noms de domaine actuellement disponibles. Il ne faut pas le confondre avec le fichier de configuration resolv.conf qui porte malencontreusement presque le même nom. Le programme resolvconf est optionnel sur les systèmes Debian.

Le fichier de configuration resolv.conf contient des informations sur les serveurs de noms de domaine que le système doit utiliser. Néanmoins, quand plusieurs programmes doivent modifer dynamiquement le fichier de configuration resolv.conf, ils peuvent se chevaucher et le fichier peut ne plus être synchronisé. Le programme resolvconf s’occupe de ce problème. Il agit comme un intermédiaire entre les programmes qui fournissent des informations sur les serveurs de noms de domaine (par exemple les clients dhcp) et les programmes qui les utilisent (par exemple resolver).

Quand resolvconf est correctement installé, le fichier de configuration resolv.conf du répertoire /etc/resolv.conf est remplacé par un lien symbolique pointant vers le fichier /etc/resolvconf/run/resolv.conf et le résolveur utilise plutôt le fichier de configuration qui est généré dynamiquement par resolvconf à cet emplacement /etc/resolvconf/run/resolv.conf.

Le programme resolvconf est en général seulement nécessaire quand un système a plusieurs programmes qui ont besoin de modifier de façon dynamique les informations sur les serveurs de noms de domaine. Sur un système simple où les serveurs de noms de domaine ne changent pas souvent ou bien ne sont modifiés que par un programme, le fichier de configuration resolv.conf est suffisant.

Si le programme resolvconf est installé, vous n’aurez pas à modifier à la main le fichier de configuration resolv.conf car il sera changé de façon dynamique par les programmes. Si vous avez besoin de définir vous-même les serveurs de noms de domaine (comme avec une interface statique), ajoutez au fichier de configuration interfaces du répertoire /etc/network/interfaces une ligne comme celle-ci :

dns-nameservers 127.0.0.1 80.67.169.12 80.67.169.40

Mettez la ligne indéntée dans un paragraphe iface, par exemple juste après la ligne gateway. Entrez les adresses IP des serveurs de noms de domaine dont vous avez besoin après dns-nameservers, toutes sur la même ligne, séparées par des espaces. N’oubliez pas le “s” à la fin de dns-nameservers.

Le programme resolvconf est un ajout plutôt récent à Debian et plusieurs anciens programmes ont besoin d’être mis à jour ou reconfigurés pour fonctionner correctement avec lui . Si vous rencontrez des problèmes, regardez /usr/share/doc/resolvconf/README qui contient beaucoup d’informations sur la manière de faire fonctionner resolvconf avec d’autres programmes.

apt install resolvconf -y
echo "nameserver 127.0.0.1" >> /etc/resolvconf/resolv.conf.d/head

Une fois le paquet « resolvconf » installé, il ne faut plus modifier le fichier « /etc/resolv.conf », car le contenu de celui-ci sera automatiquement géré et remplacé par « resolvconf ».

Structure réseau debian

tree /etc/network/
/etc/network/
├── if-down.d
│   ├── resolvconf
│   └── upstart
├── if-post-down.d
├── if-pre-up.d
├── if-up.d
│   ├── 000resolvconf
│   ├── openssh-server
│   └── upstart
├── interfaces
├── interfaces.d
│   └── 50-cloud-init.cfg
└── interfaces.save

Le résultat de la commande

nslookup afnic.fr | grep Server

devrait ressembler à ceci:

Server:     127.0.0.1

Vérifier la résolution de nom à partir du serveur :

dig @127.0.0.1 afnic.fr
; <<>> DiG 9.10.3-P4-Debian <<>> @127.0.0.1 afnic.fr
; (1 server found)
...
;; SERVER: 127.0.0.1#53(127.0.0.1)
...

La résolution fonctionne

Maintenant, vous disposez de votre propre résolveur DNS.

Mise à jour automatique des serveurs DNS de la racine

Mise à jour automatique des serveurs DNS de la racine ,créer un bash

nano /etc/unbound/dnsunbound-update-root-dns.sh
#!/bin/sh

TmpName=$(mktemp)
TmpDiff=$(mktemp)
TmpErr=$(mktemp)
REPORT_EMAIL="admin"
URL="https://www.internic.net/domain/named.cache"

wget -nv $URL -O $TmpName 2> $TmpErr

# On intercepte toute erreur
# et on stoppe le script dans ce cas
# On continue sinon

if [ "$?" -ne 0 ];then
        printf "\nScript was stopped at this point. A manual action may be required.\n" >> $TmpErr
        mail -s "[DNS - $(uname -n)] Root hints file download failed" $REPORT_EMAIL < $TmpErr
        rm $TmpErr
        rm $TmpDiff
        rm $TmpName
        exit 0
else
        rm $TmpErr
        shaTMP=$(sha512sum $TmpName | awk '{print $1}')
        shaHINTS=$(sha512sum /var/lib/unbound/root.hints | awk '{print $1}')

        if [ $shaTMP = $shaHINTS ]; then
        # Si le fichier récupéré est identique à celui
        # utilisé par Unbound, on fait... rien
                rm $TmpName
                exit 0
        else
                printf "A new root hints file was spotted on InterNIC server.\nFile downloaded and old root.hints file replaced.\nHere is the diff:\n\n" > $Tmp$
                diff $TmpName /var/lib/unbound/root.hints >> $TmpDiff
                printf "\n\n" >> $TmpDiff
                mv -f $TmpName /var/lib/unbound/root.hints
                chown unbound: /var/lib/unbound/root.hints
                chmod 644 /var/lib/unbound/root.hints
                sleep 5
                service unbound restart
                printf "Unbound status is $(service unbound status | grep Active | awk '{print $2 " " $3}')\n" >> $TmpDiff
                mail -s "[DNS - $(uname -n)] Update in Root Hints" $REPORT_EMAIL < $TmpDiff
        rm $TmpDiff
        fi
fi
exit 0

Droits en exécution

chmod +x /etc/unbound/dnsunbound-update-root-dns.sh

Planification journalière

crontab -e

Ajouter en fin de fichier

# Mise à jour automatique des serveurs DNS de la racine
50 02 * * * /etc/unbound/dnsunbound-update-root-dns.sh > /dev/null

Bloquer la publicité

Générer une liste des domaines ou sites à bloquer à partir d’une liste existante (https://github.com/StevenBlack/hosts) , créer un bash /etc/unbound/unbound.conf.d/liste-domaines-bloques.sh

nano /etc/unbound/unbound.conf.d/liste-domaines-bloques.sh
#!/bin/bash

# list of ads domain names
wget --quiet https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn-social/hosts -O w
grep -v " #\|<td>\|<p>\|<meta>\|<link>\|<title>\|href\|title=\|=\|<" w > adsList.txt
rm w # remove host syntax and clean file
sed -i 's/0.0.0.0//g' adsList.txt
sed -i 's/127.0.0.1//g' adsList.txt
sed -i 's/localhost//g' adsList.txt
sed -i 's/.localdomain//g' adsList.txt

# remove commentary after domain name
sed -i 's/#.*//' adsList.txt

# remove tabulation character and carriage return
sed -i "s/\t//g" adsList.txt
sed -i "s/\r//g" adsList.txt

# remove useless space
sed -i 's/ //g' adsList.txt

# remove empty lines
sed -i '/^\s*$/d' adsList.txt


# add prefix and suffix for unbound
sed -i "s/.*/local-zone: \"&\" static/" adsList.txt

cat adsList.txt >> adsListFinal.txt

# order list by name, it didn't cost a lot and could maybe increase unbound performance
sort adsListFinal.txt -o adsListFinal.txt

# remove duplicate ads domain in order to avoid warning with Unbound
uniq adsListFinal.txt > adslist.txt

# remove tempory files
rm adsListFinal.txt adsList.txt

# fichier copié puis effacé 
cp adslist.txt /etc/unbound/unbound.conf.d/
rm adslist.txt

# Redémarrer unbound
systemctl restart unbound

exit 0

Droits en exécution

chmod +x /etc/unbound/unbound.conf.d/liste-domaines-bloques.sh

Planification journalière

crontab -e

Ajouter en fin de fichier

# Générer une liste des domaines à bloquer
40 02 * * * /etc/unbound/unbound.conf.d/liste-domaines-bloques.sh > /dev/null

Le paramètre local-zone accepte les types suivants :

  • deny : n’envoie pas de réponse et jette la requête, sauf si un enregistrement local-data est trouvé, auquel cas ce dernier est servi.
  • refuse : renvoie un code de réponse REFUSED à la requête, sauf si un enregistrement local est trouvé, auquel cas ce dernier est servi.
  • static : Si une donnée local-data est trouvée, celle-ci est servie. Sinon, la requête se voit répondre NODATA ou NXDOMAIN. Dans ce cas là, si un enregistrement local SOA est défini, ce dernier est également servi.
  • always_deny : comme deny mais ignore tout enregistrement local.

La liste des domaines à bloquer adslist.txt est configuré avec static

Ajouter la prise en charge en fin de fichier configuration /etc/unbound/unbound.conf.d/dns-yan.conf

include: /etc/unbound/unbound.conf.d/adslist.txt 

Pour vérifier si le fichier de configuration est valide

unbound-checkconf /etc/unbound/unbound.conf.d/dns-yan.conf

Redémarrer le service dnsunbound

systemctl restart unbound

Test avec un site qui est dans la liste

dig ad2.adfarm1.adition.com
; <<>> DiG 9.10.3-P4-Debian <<>> ad2.adfarm1.adition.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 48255
...
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)

La requête DNS n’est pas servie et se voit répondre NXDOMAIN

Liens