Chaque fois que vous tapez une adresse dans votre navigateur, votre appareil envoie une requête DNS en clair, lisible par votre fournisseur d’accès à Internet, par les administrateurs réseau, et par quiconque intercepte votre trafic sur le chemin. Le protocole DNS traditionnel fonctionne sur le port 53, sans chiffrement, depuis 1983. DNS over HTTPS (DoH) résout ce problème en encapsulant les requêtes DNS dans du trafic HTTPS chiffré sur le port 443, les rendant indiscernables du reste de votre navigation web.

Ce tutoriel vous guide à travers 12 étapes concrètes pour activer et configurer DNS over HTTPS sur tous vos appareils (navigateurs, Windows, macOS, Linux) et vous montre comment implémenter un client DoH en Node.js 18+. Temps estimé : 30 minutes pour la configuration complète.

Qu’est-ce que DNS over HTTPS et pourquoi c’est important

Le système DNS (Domain Name System) traduit les noms de domaine comme shattered.io en adresses IP comme 104.21.17.6. Sans chiffrement, cette traduction se fait en clair sur le port UDP/TCP 53. Concrètement, votre FAI voit chaque site que vous visitez, même si la connexion au site lui-même est chiffrée en HTTPS. C’est une fuite de confidentialité structurelle, exploitée massivement pour la publicité ciblée, le blocage de sites, et la surveillance.

La RFC 8484, publiée par l’IETF en octobre 2018, standardise DNS over HTTPS. Le principe : les requêtes DNS sont encodées selon le format DNS wire format ou JSON, puis transmises via une requête HTTPS vers un résolveur compatible DoH. Pour un observateur externe, ces requêtes ressemblent exactement à du trafic HTTPS normal. Le protocole concurrent, DNS over TLS (DoT, RFC 7858), offre un chiffrement similaire mais utilise le port 853, plus facilement identifiable et bloquable.

En 2026, la part de marché de DoH dépasse 40% des requêtes DNS mondiales selon les données de Cloudflare. Firefox l’active par défaut en France depuis la version 91 pour les utilisateurs qui n’ont pas configuré leur propre résolveur DNS. Chrome 83 a introduit le “Secure DNS” avec bascule automatique vers DoH si le résolveur configuré supporte le protocole. La question n’est donc plus de savoir si DoH est pertinent, mais comment le configurer correctement pour maximiser la confidentialité sans casser sa connectivité.

Avantages et limites de DNS over HTTPS

DoH apporte 4 bénéfices mesurables. Premièrement, la confidentialité vis-à-vis du FAI : votre opérateur ne peut plus enregistrer les domaines que vous consultez. Deuxièmement, la résistance à la manipulation DNS : les attaques de type DNS hijacking, qui redirigent silencieusement votre trafic vers des serveurs malveillants, deviennent impossibles à réaliser sur le trajet entre votre appareil et le résolveur DoH. Troisièmement, la protection contre la censure DNS : les blocages au niveau DNS imposés par les FAI (comme les blocages de sites de streaming ou de jeux en ligne en France) sont contournés. Quatrièmement, DoH est résistant aux attaques de type MITM sur les requêtes DNS, contrairement au DNS classique.

Les limites sont réelles et méritent d’être comprises. DoH ne chiffre pas votre trafic IP, il chiffre uniquement la résolution de nom. Votre IP source reste visible. Les informations SNI (Server Name Indication) dans les handshakes TLS révèlent encore le domaine cible à un observateur réseau, bien que eSNI/ECH (Encrypted Client Hello) commence à combler cette lacune. Par ailleurs, DoH déplace la confiance de votre FAI vers votre fournisseur DoH (Cloudflare, Google, NextDNS). Ce n’est pas une anonymisation mais un changement d’interlocuteur. Enfin, DoH peut interférer avec des configurations réseau d’entreprise, les portails captifs Wi-Fi, et les résolveurs DNS internes des réseaux privés.

Comparaison des fournisseurs DNS over HTTPS

Le choix du fournisseur DoH est la décision la plus importante de cette configuration. Les critères clés sont la politique de logs, la vitesse de résolution, le filtrage de contenu malveillant, et la localisation des serveurs.

FournisseurURL DoHIP primaireLatence (France)LogsFiltrage malware
Cloudflare 1.1.1.1https://cloudflare-dns.com/dns-query1.1.1.1~3 msAucun (audité KPMG)Non (standard)
Cloudflare 1.1.1.2https://security.cloudflare-dns.com/dns-query1.1.1.2~3 msAucun (audité KPMG)Oui (malware)
Google Public DNShttps://dns.google/dns-query8.8.8.8~8 ms25 h (anonymisés)Non
Quad9https://dns.quad9.net/dns-query9.9.9.9~12 msAucunOui (malware + phishing)
AdGuard DNShttps://dns.adguard.com/dns-query94.140.14.14~15 msAucunOui (malware + publicités)
NextDNShttps://dns.nextdns.io/{profil}Variable~5 msOptionnelPersonnalisable

Pour la France, Cloudflare 1.1.1.1 offre la latence la plus faible (3 ms en moyenne) et publie un audit annuel de sa politique de non-conservation des logs, réalisé par KPMG. Quad9, basé en Suisse sous le droit helvétique, est le choix privilégié pour ceux qui veulent éviter les serveurs américains tout en bénéficiant d’un filtrage de malware actif. NextDNS, avec sa console de configuration détaillée, s’adresse aux administrateurs qui veulent contrôler finement le filtrage.

Prérequis

Pour suivre ce tutoriel dans son intégralité, vous avez besoin de :

  • Navigateur : Firefox 122+, Chrome 120+, Edge 120+, Brave 1.62+ ou Safari 17+ (macOS)
  • Système d’exploitation : Windows 11 22H2+, macOS Ventura 13+, ou Ubuntu 22.04 LTS / Debian 12+
  • Node.js 18.x ou 20.x LTS (pour la section implémentation DoH)
  • curl 7.76+ (pour les tests en ligne de commande)
  • Droits administrateur sur le système pour les configurations au niveau OS
  • Accès Internet sur le port 443 (HTTPS) sans inspection TLS profonde de l’entreprise

