Un mémo pour mettre en place un serveur DNS pour un réseau local uniquement en IPv4 avec support DNS-over-HTTPS (DoH) et DNS-over-TLS (DoT) en utilisant BIND9 comme backend et DNSdist comme proxy sous Debian Trixie avec certificat auto-signé
Installation et configuration de BIND9 et DNSdist
Architecture du système
- BIND9 : Serveur DNS autoritaire sur port 5353 (backend)
- DNSdist : Proxy DNS avec support DoH/DoT sur ports 53/443/853
- Certificat auto-signé : Pour le chiffrement TLS/HTTPS
Prérequis
- Debian 13
- Accès root
- Nom de domaine configuré (exemple : dns.mondomaine.tld)
Mise à jour du système et installation des paquets
# Mise à jour complète du système
apt update && apt full-upgrade -y
# Installation des paquets nécessaires
apt install bind9 bind9utils bind9-doc dnsdist openssl -y
Configuration de BIND9
Configuration des options principales
# Édition du fichier de configuration principal
nano /etc/bind/named.conf.options
Remplacer le contenu par :
options {
directory "/var/cache/bind";
// BIND9 écoute sur localhost:5353 seulement (backend pour DNSdist)
listen-on port 5353 { 127.0.0.1; };
listen-on-v6 { none; };
recursion yes;
allow-query { 127.0.0.1; }; // Seul DNSdist peut interroger BIND
allow-recursion { 127.0.0.1; };
// Serveurs DNS de redirection (adapter selon votre FAI/infrastructure)
forwarders {
9.9.9.9;
1.1.1.1;
};
dnssec-validation auto;
// Sécurité renforcée
version "not available";
hostname "not available";
// Optimisations
minimal-responses yes;
prefetch 2 9;
qname-minimization relaxed;
// Logging des requêtes
querylog yes;
};
Configuration de la zone DNS
# Édition de la configuration locale
nano /etc/bind/named.conf.local
Ajouter le zone (adapter selon votre domaine) :
// Clé pour les mises à jour dynamiques (optionnel)
key "ddns-key" {
algorithm hmac-sha256;
secret "VOTRE_CLE_SECRETE_ICI";
};
// Zone principale
zone "mondomaine.tld" {
type master;
file "/etc/bind/zones/db.mondomaine.tld";
allow-update { key "ddns-key"; };
};
- Pour créer la clé secrete :
tsig-keygen -a hmac-sha256 ddns-key
Création du fichier de zone
# Création du répertoire des zones
mkdir -p /etc/bind/zones
# Création du fichier de zone
nano /etc/bind/zones/db.mondomaine.tld
Contenu du fichier de zone :
$TTL 86400
@ IN SOA ns1.mondomaine.tld. admin.mondomaine.tld. (
2025091701 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ) ; Negative Cache TTL
IN NS ns1.mondomaine.tld.
ns1 IN A IP_SRV_DNS
dns IN CNAME ns1
www IN A VOTRE_IP_WEB
@ IN MX 10 mail.mondomaine.tld.
Génération du certificat SSL auto-signé
# Création du répertoire pour les certificats
mkdir -p /etc/bind/certs
# Génération du certificat auto-signé (valide 10 ans)
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
-keyout /etc/bind/certs/dns.mondomaine.tld.key \
-out /etc/bind/certs/dns.mondomaine.tld.crt \
-subj "/CN=dns.mondomaine.tld"
# Attribution des permissions correctes
chown -R bind:bind /etc/bind/zones
chown -R bind:bind /etc/bind/certs
chown _dnsdist:_dnsdist /etc/bind/certs/dns.mondomaine.tld.*
chmod 640 /etc/bind/certs/dns.mondomaine.tld.key
chmod 644 /etc/bind/certs/dns.mondomaine.tld.crt
Configuration de DNSdist
# Configuration de DNSdist
nano /etc/dnsdist/dnsdist.conf
Contenu de la configuration DNSdist :
setSecurityPollSuffix("")
-- Backend BIND9 sur port 5353
newServer({address="127.0.0.1:5353", name="bind9-local"})
-- DNSdist écoute sur port 53 pour DNS classique
setLocal("0.0.0.0:53", {})
-- DNS over TLS sur port 853 (standard)
addTLSLocal("0.0.0.0:853", "/etc/bind/certs/dns.mondomaine.tld.crt", "/etc/bind/certs/dns.mondomaine.tld.key", {
reusePort=true
})
-- DNS over HTTPS sur port 443 (standard)
addDOHLocal("0.0.0.0:443", "/etc/bind/certs/dns.mondomaine.tld.crt", "/etc/bind/certs/dns.mondomaine.tld.key", "/dns-query", {
reusePort=true,
trustForwardedForHeader=false,
keepIncomingHeaders=true
})
-- Configuration de sécurité
setMaxTCPClientThreads(20)
setMaxTCPQueriesPerConnection(20)
setMaxTCPConnectionDuration(30)
-- Cache pour améliorer les performances
pc = newPacketCache(10000, {
maxTTL=86400,
minTTL=60,
temporaryFailureTTL=60,
staleTTL=60
})
getPool(""):setCache(pc)
-- Protection contre les attaques DDoS
addAction(MaxQPSIPRule(50), DropAction()) -- Max 50 requêtes/sec par IP
addAction(MaxQPSRule(2000), DropAction()) -- Max 2000 requêtes/sec global
-- Logging (optionnel - décommenter si nécessaire)
-- setVerbose(true)
-- addAction(AllRule(), LogAction("/var/log/dnsdist/queries.log"))
print("DNSdist configuration loaded - DoH on port 443, DoT on port 853")
-- Accès console de dnsdist
setKey("clé secrète")
controlSocket("127.0.0.1:5199")
- Pour créer la clé secrète :
openssl rand -base64 32
Configuration du pare-feu
# Si utilisation de UFW
ufw allow 53/tcp
ufw allow 53/udp
ufw allow 443/tcp
ufw allow 853/tcp
ufw reload
# Si utilisation de iptables directement
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 853 -j ACCEPT
# Sauvegarde des règles iptables
iptables-save > /etc/iptables/rules.v4
Démarrage et activation des services
# Vérification des configurations
named-checkconf
named-checkzone mondomaine.tld /etc/bind/zones/db.mondomaine.tld
dnsdist --check-config
# Arrêt des services pour éviter les conflits
systemctl stop dnsdist
systemctl stop bind9
# Redémarrage de BIND9 avec la nouvelle configuration
systemctl start bind9
systemctl enable bind9
systemctl status bind9
# Vérification que BIND9 écoute sur le port 5353
ss -tlnp | grep :5353
# Démarrage de DNSdist
systemctl start dnsdist
systemctl enable dnsdist
systemctl status dnsdist
# Vérification des ports en écoute
ss -tlnp | grep -E ":(53|443|853|5353)"
Tests et validation
Test DNS classique
# Test depuis le serveur local
dig @127.0.0.1 ns1.mondomaine.tld
dig @localhost ns1.mondomaine.tld
# Test depuis un client externe
dig @IP_SRV_DNS ns1.mondomaine.tld
Test DNS-over-HTTPS
# Test avec dig (si supporté)
dig @IP_SRV_DNS +https=/dns-query ns1.mondomaine.tld
# Test avec curl
curl -k "https://IP_SRV_DNS/dns-query?name=ns1.mondomaine.tld&type=A"
Test DNS-over-TLS
# Test avec dig (si supporté)
dig @IP_SRV_DNS +tls ns1.mondomaine.tld
# Test de la connexion TLS
openssl s_client -connect IP_SRV_DNS:853 -servername dns.mondomaine.tld
Surveillance et logs
Consultation des logs
# Logs DNSdist en temps réel
journalctl -u dnsdist -f
# Logs BIND9 en temps réel
journalctl -u bind9 -f
# Logs des erreurs uniquement
journalctl -u dnsdist -u bind9 | grep -i error
Statistiques DNSdist
# Affichage des statistiques
echo "showServers();" | dnsdist -c -k "clé_secrète"
Configuration des clients
Firefox
- Taper
about:config
dans la barre d’adresse - Chercher
network.trr.mode
et définisser à2
- Chercher
network.trr.uri
et définisser àhttps://dns.mondomaine.tld/dns-query
Chrome
# Lancement avec DoH
google-chrome --dns-over-https-server=https://dns.mondomaine.tld/dns-query
Android (DNS privé)
- Paramètres → Réseau et Internet → Avancé → DNS privé
- Sélectionner « Nom d’hôte du fournisseur DNS privé »
- Entrer :
dns.mondomaine.tld
Sécurisation avancée (optionnel)
Restriction des ACL
Dans /etc/dnsdist/dnsdist.conf
, ajouter :
-- Limiter l'accès à certains réseaux seulement
setACL({"127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"})
Monitoring automatique
# Script de surveillance
nano /usr/local/bin/dns-health-check.sh
#!/bin/bash
# Test des services DNS
dig @127.0.0.1 ns1.mondomaine.tld > /dev/null 2>&1
if [ $? -ne 0 ]; then
systemctl restart dnsdist
echo "$(date): DNSdist redémarré" >> /var/log/dns-health.log
fi
# Rendre exécutable et ajouter au cron
chmod +x /usr/local/bin/dns-health-check.sh
echo "*/5 * * * * /usr/local/bin/dns-health-check.sh" | crontab -
Conclusion
Le serveur DNS est maintenant opérationnel avec :
- DNS classique via DNSdist
- DNS-over-HTTPS sécurisé sur le port 443
- DNS-over-TLS chiffré sur le port 853
- Cache pour de meilleures performances
- Protection anti-DDoS intégrée
Les clients peuvent utiliser le serveur DNS via :
- DNS classique :
VOTRE_IP:53
- DoH :
https://dns.mondomaine.tld/dns-query
- DoT :
dns.mondomaine.tld:853