Introduction
Unbound :
- Resolveur recursif (interroge les root servers directement)
- Validation DNSSEC native
- Support DNS-over-TLS (DoT) sortant
- Cache performant, tres faible empreinte memoire
- Ecrit en C, audite, focus securite (NLnet Labs)
- Multi-thread, configurable jusqu'a 100k qps
Utilisez Unbound quand :
- Vous voulez un resolveur local sans dependance externe (privacy)
- Vous gerez un LAN d'entreprise / datacenter
- Vous voulez bloquer la pub/malware (avec listes)
- Vous voulez du DNS chiffre vers l'amont
Prerequis
- VPS Linux Debian / Ubuntu
- Acces root
- Port 53 UDP/TCP libre
Etape 1 : Installation
sudo apt update
sudo apt install -y unbound
unbound -V
sudo systemctl enable --now unbound
Etape 2 : Configuration minimale (resolveur LAN)
sudo nano /etc/unbound/unbound.conf.d/lan.conf
server:
verbosity: 1
interface: 0.0.0.0
port: 53
access-control: 127.0.0.0/8 allow
access-control: 192.168.0.0/16 allow
access-control: 10.0.0.0/8 allow
access-control: 172.16.0.0/12 allow
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: yes
cache-min-ttl: 300
cache-max-ttl: 86400
prefetch: yes
prefetch-key: yes
num-threads: 2
msg-cache-size: 64m
rrset-cache-size: 128m
Etape 3 : Telecharger les root hints
sudo wget https://www.internic.net/domain/named.root -O /var/lib/unbound/root.hints
Dans la config :
server:
root-hints: "/var/lib/unbound/root.hints"
Pour DNSSEC :
sudo unbound-anchor -a /var/lib/unbound/root.key
server:
auto-trust-anchor-file: "/var/lib/unbound/root.key"
Etape 4 : Tester
sudo unbound-checkconf
sudo systemctl restart unbound
Resolvez :
dig @127.0.0.1 google.com
dig @127.0.0.1 verycloud.fr
Verifiez DNSSEC :
dig @127.0.0.1 +dnssec dnssec-failed.org
Devrait retourner SERVFAIL (signature DNSSEC invalide bloquee par Unbound).
dig @127.0.0.1 +dnssec cloudflare.com
Devrait retourner ad dans flags (Authentic Data) = validation DNSSEC OK.
Etape 5 : DNS-over-TLS sortant (DoT)
Pour chiffrer le trafic DNS sortant vers Quad9/Cloudflare au lieu de l'envoyer en clair :
server:
tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 9.9.9.9@853#dns.quad9.net
forward-addr: 149.112.112.112@853#dns.quad9.net
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
⚠️ Avec cette config, Unbound n'est plus recursif (il forwarde). C'est un compromis : moins de privacy granulaire, mais le trafic est chiffre vers l'amont.
sudo systemctl restart unbound
Etape 6 : Resolveur recursif et DoT pour certaines zones
Mode hybride : recursif par defaut, mais forwarde certaines zones sensibles :
forward-zone:
name: "google.com"
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
# Le reste passe par la recursion normale
Etape 7 : Blocage de pub / malware
Telechargez une liste de domaines a bloquer (StevenBlack/hosts ou autre) :
sudo wget https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts -O /tmp/hosts
Convertissez en format Unbound :
sudo grep "^0.0.0.0" /tmp/hosts | awk '{print "local-zone: \""$2"\" always_nxdomain"}' > /etc/unbound/unbound.conf.d/blocklist.conf
sudo systemctl restart unbound
Testez :
dig @127.0.0.1 doubleclick.net
Devrait retourner NXDOMAIN.
Pour automatiser le refresh :
sudo nano /usr/local/bin/update-blocklist.sh
#!/bin/bash
wget -q https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts -O /tmp/hosts
grep "^0.0.0.0" /tmp/hosts | awk '{print "local-zone: \""$2"\" always_nxdomain"}' > /etc/unbound/unbound.conf.d/blocklist.conf
systemctl reload unbound
sudo chmod +x /usr/local/bin/update-blocklist.sh
echo "0 4 * * 0 root /usr/local/bin/update-blocklist.sh" | sudo tee -a /etc/crontab
Etape 8 : Zones locales (resolution interne)
Pour resoudre des noms internes :
server:
local-zone: "verycloud.lan." static
local-data: "server1.verycloud.lan. IN A 192.168.50.10"
local-data: "server2.verycloud.lan. IN A 192.168.50.11"
local-data-ptr: "192.168.50.10 server1.verycloud.lan"
local-data-ptr: "192.168.50.11 server2.verycloud.lan"
Etape 9 : Performance et tuning
Pour des charges elevees, augmentez :
server:
num-threads: 4
msg-cache-slabs: 8
rrset-cache-slabs: 8
infra-cache-slabs: 8
key-cache-slabs: 8
msg-cache-size: 256m
rrset-cache-size: 512m
so-rcvbuf: 4m
so-sndbuf: 4m
so-reuseport: yes
outgoing-range: 8192
num-queries-per-thread: 4096
Etape 10 : Monitoring
Activez les stats :
remote-control:
control-enable: yes
control-interface: 127.0.0.1
control-use-cert: no
sudo unbound-control stats
Sortie :
total.num.queries=12345
total.num.cachehits=10000
total.num.cachemiss=2345
total.num.recursivereplies=2345
mem.cache.message=...
Pour Prometheus, utilisez unbound_exporter.
Etape 11 : DNS over HTTPS (DoH) sortant
Unbound 1.20+ supporte DoH sortant via doq. Pour DoH legacy, utilisez dnscrypt-proxy devant Unbound :
client → unbound (53) → dnscrypt-proxy (5353) → DoH upstream
Etape 12 : Anti-DDoS et rate limiting
server:
ratelimit: 1000 # qps max par IP source
ip-ratelimit: 500
edns-buffer-size: 1232 # eviter amplification UDP
do-not-query-localhost: yes
Depannage
"SERVFAIL" sur tous les domaines
Verifiez les root hints :
sudo unbound-checkconf
sudo unbound -dd
Lancez en debug pour voir l'erreur exacte.
Resolution lente
Cache pas chaud. Verifiez :
sudo unbound-control stats | grep cachehits
Si tres faible, le cache est en cours de remplissage. Sera plus rapide apres quelques min.
DNSSEC echoue partout
Verifiez la trust anchor :
sudo unbound-anchor -a /var/lib/unbound/root.key -v
Logs trop verbeux
server:
verbosity: 0 # 0=silent, 1=normal, 4=detailed
log-queries: no
log-replies: no
log-tag-queryreply: no
Memory consumption eleve
Reduisez les caches :
server:
msg-cache-size: 32m
rrset-cache-size: 64m
Commandes utiles
# Service
sudo systemctl status unbound
sudo systemctl reload unbound
sudo systemctl restart unbound
# Config
sudo unbound-checkconf
# Stats temps reel
sudo unbound-control stats
# Reset stats
sudo unbound-control reset_cache
# Forcer un domaine en cache
sudo unbound-control flush google.com
# Logs
sudo journalctl -u unbound -f
# Debug
sudo unbound -dd
# Test
dig @127.0.0.1 google.com
dig @127.0.0.1 +dnssec cloudflare.com
dig @127.0.0.1 +trace example.com
# Update trust anchor
sudo unbound-anchor
Conclusion
Unbound vous donne :
- Resolution privee, recursive, DNSSEC-validee
- DoT sortant pour le chiffrement
- Blocage de pub/malware
- Performance et scalabilite
Pour aller plus loin :
- Combinez avec dnscrypt-proxy pour DoH
- Utilisez Pi-hole + Unbound (Pi-hole devant, Unbound derriere)
- Pour de la HA, deployez 2-3 Unbound + Keepalived
Ressources
- Documentation officielle : https://unbound.docs.nlnetlabs.nl
- NLnet Labs : https://nlnetlabs.nl
- Best practices : https://nlnetlabs.nl/documentation/unbound/howto-optimise/
- Github : https://github.com/NLnetLabs/unbound


