Étape 1 : Activer DNS over HTTPS dans Firefox

Firefox est le navigateur le plus avancé dans l’implémentation de DoH. Il propose trois modes : désactivé, activé avec repli (utilise DoH si disponible, sinon DNS classique), et activé sans repli (bloque la résolution si DoH échoue). Pour la confidentialité maximale, utilisez le mode sans repli, mais sachez qu’il peut bloquer l’accès sur les réseaux avec portails captifs.

Ouvrez Firefox et accédez à about:preferences#privacy. Faites défiler jusqu’à la section “Sécurité DNS”. Cochez “Activer le DNS sécurisé” et sélectionnez le niveau de protection souhaité. Dans la liste déroulante “Utiliser le fournisseur”, choisissez l’un des fournisseurs préconfigurés ou sélectionnez “Personnalisé” pour entrer l’URL de votre fournisseur préféré. Pour Cloudflare : entrez https://cloudflare-dns.com/dns-query. Pour Quad9 : https://dns.quad9.net/dns-query.

Pour les utilisateurs qui préfèrent la configuration via l’interface about:config, trois préférences contrôlent le comportement DoH :

// about:config dans Firefox
// Activer DoH en mode strict (sans repli DNS classique)
// network.trr.mode valeurs : 0=désactivé, 2=avec repli, 3=strict, 5=désactivé entreprise
network.trr.mode = 3

// Définir l'URL du résolveur DoH
network.trr.uri = "https://cloudflare-dns.com/dns-query"

// Forcer la résolution de l'URI DoH via l'IP directe (évite le problème bootstrap)
// Le problème bootstrap : comment résoudre le nom du résolveur DoH sans DNS classique ?
network.trr.bootstrapAddress = "1.1.1.1"

Le mode 3 est recommandé pour la confidentialité maximale. Firefox affiche une icône de bouclier dans la barre d’adresse quand DoH est actif pour la page courante. Vérifiez que l’icône est présente après avoir sauvegardé les paramètres.

Étape 2 : Configurer DoH dans Chrome et Chromium

Google Chrome implémente DoH sous le nom “Secure DNS”. Par défaut, Chrome bascule automatiquement vers DoH si le résolveur DNS actuellement configuré (via DHCP ou OS) supporte le protocole. Cette approche dite “upgrade” est plus conservatrice que Firefox mais plus transparente pour l’utilisateur final.

Pour configurer Chrome, naviguez vers chrome://settings/security. Dans la section “Utilisation d’un DNS sécurisé”, cochez “Avec” et sélectionnez un fournisseur dans la liste, ou entrez une URL personnalisée. Pour une configuration via les politiques d’entreprise (déploiement sur plusieurs postes), Chrome accepte les paramètres via les GPO Windows ou via un fichier de politique JSON sur macOS/Linux :

# Configuration Chrome via politique JSON (Linux/macOS)
# Fichier : /etc/chromium/policies/managed/dns_over_https.json
{
  "DnsOverHttpsMode": "secure",
  "DnsOverHttpsTemplates": "https://cloudflare-dns.com/dns-query"
}

# Sur Windows, via PowerShell (crée la clé de registre GPO)
# HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" `
  -Name "DnsOverHttpsMode" -Value "secure" -Type String
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Google\Chrome" `
  -Name "DnsOverHttpsTemplates" -Value "https://cloudflare-dns.com/dns-query" -Type String

La valeur “secure” pour DnsOverHttpsMode impose DoH strict. La valeur “automatic” permet le repli vers DNS classique. Cette configuration s’applique identiquement à Chromium, Brave (avec les politiques Chromium), et Edge en mode géré.

Étape 3 : Activer DoH dans Edge et Brave

Microsoft Edge expose le paramètre DoH via edge://settings/privacy, dans la section “Sécurité”. Edge ajoute une option pour utiliser le résolveur DoH de Microsoft en dehors de l’Union Européenne, et https://dns.quad9.net/dns-query pour les utilisateurs en Europe, conformément aux exigences de localisation des données RGPD.

Brave implémente DoH nativement et propose son propre résolveur via son partenariat avec Quad9. La configuration s’effectue dans brave://settings/security, section “Utiliser un DNS sécurisé”. Brave a la particularité de désactiver automatiquement DoH quand Tor est actif dans les onglets Brave Private Windows, pour éviter les fuites de résolution DNS qui trahiraient l’identité de l’utilisateur. C’est un comportement par défaut qui protège les utilisateurs avancés d’une erreur courante.

Étape 4 : Configurer DoH au niveau système sous Windows 11

La configuration DoH au niveau navigateur ne chiffre les requêtes DNS que pour ce navigateur spécifique. Les applications système, les jeux, les clients email, et tous les autres logiciels continuent d’utiliser le DNS classique. Pour une protection complète, il faut configurer DoH au niveau du système d’exploitation.

Windows 11 22H2 intègre DoH nativement dans le stack réseau. Pour l’activer : ouvrez Paramètres, allez dans Réseau et Internet, puis sélectionnez votre connexion réseau (WiFi ou Ethernet). Cliquez sur “Modifier l’attribution du serveur DNS”. Passez de “Automatique (DHCP)” à “Manuel”. Activez IPv4, entrez 1.1.1.1 comme DNS préféré, et dans la liste déroulante “Chiffrement DNS”, sélectionnez “Chiffré uniquement (DNS sur HTTPS)”.

Pour les utilisateurs avancés et le déploiement automatisé, la même configuration via PowerShell (administrateur) :

# PowerShell (administrateur) - Configurer DoH sur Windows 11
# Étape 1 : Lister les interfaces réseau disponibles
Get-DnsClientServerAddress

# Étape 2 : Configurer les serveurs DNS (adapter "Wi-Fi" selon votre interface)
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ServerAddresses "1.1.1.1","1.0.0.1"

