Installation et configuration d’un serveur DNS DoH et DoT sous Debian 13

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é

debian dns bind9 dnsdist doh dot

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

  1. Taper about:config dans la barre d’adresse
  2. Chercher network.trr.mode et définisser à 2
  3. 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é)

  1. Paramètres → Réseau et Internet → Avancé → DNS privé
  2. Sélectionner « Nom d’hôte du fournisseur DNS privé »
  3. 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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.