Unbound : resolveur DNS recursif valide

Unbound : resolveur DNS recursif valide

Unbound est un resolveur DNS recursif moderne : validation DNSSEC native, DNS-over-TLS sortant, cache performant, faible empreinte. La meilleure alternative a un forward vers Cloudflare/Quad9 si vous voulez du DNS prive de bout en bout.

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

Rejoignez notre serveur communautaire Discord

Pour toute question, suggestion ou simplement pour discuter avec la communauté, rejoignez-nous sur Discord !

900+Membres