# Étape 3 : Enregistrer les templates DoH pour chaque serveur
Add-DnsClientDohServerAddress -ServerAddress "1.1.1.1" `
    -DohTemplate "https://cloudflare-dns.com/dns-query" `
    -AllowFallbackToUdp $false `
    -AutoUpgrade $true

Add-DnsClientDohServerAddress -ServerAddress "1.0.0.1" `
    -DohTemplate "https://cloudflare-dns.com/dns-query" `
    -AllowFallbackToUdp $false `
    -AutoUpgrade $true

# Étape 4 : Vérifier la configuration
Get-DnsClientDohServerAddress

# Sortie attendue :
# ServerAddress DohTemplate                              AllowFallbackToUdp AutoUpgrade
# ------------- -----------                              ------------------ -----------
# 1.1.1.1       https://cloudflare-dns.com/dns-query    False              True
# 1.0.0.1       https://cloudflare-dns.com/dns-query    False              True

Le paramètre AllowFallbackToUdp $false impose DoH strict. AutoUpgrade $true active la mise à niveau automatique depuis DNS classique vers DoH pour les serveurs qui supportent les deux protocoles.

Étape 5 : Activer DoH sous macOS avec cloudflared

macOS Ventura (13) et Sonoma (14) supportent DoH via des profils de configuration réseau (format .mobileconfig), installables via l’application Configuration Apple ou MDM. Pour les utilisateurs avancés, l’approche la plus flexible est d’utiliser cloudflared, le daemon officiel de Cloudflare, comme proxy DoH local.

# Installation de cloudflared sur macOS via Homebrew
brew install cloudflared

# Démarrer cloudflared comme proxy DoH local sur le port 5053
# (Port 53 nécessite les droits root, 5053 fonctionne sans sudo)
cloudflared proxy-dns --port 5053 --upstream "https://cloudflare-dns.com/dns-query"

# Pour l'activer en service système (démarre automatiquement au boot)
sudo cloudflared service install --legacy

# Vérifier que cloudflared écoute
sudo lsof -i :5053

# Tester la résolution DNS via le proxy local
dig @127.0.0.1 -p 5053 cloudflare.com A

Une fois cloudflared en cours d’exécution sur 127.0.0.1:5053, configurez macOS pour utiliser 127.0.0.1 comme serveur DNS : Préférences Système, Réseau, sélectionnez votre interface, puis dans “Avancé” et “DNS”, ajoutez 127.0.0.1 en premier serveur DNS et supprimez les autres. Toutes les applications du système enverront leurs requêtes DNS vers cloudflared, qui les transmettra chiffrées via DoH vers Cloudflare.

Étape 6 : Configurer DoH sous Linux avec dnscrypt-proxy

Sur Linux, dnscrypt-proxy est l’outil de référence pour activer DoH au niveau système. Il supporte aussi bien DoH que DNSCrypt, gère la rotation entre plusieurs fournisseurs, et propose un filtrage de contenu via des listes de blocage. Contrairement à systemd-resolved qui supporte DNS over TLS (DoT) via DNSOverTLS=yes mais pas DoH nativement dans la plupart des distributions en 2026, dnscrypt-proxy gère les deux protocoles.

# Installation de dnscrypt-proxy sur Ubuntu 22.04 / Debian 12
sudo apt update && sudo apt install -y dnscrypt-proxy

# Vérifier les conflits : systemd-resolved peut écouter sur le port 53
sudo ss -tulnp | grep ':53'

# Si systemd-resolved occupe le port 53, désactiver son stub resolver
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved

# Vérifier que le port 53 est libre
sudo ss -tulnp | grep ':53'

# Créer le répertoire de cache pour dnscrypt-proxy
sudo mkdir -p /var/cache/dnscrypt-proxy

# Démarrer et activer le service
sudo systemctl enable --now dnscrypt-proxy
sudo systemctl status dnscrypt-proxy

Modifiez ensuite le fichier de configuration principal pour activer DoH avec les fournisseurs souhaités. Le fichier se trouve dans /etc/dnscrypt-proxy/dnscrypt-proxy.toml :

# /etc/dnscrypt-proxy/dnscrypt-proxy.toml (extraits clés à modifier)

# Écouter sur localhost, port 53
listen_addresses = ['127.0.0.1:53', '[::1]:53']

# Utiliser des serveurs spécifiques (DoH uniquement)
server_names = ['cloudflare', 'quad9-dnscrypt-ip4-filter-pri']

# Exiger l'absence de logs côté serveur
require_nolog = true

# Activer DNSSEC
require_dnssec = true

# Activer uniquement les serveurs DoH (et pas DNSCrypt)
# Mettre à true pour DoH uniquement
doh_servers = true
dnscrypt_servers = false

# Sources de liste de serveurs
[sources]
  [sources.'public-resolvers']
  urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md']
  cache_file = '/var/cache/dnscrypt-proxy/public-resolvers.md'
  minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
  refresh_delay = 72

# Configurer /etc/resolv.conf pour pointer vers dnscrypt-proxy
# echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

Étape 7 : Vérifier que DoH fonctionne correctement

La vérification est une étape critique. Beaucoup d’utilisateurs pensent avoir activé DoH alors que le navigateur ou l’OS utilise encore le DNS classique comme repli. Plusieurs méthodes permettent de confirmer que les requêtes DNS passent bien par DoH.

Test 1 : vérification via la page de diagnostic Cloudflare. Naviguez vers https://1.1.1.1/help. La page affiche si votre connexion utilise DoH (DNS over HTTPS: Yes) et si DNSSEC est activé. Cloudflare affiche aussi l’adresse IP du résolveur qui a traité votre requête, permettant de confirmer que c’est bien leurs serveurs et non ceux de votre FAI.

Test 2 : requête DoH directe via curl pour tester l’API JSON de Cloudflare :

# Tester l'API DoH de Cloudflare directement (format JSON)
curl -s -H "Accept: application/dns-json" \
  "https://cloudflare-dns.com/dns-query?name=example.com&type=A" | python3 -m json.tool

# Sortie attendue :
# {
#   "Status": 0,          <-- 0 = NOERROR (succès)
#   "TC": false,
#   "RD": true,
#   "RA": true,
#   "AD": true,           <-- Authentic Data = DNSSEC validé
#   "CD": false,
#   "Question": [{"name": "example.com.", "type": 1}],
#   "Answer": [
#     {
#       "name": "example.com.",
#       "type": 1,        <-- Type A (IPv4)
#       "TTL": 86400,
#       "data": "93.184.216.34"
#     }
#   ]
# }

# Tester avec Quad9 pour comparaison
curl -s -H "Accept: application/dns-json" \
  "https://dns.quad9.net/dns-query?name=shattered.io&type=A" | python3 -m json.tool

# Vérifier l'absence de trafic DNS classique (port 53) pendant la navigation
# Lancez cette commande, naviguez 30 secondes, puis arrêtez avec Ctrl+C
# Aucune ligne = toutes les requêtes passent par DoH
sudo tcpdump -i any -n 'port 53 and not host 127.0.0.1' 2>/dev/null

Le champ "Status": 0 indique une résolution réussie (NOERROR). "AD": true confirme que DNSSEC a validé la réponse. Si la commande tcpdump ne produit aucune sortie pendant la navigation, toutes les requêtes passent bien par DoH sur le port 443 et non en clair sur le port 53.

Étape 8 : Implémenter un client DNS over HTTPS en Node.js

Node.js 18 et supérieur intègre l’API fetch nativement, ce qui simplifie l’implémentation d’un client DoH sans dépendances externes. L’API JSON de Cloudflare (format application/dns-json) est plus accessible que le format binaire DNS wire (format application/dns-message) défini dans la RFC 8484. Voici un client DoH complet qui interroge plusieurs types de records DNS :

// doh-client.js - Client DNS over HTTPS pour Node.js 18+
// Usage : node doh-client.js

const DOH_PROVIDERS = {
  cloudflare: 'https://cloudflare-dns.com/dns-query',
  google:     'https://dns.google/dns-query',
  quad9:      'https://dns.quad9.net/dns-query',
};

/**
 * Résout un nom de domaine via DNS over HTTPS
 * @param {string} hostname - Nom de domaine à résoudre
 * @param {string} type - Type de record ('A', 'AAAA', 'MX', 'TXT', 'CNAME', 'NS')
 * @param {string} provider - Fournisseur ('cloudflare', 'google', 'quad9')
 * @returns {Promise<Array>} Tableau de records DNS
 */
async function resolveDoH(hostname, type = 'A', provider = 'cloudflare') {
  const baseUrl = DOH_PROVIDERS[provider];
  if (!baseUrl) throw new Error(`Fournisseur DoH inconnu : ${provider}`);

  const url = new URL(baseUrl);
  url.searchParams.set('name', hostname);
  url.searchParams.set('type', type);

  const response = await fetch(url.toString(), {
    headers: { 'Accept': 'application/dns-json' },
    signal: AbortSignal.timeout(5000), // Timeout 5 secondes
  });

  if (!response.ok) {
    throw new Error(`Erreur HTTP DoH ${response.status} : ${response.statusText}`);
  }

  const data = await response.json();

  // Codes d'erreur DNS : 0=NOERROR, 1=FORMERR, 2=SERVFAIL, 3=NXDOMAIN, 5=REFUSED
  if (data.Status !== 0) {
    const errors = { 1: 'FORMERR', 2: 'SERVFAIL', 3: 'NXDOMAIN', 5: 'REFUSED' };
    throw new Error(`Erreur DNS ${data.Status} : ${errors[data.Status] || 'UNKNOWN'}`);
  }

  return { records: data.Answer || [], dnssecValid: data.AD === true };
}

async function main() {
  try {
    // Records A via Cloudflare
    const { records: aRecords, dnssecValid } = await resolveDoH('cloudflare.com', 'A');
    console.log('Records A de cloudflare.com (via Cloudflare DoH) :');
    aRecords.forEach(r => console.log(`  ${r.data} (TTL: ${r.TTL}s)`));
    console.log(`DNSSEC validé : ${dnssecValid ? 'OUI' : 'NON'}`);

    // Records MX via Quad9
    const { records: mxRecords } = await resolveDoH('google.com', 'MX', 'quad9');
    console.log('\nRecords MX de google.com (via Quad9 DoH) :');
    mxRecords.forEach(r => console.log(`  ${r.data} (TTL: ${r.TTL}s)`));

    // Test NXDOMAIN (domaine inexistant)
    try {
      await resolveDoH('ce-domaine-nexiste-pas-12345.fr', 'A');
    } catch (err) {
      console.log(`\nTest NXDOMAIN : ${err.message}`); // Attendu : Erreur DNS 3 : NXDOMAIN
    }
  } catch (error) {
    console.error('Erreur :', error.message);
    process.exit(1);
  }
}

main();

Exécutez avec node doh-client.js. La sortie attendue :

Records A de cloudflare.com (via Cloudflare DoH) :
  104.16.132.229 (TTL: 300s)
  104.16.133.229 (TTL: 300s)
DNSSEC validé : OUI

Records MX de google.com (via Quad9 DoH) :
  10 smtp.google.com. (TTL: 3600s)

Test NXDOMAIN : Erreur DNS 3 : NXDOMAIN

Mesure de performance : DoH vs DNS classique en Node.js

Un benchmark simple compare la latence de résolution DoH versus DNS classique. La première résolution DoH est plus lente (handshake TLS inclus). Les résolutions suivantes bénéficient de la réutilisation de connexion HTTP/2 et du cache DNS côté résolveur :

// benchmark-doh.js - Comparer DoH vs DNS classique en Node.js 18+
const dns = require('dns').promises;

async function benchmark(hostname, iterations = 5) {
  // DNS classique via le résolveur système
  const classicTimes = [];
  for (let i = 0; i < iterations; i++) {
    const start = performance.now();
    await dns.resolve4(hostname);
    classicTimes.push(performance.now() - start);
  }

  // DNS over HTTPS via Cloudflare
  const dohTimes = [];
  const url = `https://cloudflare-dns.com/dns-query?name=${hostname}&type=A`;
  for (let i = 0; i < iterations; i++) {
    const start = performance.now();
    await fetch(url, { headers: { Accept: 'application/dns-json' } });
    dohTimes.push(performance.now() - start);
  }

  const avg = arr => (arr.reduce((a, b) => a + b, 0) / arr.length).toFixed(1);
  console.log(`Benchmark pour "${hostname}" (${iterations} itérations) :`);
  console.log(`  DNS classique : ${avg(classicTimes)} ms (moyenne)`);
  console.log(`  DoH 1re requête : ${dohTimes[0].toFixed(1)} ms (TLS inclus)`);
  console.log(`  DoH dernière requête : ${dohTimes[iterations-1].toFixed(1)} ms (connexion réutilisée)`);
  console.log(`  DoH moyenne : ${avg(dohTimes)} ms`);
}

benchmark('google.com');

Étape 9 : Configuration avancée avec NextDNS

NextDNS se distingue des autres fournisseurs DoH par son niveau de personnalisation. Chaque compte crée un profil avec un identifiant unique (ex : abc123), ce qui génère un endpoint DoH personnalisé : https://dns.nextdns.io/abc123. Via la console NextDNS, configurez des listes de blocage (EasyList, oisd, AdGuard DNS Filter), des règles de réécriture DNS, des blocages parentaux par catégorie, et visualisez les requêtes DNS en temps réel.

Pour les entreprises, NextDNS propose une journalisation conforme au RGPD avec stockage optionnel en Europe (Allemagne) ou pas de stockage du tout. Le plan gratuit couvre 300 000 requêtes par mois, ce qui suffit pour un foyer de 4 personnes sur tous les appareils. Les plans payants démarrent à 1,99 €/mois sans limite.

L’API NextDNS permet de gérer la configuration et d’extraire des statistiques pour intégration dans des tableaux de bord :

# API NextDNS - exemples de gestion (remplacer PROFILE_ID et API_KEY)
PROFILE_ID="votre_profil_id"
API_KEY="votre_cle_api_nextdns"

# Statistiques des dernières 24 heures
curl -s "https://api.nextdns.io/profiles/${PROFILE_ID}/analytics/status?from=-24h" \
  -H "X-Api-Key: ${API_KEY}" | python3 -m json.tool

# Ajouter un domaine à la liste blanche (éviter blocages légitimes)
curl -s -X POST "https://api.nextdns.io/profiles/${PROFILE_ID}/allowlist" \
  -H "X-Api-Key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"id": "example.com", "active": true}'

# Tester la connectivité DoH avec votre profil NextDNS personnalisé
curl -s -H "Accept: application/dns-json" \
  "https://dns.nextdns.io/${PROFILE_ID}?name=cloudflare.com&type=A"

Étape 10 : DoH sur un routeur avec pfSense et OPNsense

Configurer DoH directement sur le routeur présente un avantage majeur : tous les appareils du réseau (smartphones, téléviseurs connectés, consoles de jeu) bénéficient du chiffrement DNS sans configuration individuelle. pfSense et OPNsense supportent DoH via leurs packages Unbound.

Sur OPNsense, la configuration DoT (DNS over TLS, protocole similaire à DoH) s’effectue dans Services, Unbound DNS, DNS over TLS. Ajoutez les serveurs Cloudflare (1.1.1.1, hostname TLS : cloudflare-dns.com) et 1.0.0.1. Pour du DoH natif, OPNsense propose le plugin os-unbound-plus ou l’installation de cloudflared comme package système. Avec OPNsense 24.7+, l’interface graphique propose une option “Queries over HTTPS” directement dans la configuration DNS Resolver.

Sur pfSense Plus 24.11, allez dans Services, DNS Resolver. Dans la section “Custom Options”, ajoutez la directive Unbound pour utiliser un serveur DoH upstream en combinant Unbound avec cloudflared installé via le gestionnaire de paquets FreeBSD. Pi-hole peut également être combiné avec DoH en configurant cloudflared comme upstream DNS vers le port 5053 local, puis en pointant Pi-hole vers 127.0.0.1:5053.

Étape 11 : Combiner DoH avec DNSSEC

DoH chiffre le transport des requêtes DNS, mais ne garantit pas l’intégrité des réponses. DNSSEC (DNS Security Extensions, RFC 4033) ajoute des signatures cryptographiques sur les zones DNS, permettant de vérifier que la réponse n’a pas été altérée. DoH + DNSSEC forme une protection complète : chiffrement du transport ET intégrité des données.

Vérifier le support DNSSEC d’un domaine via l’API DoH :

# Vérifier DNSSEC via l'API DoH (champ "AD" = Authentic Data = DNSSEC validé)
curl -s -H "Accept: application/dns-json" \
  "https://cloudflare-dns.com/dns-query?name=cloudflare.com&type=A" | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('DNSSEC validé :', 'OUI' if d.get('AD') else 'NON')"

# Sortie : DNSSEC validé : OUI

# Vérifier avec un domaine sans DNSSEC
curl -s -H "Accept: application/dns-json" \
  "https://cloudflare-dns.com/dns-query?name=example.com&type=A" | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('DNSSEC validé :', 'OUI' if d.get('AD') else 'NON')"

# Sortie : DNSSEC validé : NON  (example.com n'utilise pas DNSSEC)

# Vérifier via dig si disponible
dig +dnssec cloudflare.com @1.1.1.1 | grep -E "flags:|RRSIG"
# Chercher "ad" dans les flags = DNSSEC validé par le résolveur

Tous les grands fournisseurs DoH (Cloudflare, Quad9, NextDNS) valident DNSSEC par défaut. Si un domaine retourne "AD": true, la chaîne de confiance DNSSEC depuis la zone racine jusqu’au domaine est validée. Quad9 bloque par défaut les domaines dont la validation DNSSEC échoue, offrant une protection supplémentaire contre les attaques de type DNS spoofing.

Étape 12 : Surveillance des requêtes DNS et détection d’anomalies

Même avec DoH actif, maintenir une visibilité sur les requêtes DNS du réseau est utile pour détecter des comportements anormaux (malware DGA, exfiltration de données via DNS tunnel). Trois approches complémentaires permettent de surveiller les requêtes tout en maintenant le chiffrement DoH.

Approche 1 : utiliser la console de logs NextDNS ou AdGuard DNS avec journalisation activée. Ces fournisseurs stockent les requêtes dans leur interface web pour une durée configurable (de 1 heure à 2 ans). Approche 2 : déployer dnscrypt-proxy avec journalisation locale activée dans dnscrypt-proxy.toml. Approche 3 : un script Node.js pour analyser les logs DNS et détecter les patterns suspects comme les domaines générés algorithmiquement (DGA) :

// dns-anomaly-detector.js - Détection d'anomalies DNS en Node.js 18+
// Analyse les domaines NXDOMAIN pour détecter les malwares DGA

const fs = require('fs');
const readline = require('readline');

const LOG_FILE = '/var/log/dnscrypt-proxy/nx.log'; // Adapter selon votre config

// Patterns suspects : DGA (Domain Generation Algorithm) utilisé par les malwares
// Les malwares génèrent des centaines de domaines aléatoires pour trouver leur C2
const SUSPICIOUS_PATTERNS = [
  /^[a-z0-9]{15,}\.(com|net|org)$/i, // Domaines très longs et aléatoires
  /\.(tk|ml|ga|cf|gq)$/i,             // TLDs gratuits souvent abusés
  /^[a-z]{3,5}[0-9]{4,8}\./i,         // Combinaison lettres-chiffres suspecte
];

async function detectAnomalies() {
  if (!fs.existsSync(LOG_FILE)) {
    console.log(`Fichier log introuvable : ${LOG_FILE}`);
    console.log('Activez query_log dans dnscrypt-proxy.toml');
    return;
  }

  const fileStream = fs.createReadStream(LOG_FILE);
  const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity });

  let total = 0;
  const suspicious = [];
  const domainFrequency = new Map();

  for await (const line of rl) {
    const parts = line.split('\t');
    if (parts.length < 3) continue;
    const [timestamp, domain] = parts;
    total++;

    // Compter les requêtes par domaine de base
    const baseDomain = domain.split('.').slice(-2).join('.');
    domainFrequency.set(baseDomain, (domainFrequency.get(baseDomain) || 0) + 1);

    const isSuspicious = SUSPICIOUS_PATTERNS.some(p => p.test(domain));
    if (isSuspicious) suspicious.push({ timestamp, domain });
  }

  console.log(`Total requêtes NXDOMAIN analysées : ${total}`);

  // Alerter si plus de 20 sous-domaines NXDOMAIN pour un même domaine de base
  // (indicateur fort de malware DGA ou d'exfiltration DNS)
  const highFrequency = [...domainFrequency.entries()]
    .filter(([, count]) => count > 20)
    .sort(([, a], [, b]) => b - a);

  if (highFrequency.length > 0) {
    console.warn('\nALERTE - Domaines avec plus de 20 NXDOMAIN (possible DGA) :');
    highFrequency.forEach(([d, c]) => console.warn(`  ${d}: ${c} requêtes`));
  }

  if (suspicious.length > 0) {
    console.warn(`\nALERTE - ${suspicious.length} domaine(s) au pattern suspect :`);
    suspicious.slice(0, 10).forEach(d => console.warn(`  ${d.timestamp} - ${d.domain}`));
  }

  if (highFrequency.length === 0 && suspicious.length === 0) {
    console.log('Aucune anomalie DNS détectée.');
  }
}

detectAnomalies().catch(console.error);

Les 8 pièges courants avec DNS over HTTPS

Piège 1 : Mode de repli DNS actif sans le savoir. Par défaut, Chrome et Firefox activent DoH en mode “automatique avec repli” : si le résolveur DoH est inaccessible, le navigateur bascule silencieusement vers le DNS classique du système. Cette fuite passe inaperçue. Passez en mode strict (Firefox network.trr.mode = 3, Chrome DnsOverHttpsMode = "secure") et acceptez que certains réseaux soient momentanément inaccessibles.

Piège 2 : Portails captifs Wi-Fi cassés. Les portails captifs (hôtels, aéroports, campus) interceptent les requêtes DNS pour rediriger vers leur page d’authentification. Avec DoH strict actif, le portail ne peut plus intercepter vos requêtes, et vous semblez n’avoir pas accès à Internet, alors que la connexion fonctionne. Solution : désactiver temporairement DoH sur les réseaux Wi-Fi publics ou passer en mode avec repli sur ces réseaux.

Piège 3 : Split-horizon DNS d’entreprise cassé. Les réseaux d’entreprise utilisent souvent un DNS interne qui résout des noms privés (ex : intranet.entreprise.com, serveur.local) vers des IPs internes. DoH interroge le résolveur externe (Cloudflare, Quad9) qui ne connaît pas ces zones privées : toutes les résolutions internes échouent. Solution : configurer une liste de domaines exclus de DoH dans Firefox via network.trr.excluded-domains, ou maintenir un DNS interne avec DoT/DoH.

Piège 4 : Confusion entre DoH et DoT. DNS over TLS (DoT) chiffre les requêtes DNS sur le port 853 via une session TLS dédiée. DNS over HTTPS (DoH) les encapsule dans HTTP/2 sur le port 443. systemd-resolved sous Linux active DoT avec DNSOverTLS=yes mais ne supporte pas DoH nativement sur Ubuntu 22.04 et Debian 12. Si vous configurez DNSOverTLS=yes en pensant activer DoH, vous activez DoT. Les deux chiffrent le DNS, mais seul DoH sur le port 443 est indiscernable du trafic HTTPS normal.

Piège 5 : VPN qui court-circuite DoH. Un client VPN actif remplace généralement les paramètres DNS du système pour forcer l’utilisation du résolveur DNS du VPN. Si votre VPN est mal configuré ou ne supporte pas DoH, toutes vos requêtes DNS passeront en clair par le résolveur du VPN, contournant la configuration DoH. Vérifiez que votre fournisseur VPN expose un résolveur DoH (Mullvad et ProtonVPN le font), ou configurez DoH dans chaque application individuellement plutôt qu’au niveau système.

Piège 6 : Performance dégradée par la création répétée de connexions. Chaque nouvelle connexion HTTPS vers le résolveur DoH implique un handshake TLS 1.3 (~20-50 ms selon la latence). Sur HTTP/2, les requêtes suivantes multiplexent la connexion existante sans overhead TLS. Si votre application Node.js crée une nouvelle connexion fetch pour chaque requête DNS, la latence est 10x supérieure au DNS classique. Solution : réutiliser les connexions via un client HTTP avec keepAlive: true ou utiliser une bibliothèque DoH qui gère le pool de connexions.

Piège 7 : Applications qui ignorent le DNS système. Chrome, Firefox en mode DoH actif, et certains clients P2P implémentent leur propre résolveur DNS et ignorent le résolveur configuré au niveau OS. Sur ces applications, même avec dnscrypt-proxy actif sur le port 53, leurs requêtes DNS passent directement vers des serveurs hardcodés dans l’application. Vérification : capturer le trafic avec Wireshark sur les ports 53 et 443 simultanément pour identifier ces applications.

Piège 8 : Fausse impression d’anonymat complet. DoH masque vos requêtes DNS à votre FAI et aux opérateurs réseau intermédiaires. Mais le fournisseur DoH voit toutes vos requêtes. Cloudflare, bien qu’audité annuellement, reste une entreprise américaine. Pour une confidentialité DNS plus robuste, combinez DoH avec un VPN dont le résolveur DNS utilise lui-même DoH, ou utilisez un résolveur DoH auto-hébergé sur un VPS européen avec dnscrypt-proxy.

Dépannage : 10 problèmes courants et leurs solutions

SymptômeCause probableSolution
Sites web inaccessibles après activation DoHMode strict actif, résolveur DoH inaccessiblePasser en mode avec repli, vérifier connectivité vers l’URL DoH avec curl
Wi-Fi public inaccessible (portail captif)DoH strict bloque l’interception DNS du portailDésactiver temporairement DoH ou passer en mode automatique
Ressources intranet non résoluesDNS split-horizon incompatible avec résolveur DoH externeAjouter domaines internes dans network.trr.excluded-domains (Firefox)
curl DoH retourne erreur 400Header Accept manquant ou URL mal forméeAjouter -H "Accept: application/dns-json" à la commande curl
dnscrypt-proxy ne démarre pasPort 53 occupé par systemd-resolvedDésactiver stub resolver : DNSStubListener=no dans /etc/systemd/resolved.conf
Firefox revient au DNS classique après redémarrageExtension (uBlock, VPN) surcharge les paramètres DNSVérifier about:config, désactiver extensions DNS temporairement
Quad9 bloque des sites légitimesFaux positif dans le filtre de malware Quad9Tester avec Cloudflare 1.1.1.1, signaler le faux positif sur quad9.net
DoH très lent (500+ ms par requête)Nouvelle connexion TLS créée pour chaque requêteActiver HTTP/2 et keepalive dans le client HTTP, implémenter un cache DNS local
Mobile Android ignore DoH configuréAndroid utilise Private DNS (DoT port 853), pas DoHParamètres, Connexions, DNS privé : entrer 1dot1dot1dot1.cloudflare-dns.com
DNSSEC échoue (AD=false) sur Quad9Domaine sans DNSSEC ou validation DNSSEC bloquéeComportement normal si le domaine n’implémente pas DNSSEC, utiliser Cloudflare 1.1.1.1 si blocage gênant

Diagnostic avancé : identifier la source des requêtes DNS en clair

Pour diagnostiquer avec précision quelle application envoie encore des requêtes DNS classiques malgré DoH actif, utilisez ss ou lsof sous Linux pour identifier les processus qui établissent des connexions sur le port 53 :

# Identifier les processus qui utilisent le port 53 (DNS classique)
sudo ss -tulnp | grep ':53'
# ou
sudo lsof -i :53 -P -n

# Capturer toutes les requêtes DNS classiques en temps réel et identifier leur source
sudo tcpdump -n -i any 'udp port 53 or tcp port 53' -l 2>/dev/null | \
  head -20

# Sur Linux : trouver quel processus fait des requêtes DNS en clair
sudo strace -e trace=network -f -p $(pgrep -f "nom_du_processus") 2>&1 | \
  grep "connect\|sendto" | grep "53"

# Sous Windows PowerShell
Get-NetUDPEndpoint -LocalPort 53 | ForEach-Object {
    $proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
    [PSCustomObject]@{PID=$_.OwningProcess; Nom=$proc.Name; Port=$_.LocalPort}
}

Conseils avancés pour administrateurs réseau et développeurs

DoH en entreprise avec résolveur interne. Les organisations peuvent déployer leur propre résolveur DoH interne via Unbound, dnscrypt-proxy en mode serveur, ou des solutions commerciales comme Cloudflare Gateway ou Cisco Umbrella. Cette approche “secure split DNS” offre DoH aux employés tout en maintenant la résolution des noms internes et la visibilité sur les requêtes DNS pour le SOC.

DoH dans Kubernetes via CoreDNS. CoreDNS 1.9+ supporte les transports TLS et HTTPS pour les requêtes upstream. Modifiez le ConfigMap CoreDNS pour ajouter le transport TLS vers Cloudflare : forward . tls://1.1.1.1 tls://1.0.0.1 { tls_servername cloudflare-dns.com } dans le Corefile. Les pods du cluster bénéficient alors du chiffrement DNS sans modification de leurs applications.

Conformité RGPD des fournisseurs DoH. En France et dans l’UE, le transfert de données de navigation DNS vers des serveurs américains peut créer une tension avec le RGPD (Articles 44-49, transferts vers pays tiers). Quad9 (basé en Suisse) et ses serveurs en Europe, ou un résolveur DoH auto-hébergé sur un VPS en France ou en Allemagne, sont des alternatives conformes sans questions de transferts hors UE. Cloudflare propose des Data Processing Agreements RGPD et localise les requêtes européennes dans ses datacenters en France, Allemagne, et Pays-Bas.

DoH et monitoring DNSSEC automatisé. Automatisez la surveillance de la validité DNSSEC pour vos domaines critiques. Un script cron qui interroge l’API DoH toutes les heures et alerte via Webhook Slack ou email si le champ AD passe de true à false peut détecter des compromissions de zone DNS ou des attaques BGP hijacking ciblant vos domaines.

Comparaison des méthodes de déploiement DoH

MéthodePortéeDifficultéAppareils couvertsRésistance VPN
Configuration navigateur (Firefox/Chrome)1 navigateur uniquementFacile (GUI)1 app sur 1 appareilFaible (VPN override)
Windows 11 (paramètres réseau)OS completMoyenToutes apps WindowsÉlevée (VPN override OS)
cloudflared (macOS/Linux)OS completMoyen (CLI)Toutes appsÉlevée (VPN override OS)
dnscrypt-proxy (Linux)OS completAvancé (config fichier)Toutes appsVariable
Configuration routeur (pfSense/OPNsense)Réseau entierAvancé (admin réseau)Tous appareils du LANNulle (en amont du VPN client)
Résolveur DoH auto-hébergéRéseau entier + contrôle totalExpert (infra VPS)Tous appareilsNulle

Questions fréquentes sur DNS over HTTPS

DoH remplace-t-il un VPN ?

Non. DoH chiffre uniquement les requêtes DNS. Votre adresse IP reste visible à tous les sites que vous visitez, et le contenu de vos connexions (hors DNS) n’est pas chiffré ou anonymisé par DoH. Un VPN chiffre l’intégralité de votre trafic et masque votre IP, mais son résolveur DNS peut ne pas utiliser DoH. Les deux sont complémentaires : un VPN avec résolveur DoH interne (comme Mullvad ou ProtonVPN) vous offre chiffrement du trafic, masquage d’IP, et chiffrement DNS simultanément.

DoH fonctionne-t-il sur Android et iOS ?

Android 9+ supporte “DNS privé” (DNS over TLS, pas DoH). Pour Cloudflare en DoT sur Android : Paramètres, Connexions, Paramètres réseau supplémentaires, DNS privé, puis entrez 1dot1dot1dot1.cloudflare-dns.com. Pour du DoH natif sur Android, des applications comme 1.1.1.1 (Cloudflare) créent un VPN local qui intercepte les requêtes DNS et les convertit en DoH. Sur iOS 14+, des profils de configuration DoH/DoT s’installent via l’application Apple Configurator ou l’app 1.1.1.1 de Cloudflare qui génère un profil .mobileconfig.

Mon FAI peut-il bloquer DoH ?

Techniquement oui, mais c’est difficile. DoH utilise le port 443 comme tout trafic HTTPS standard. Un FAI qui voudrait bloquer DoH devrait soit bloquer les IPs des résolveurs DoH (1.1.1.1, 8.8.8.8, 9.9.9.9), coupant du même coup des services légitimes, soit inspecter le SNI des connexions TLS. L’adoption d’ECH (Encrypted Client Hello) rendra cette inspection de plus en plus inefficace. En France, aucun FAI ne bloque activement les résolveurs DoH publics connus en 2026.

DoH améliore-t-il les performances DNS ?

La réponse dépend de votre situation de départ. Si votre résolveur DNS actuel (celui de votre FAI ou du DHCP) est lent ou géographiquement distant, passer à Cloudflare 1.1.1.1 (3 ms depuis la France) peut accélérer significativement la résolution DNS. Si votre résolveur actuel est déjà rapide, la première résolution DoH sera plus lente (handshake TLS ~20-50 ms), mais les suivantes seront comparables grâce au multiplexage HTTP/2 et au cache DNS côté résolveur.

Quelle est la différence entre DoH et DoT ?

DNS over TLS (DoT, RFC 7858) chiffre les requêtes DNS via TLS sur le port dédié 853. DNS over HTTPS (DoH, RFC 8484) les encapsule dans HTTP/2 sur le port 443. Les deux offrent un chiffrement équivalent en termes de sécurité. La différence principale est la discrétion : DoH sur le port 443 est indiscernable du trafic HTTPS normal, tandis que DoT sur le port 853 est facilement identifiable et bloquable par les pare-feux. Pour les particuliers, DoH est généralement préférable. Pour les entreprises qui veulent distinguer le trafic DNS du reste pour le filtrer ou l’auditer, DoT sur le port 853 est plus simple à gérer.

Comment DoH interagit-il avec Pi-hole ?

Pi-hole est un résolveur DNS local qui filtre les publicités mais ne supporte pas DoH nativement. Pour combiner Pi-hole et DoH : installez cloudflared sur le même serveur que Pi-hole, configurez cloudflared pour écouter sur le port 5053, puis configurez Pi-hole pour utiliser 127.0.0.1:5053 comme serveur DNS upstream dans Paramètres, DNS. Pi-hole filtre les publicités localement, et cloudflared transmet les requêtes non bloquées via DoH vers Cloudflare. Le réseau entier bénéficie du blocage de publicités Pi-hole ET du chiffrement DNS DoH.

Comment vérifier que mes données DNS ne fuitent pas ?

Utilisez le test de diagnostic Cloudflare sur https://1.1.1.1/help. Ce test effectue plusieurs résolutions DNS et identifie quel résolveur répond à vos requêtes. Si le test retourne les serveurs de votre FAI plutôt que les serveurs de votre fournisseur DoH configuré, vous avez une fuite DNS. Les causes les plus fréquentes sont un VPN actif qui surcharge les paramètres DNS, une application qui utilise son propre résolveur DNS interne, ou un mode DoH “avec repli” qui bascule vers DNS classique sans vous en informer.

Couverture associée

Pour approfondir la protection de votre vie privée numérique et la sécurité réseau :