2024-07-02 00:07:30 +02:00
2023-01-20 09:55:32 +00:00
Fix
2024-07-02 00:07:30 +02:00

Installation et configuration d'un résolveur DoT et DoH public

DNS over TLS (DoT) et DNS over HTTPS (DoH) sont deux protocoles standardisés par l'IETF dans les RFC 7858 et RFC 8484 respectivement. Ces deux protocoles ont pour but de sécuriser les requêtes DNS entre un client et le résolveur. Ces deux protocoles sont en fait une encapsulation du protocole DNS dans une session TLS pour DoT ou HTTPS pour DoH.

Pour plus d'informations sur DoH, une présentation a été réalisée lors de la journée du Conseil Scientifique 2019.

Le but de ce document est de décrire comment installer et configurer son propre résolveur DoT et DoH accessible depuis Internet.

Il existe de nombreux logiciels de résolution DNS. Cependant peu, voire aucun, ne supportent actuellement nativement et de manière stable les protocoles DoT et DoH. Cela évolue néanmoins, les éditeurs y travaillent. C'est pour cela qu'il a été choisi de décrire cette procédure en utilisant dnsdist et unbound. dnsdist est un frontal DNS qui supporte DoT et DoH. En tant que frontal il doit être configuré pour savoir vers quel résolveur DNS faire suivre les requêtes entrantes. unbound sera ce résolveur.

Ce document suppose que vous disposez des droits administrateurs sur la machine où vous souhaitez installer le résolveur DoT/DoH. Il est tout à fait possible d'utiliser une machine locale (serveur, Raspberry Pi) ou un hébergement externalisé. Ce tutoriel a été réalisé avec un serveur dédié virtuel et le système d'exploitation Debian 10.



Prérequis

Assurez vous que les ports 853 (DoT), 443 (DoH) et 80 (challenge Let's encrypt) sont bien ouverts sur votre machine.

Dans le cadre de la mise en place d'un résolveur public, vous possédez un nom de domaine auquel sont associés les enregistrement A et AAAA éventuels correspondant à l'adresse IP sur laquelle sera installé le résolveur DoT/DoH.

La solution technique retenue ici pour le résolveur DoT/DoH est composée d'un frontal dnsdist qui assure la terminaison des sessions TLS et HTTPS et transmet les requêtes vers un résolveur DNS unbound installé en local sur la machine.

Partie I - Résolveur

Commençons par installer et configurer le résolveur DNS. Il existe plusieurs logiciels pour faire de la résolution comme BIND 9, Knot Resolver ou encore Unbound. Nous avons choisi d'utiliser Unbound et cette partie documente comment installer et configuer ce résolveur.

Installation

En règle général Unbound est disponible dans les dépôts des distributions. Donc il suffit de l'installer depuis le gestionnaire de paquet de votre machine.

$ sudo apt-get install unbound

Configuration

Maintenant que Unbound est installé, il ne reste plus qu'à le configurer avant de démarrer le service.

Il s'agit du résolveur DNS, celui ci n'est accessible que depuis la machine locale via le port 53 (il est tout à fait possible de modifier cette valeur).

Pour cela il est nécessaire de modifier le fichier de configuration par défaut /etc/unbound/unbound.conf. Il est tout à fait possible de sauvegarder la configuration par défaut :

$ sudo cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.orig

Puis modifier le fichier avec le contenu suivant :

server:
    # ne rien enregistrer dans les journaux hormis les erreurs
    verbosity: 0

    # n'écouter que sur l'interface locale en IPv4
    # unbound nécessite d'être relancé si modifié
    interface: 127.0.0.1

    port: 53

    # refuser tout le monde sauf les connexions locales (pas forcément
    # nécessaire vu que le serveur n'écoute que sur la boucle locale en IPv4)
    access-control: 0.0.0.0/0 refuse
    access-control: 127.0.0.1/32 allow

    # par défaut, unbound ne log pas les requêtes ni les réponses
    # on peut le rappeler au cas où
    log-queries: no
    log-replies: no

    # imposer la QNAME minimisation (RFC 7816)
    qname-minimisation: yes
    # même si le serveur faisant autorité ne le veut pas
    #   après discussion, il est possible que cette option ne soit
    #   pas recommandée dans le cadre d'un résolveur ouvert
    qname-minimisation-strict: yes

Enregistrer le contenu de ce fichier dans /etc/unbound/unbound.conf. Il est possible de vérifier la validité du fichier de configuration avec la commande suivante :

$ unbound-checkconf /etc/unbound/unbound.conf
unbound-checkconf: no errors in /etc/unbound/unbound.conf

Remarque: il est possible que les utilitaires unbound et unbound-checkconf soient dans le dossier /usr/sbin/ et que ce dossier ne soit pas dans le PATH, pour l'y ajouter utilisez la commande suivante :

export PATH=$PATH:/usr/sbin

Toutes les règles disponibles sont détaillées dans le manuel man 5 unbound.conf ou dans le manuel en ligne.

Enfin il ne reste plus qu'à démarrer le résolveur.

$ sudo systemctl start unbound.service

Il est possible de s'assurer que tout fonctionne bien à l'aide de la commande dig disponible dans le paquet bind9-dnsutils ou dnsutils. Pour cela il suffit de spécifier l'adresse de notre résolveur, ici 127.0.0.1 ou ::1 et d'effectuer une requête DNS. Ici on demande à Unbound de récupérer l'enregistrement AAAA associé au nom de domaine afnic.fr.

$ sudo apt-get install bind9-dnsutils # ou dnsutils selon les distributions
$ dig @127.0.0.1 AAAA afnic.fr
; <<>> DiG 9.16.1-Ubuntu <<>> @127.0.0.1 AAAA afnic.fr
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35856
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;afnic.fr.                      IN      AAAA

;; ANSWER SECTION:
afnic.fr.               600     IN      AAAA    2001:67c:2218:302::51:231

;; Query time: 152 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Sep 28 10:16:00 UTC 2020
;; MSG SIZE  rcvd: 65

Une réponse est bien renvoyée. Le résolveur fonctionne. Il est possible de s'assurer que tout est opérationnel en IPv4, et en utilisant UDP et TCP.

$ dig +notcp @127.0.0.1 AAAA afnic.fr  # connexion UDP en IPv4 au résolveur
$ dig +tcp @127.0.0.1 AAAA afnic.fr    # connexion TCP en IPv4 au résolveur

À ce stade, un résolveur Unbound est configuré en local et écoute sur le port 53. Il peut donc être utilisé pour résoudre toutes les requêtes en provenance de la machine.

Partie II - Frontal DNS

Cette section s'attarde sur l'installation et la configuration d'un frontal DoT/DoH qui transmettra les requêtes DNS à un résolveur local écoutant sur le port 53 de l'interface local 127.0.0.1 (IPv4).

Ici dnsdist se trouve être une très bonne solution pour remplir ce rôle.

Installation

Il est possible que dnsdist soit déjà présent dans les dépôts officiels. Vous pouvez utilisez cette version, il suffit alors de s'assurer que la version de dnsdist ainsi récupérée supporte bien DoT et DoH :

$ sudo apt-get install dnsdist
$ dnsdist --version
dnsdist 1.4.0 (Lua 5.2.4)
Enabled features: ... dns-over-tls(gnutls openssl) dns-over-https(DOH) ...

Si les options dns-over-tls et dns-over-https ne sont pas listées, ou que vous désiriez utiliser la dernière version de dnsdist, PowerDNS qui développpe le logiciel propose et maintient ses propres dépôts pour Debian, Raspbian, Ubuntu et CentOS.

Ainsi, voici comment installer la dernière version de dnsdist, actuellement 1.5.0, tel que défini sur le site de PowerDNS pour :

  • Debian / Ubuntu / Raspbian
# récupération du nom de la distribution et de son ID
# ATTENTION: le fichier /etc/os-release peut être différent selon la distribution
export D_NAME=$(. /etc/os-release; echo ${VERSION_CODENAME})
export D_ID=$(. /etc/os-release; echo ${ID})

# ajout du dépôt aux sources
# Debian / Ubuntu
echo "deb [arch=amd64] http://repo.powerdns.com/${D_ID} ${D_NAME}-dnsdist-15 main" | sudo tee /etc/apt/sources.list.d/pdns.list
# Raspbian
echo "deb http://repo.powerdns.com/raspbian ${D_NAME}-dnsdist-15 main" | sudo tee etc/apt/sources.list.d/pdns.list

# gestion de l'étiquette et de la priorité du nouveau dépôt
sudo tee /etc/apt/preferences.d/dnsdist << EOF
Package: dnsdist*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF

# ajout de la clé publique de PowerDNS
curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo apt-key add -

# mise à jour des dépôts
sudo apt-get update

# installation de dnsdist
sudo apt-get install dnsdist
  • Debian 12
# Créer le fichier '/etc/apt/sources.list.d/pdns.list' avec ce contenu :

deb [signed-by=/etc/apt/keyrings/dnsdist-19-pub.asc arch=amd64] http://repo.powerdns.com/debian bookworm-dnsdist-19 main


# Mettre ceci dans '/etc/apt/preferences.d/dnsdist-19':

Package: dnsdist*
Pin: origin repo.powerdns.com
Pin-Priority: 600

# Exécuter la commande suivante :

sudo install -d /etc/apt/keyrings; curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo tee /etc/apt/keyrings/dnsdist-19-pub.asc

# S'il y a ce message d'erreur :

The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 1B0C6205FD380FBB

# Alors exécuter cette commande :

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1B0C6205FD380FBB

# mise à jour des dépôts
sudo apt-get update

# installation de dnsdist
sudo apt-get install dnsdist
  • CentOS 7
yum install epel-release yum-plugin-priorities
curl -o /etc/yum.repos.d/powerdns-dnsdist-15.repo https://repo.powerdns.com/repo-files/centos-dnsdist-15.repo
yum install dnsdist

Configuration

Maintenant que dnsdist est installé, passons à sa configuration. Cela se passe dans le fichier /etc/dnsdist/dnsdist.conf. Ce fichier utilise une syntaxe très accessible. Pensez à modifier les IPs avec celle de l'interface de votre machine.

-- le résolveur DoT/DoH est public, on accepte tout le monde en IPv4 et IPv6
setACL({'0.0.0.0/0', '[::]/0'})

-- serveur DNS où transférer les requêtes entrantes
newServer({address='127.0.0.1:53', name='Unbound (local)'})

-- configuration de DoT
-- modifier l'IPv4 et l'IPv6 en conséquence
addTLSLocal('198.51.100.19:853', '/etc/dnsdist/dot-server.crt', '/etc/dnsdist/dot-server.key', {minTLSVersion='tls1.2'})
addTLSLocal('[2001:db8::19]:853', '/etc/dnsdist/dot-server.crt', '/etc/dnsdist/dot-server.key', {minTLSVersion='tls1.2'})

-- configuration de DoH
-- modifier l'IPv4 et l'IPv6 en conséquence
addDOHLocal('198.51.100.19:443', '/etc/dnsdist/doh-server.crt', '/etc/dnsdist/doh-server.key', '/', {minTLSVersion='tls1.2'})
addDOHLocal('[2001:db8::19]:443', '/etc/dnsdist/doh-server.crt', '/etc/dnsdist/doh-server.key', '/', {minTLSVersion='tls1.2'})

-- limitation du trafic à 100 requêtes par seconde
-- plus d'info en <https://dnsdist.org/advanced/qpslimits.html>
addAction(MaxQPSIPRule(100), DropAction())

L'ensemble des options de configuration est détaillé sur le site de dnsdist.

Il est possible de vérifier que le fichier de configuration est valide avec la commande :

$ dnsdist --check-config
Configuration '/etc/dnsdist/dnsdist.conf' OK!

dnsdist est donc configuré pour écouter sur l'interface publique de la machine sur les ports 443 (DoH) et 853 (DoT). Toutes les requêtes sont ensuite relayées à un serveur écoutant le port 53 sur l'interface locale.

Pour l'instant les fichiers dot-server.crt, dot-server.key, doh-server.crt et doh-server.key n'existent pas. Il est nécessaire de les générer. Cela peut se faire avec openssl dans le cas de certificats auto-signés. Il est aussi possible de passer par une autorité de certification, ceci est le but de la prochaine partie.

Remarque: attention aux droits des fichiers du certificat et de la clé, l'utilisateur ou le groupe dnsdist (parfois _dnsdist, vérifier le contenu du fichier /etc/group avec la commande grep dnsdist /etc/group) doit avoir les droits en lecture dessus sudo chown -R root:dnsdist /etc/dnsdist

Remarque: par soucis de sécurité les clés ne sont pas lisibles par tout le monde sudo chmod 640 /etc/dnsdist/do[th]-server.key

Utilisation de la console dnsdist

Remarque: il est possible qu'en déroulant ce tutoriel de manière linéaire, les commandes de cette partie échouent car les fichiers avec les certificats n'existent pas encore. Pour remédier à ce problème, vous pouvez commenter les lignes contenant addTLSLocal et addDOHLocal dans le fichier de configuration, ou bien générer des certificats autosignés avec openssl ou encore vous référer à la partie suivante sur la gestion des certificats, avant de revenir à celle-ci.

Lorsque dnsdist est lancé par sytemd, le programme est lancé en mode supervisé, c'est à dire sans console. Toutefois avoir un accès à la console de dnsdist peut s'avérer utile pour analyser les codes de retour des requêtes DoH par exemple. Pour cela il est nécessaire de configurer dnsdist pour accepter le rattachement d'une console cliente au programme. Cela passe par l'ajout des options suivantes à la configuration de dnsdist :

-- demande à dnsdist d'écouter sur le port 5199 de l'interface locale
controlSocket('127.0.0.1:5199')
-- définition d'une clé d'authentification que devra utiliser le client
setKey('clé générée avec makeKey()')
-- il est aussi possible de restreindre les accès
setConsoleACL({'127.0.0.1/32', '::1'}) -- depuis la machine locale uniquement

Afin de générer la clé privée, lancer la commande makeKey() dans la console dnsdist et copier la sortie dans le fichier de configuration :

$ sudo dnsdist
> makeKey()
setKey("Oj9sQ+/PtUm7qLCZtRtzl8uWmgRXSKVqjej+YS/iEjc=")

Ainsi, lorsque dnsdist tourne, il est tout à fait possible d'accéder à sa console depuis la machine locale :

$ sudo systemctl start dnsdist
$ dnsdist -c 127.0.0.1:5199
> showDOHResponseCodes()

- HTTP/1:

#   Address               200     400     403     500     502     Others
0   198.51.100.19:443       0       0       0       0       0          0
1   [2001:db8::19]:443      0       0       0       0       0          0

- HTTP/2:

#   Address               200     400     403     500     502     Others
0   198.51.100.19:443       0       0       0       0       0          0
1   [2001:db8::19]:443      0       0       0       0       0          0

Partie III - Gestion des certificats

Afin de pouvoir proposer une connexion sécurisée au résolveur, il est nécessaire de posséder au moins un certificat par service. Il est tout à fait possible de générer ses propres certificats auto-signés. Cependant pour augmenter la confiance dans le service proposé, il est intéressant de s'appuyer sur un tiers de confiance, l'autorité de certification. Nous allons utiliser Let's Encrypt comme autorité de certification. Let's Encrypt propose par ailleurs un petit utilitaire en ligne de commande certbot pour générer et gérer ses certificats. La génération d'un certificat via cet utilitaire repose sur un challenge que doit résoudre la machine.

Bien que nous privilégions et recommandons l'utilsation du challenge DNS ;), nous retenons ici le challenge HTTP. Ce challenge repose sur l'utilisation d'un serveur web écoutant sur le port 80. Il n'est pas nécessaire d'avoir un tel serveur installé sur la machine. Dans ce cas, certbot se charge de faire tourner un serveur web temporaire le temps de résoudre le challenge. Si un serveur web écoute déjà sur le port 80 comme apache ou nginx, certbot peut être configuré pour utiliser ce serveur web. Pour cela référez vous aux instructions de certbot.

Nous allons configurer les noms de domaine suivants : dot-demo.rd.nic.fr et doh-demo.rd.nic.fr. Les enregistrements suivants sont ajoutés à la zone rd.nic.fr. (pensez à remplacer les IPs avec celles de votre machine) :

dot-demo     86400   A       198.51.100.19
             86400   AAAA    2001:db8::19
doh-demo     86400   A       198.51.100.19
             86400   AAAA    2001:db8::19

Une fois cette étape réalisée, il ne reste plus qu'à installer certbot et à demander 2 certificats, un pour chaque service.

$ sudo apt-get install certbot

Certbot stocke tous les certificats générés dans /etc/letsencrypt/archive/nomdedomaine/ et le répertoire /etc/letsencrypt/live/nomdedomaine/ contient des liens vers les fichiers du dossier archive/nomdedomaine/. Par défaut tous ces fichiers sont la propriété de l'utilisateur root. Or nous avons vu que dnsdist tourne avec l'utilisateur dnsdist et donc il est nécessaire que cet utilisateur ait la capacité de lire les certificats.

Pour cela nous allons suivre la procédure suivante :

  1. (re)générer les certificats avec certbot
  2. copier les certificats dans le dossier /etc/dnsdist/ en utilisant le nom utilisé dans la configuration de dnsdist
  3. modifier les droits de ces fichiers sudo chown :dnsdist /etc/dnsdist/do[th]-server.* (il est possible que le nom du groupe diffère, par exemple _dnsdist)
  4. relancer dnsdist

Génération d'un certificat pour le nom de domaine dot-demo.rd.nic.fr :

$ sudo certbot certonly --standalone -d 'dot-demo.rd.nic.fr' -m 'mail@example.com' --no-eff-email
  • -m 'mail@example.com' : permet de renseigner son mail depuis la ligne de commande
  • --no-eff-email : demander à l'autorité de certification de ne pas transmettre le mail à l'EFF

Idem pour le nom de domaine doh-demo.rd.nic.fr :

$ sudo certbot certonly --standalone -d 'doh-demo.rd.nic.fr' -m 'mail@example.com' --no-eff-email

Les étapes 2 à 4 peuvent être automatisées dans un script comme celui ci, que nous avons appelé deploy-cert.sh :

#!/bin/sh

# script de déploiement des certificats
# lancé par certbot via l'option --deploy-hook /chemin/du/script.sh
# ce script doit être lancé avec les droits root

DOMAIN_DOT="dot-demo.rd.nic.fr"
DOMAIN_DOH="doh-demo.rd.nic.fr"

DNSDIST_GROUP="$(grep dnsdist /etc/group | cut -d ':' -f 1)"

# copie du certificat utilisé pour DoT
cp /etc/letsencrypt/live/${DOMAIN_DOT}/fullchain.pem /etc/dnsdist/dot-server.crt
cp /etc/letsencrypt/live/${DOMAIN_DOT}/privkey.pem /etc/dnsdist/dot-server.key

# copie du certificat utilisé pour DoH
cp /etc/letsencrypt/live/${DOMAIN_DOH}/fullchain.pem /etc/dnsdist/doh-server.crt
cp /etc/letsencrypt/live/${DOMAIN_DOH}/privkey.pem /etc/dnsdist/doh-server.key

# modification des droits
chown root:${DNSDIST_GROUP} /etc/dnsdist/dot-server.crt /etc/dnsdist/dot-server.key
chown root:${DNSDIST_GROUP} /etc/dnsdist/doh-server.crt /etc/dnsdist/doh-server.key
chmod 640 /etc/dnsdist/dot-server.key /etc/dnsdist/doh-server.key

# relancer dnsdist pour prendre en compte les changements
# REMARQUE: il est aussi possible d'utiliser la console dnsdist pour recharger
#           les certificats, avec l'option reloadAllCertificates() :
#
#             $ dnsdist -c 127.0.0.1:5199
#             > reloadAllCertificates()
#
#           et en une ligne :
#
#             $ dnsdist -c 127.0.0.1:5199 -e 'reloadAllCertificates()'
#
#           cela nécessite que dnsdist soit configuré de sorte à ce que la
#           console soit accessible
systemctl restart dnsdist

Ainsi suite à la génération des certificats, il ne reste plus qu'à lancer ce script :

$ sudo ./deploy-cert.sh

Renouvellement des certificats

Les certificats générés par Let's Encrypt ne sont valable que 90 jours. Il convient de penser à préparer leur renouvellement. Le script deploy-hook.sh s'avère ici très utile pour automatiser le déploiement des certificats, et cela grâce à l'option --deploy-hook de l'utilitaire certbot.

$ sudo certbot renew --deploy-hook "/path/to/deploy-cert.sh"

Le renouvellement d'un certificat n'a lieu que dans les 30 jours avant son expiration. Ainsi nous choisissons d'automatiser la demande de renouvellement toutes les semaines, afin d'être de palier à d'éventuels problèmes (machine qui redémarre, autorité de certification en panne au moment de la demande...).

Automatisation avec cron

Il est tout à fait possible d'automatiser cette commande dans une tâche de type cron en ajoutant la ligne suivante à crontab (sudo crontab -e) :

# se lance toutes les semaines le lundi
0 0 * * 1 certbot renew --deploy-hook "/path/to/deploy-cert.sh"

Automatisation avec un timer systemd

Une autre approche est d'utiliser systemd pour automatiser le renouvellement des certificats. Il s'avère que sur la machine utilisée, certbot installe deux fichiers systemd :

  • /lib/systemd/system/certbot.service : l'unité qui contient la commande à lancer pour le renouvellement
  • /lib/systemd/system/certbot.timer : un minuteur associé au service (ils portent le même nom)

Il est alors possible de substituer certaines règles en créant les même fichiers dans /etc/systemd/system. Dans ce cas, systemd retiendra les valeurs définies dans ces fichiers.

$ cat /etc/systemd/system/certbot.service
[Unit]
Description=Certbot renew

[Service]
ExecStart=/usr/bin/certbot renew --deploy-hook "/etc/certbot/deploy-cert.sh"
$ cat /etc/systemd/system/certbot.timer
[Unit]
Description=Run certbot renew monthly

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target

Une fois les fichiers créés, il reste à recharger ces règles dans systemd :

$ sudo systemctl daemon-reload

Il est alors possible de vérifier les journaux pour s'assurer du bon renouvellement :

$ journalctl -u certbot.service

Remarques

Si vous avez un déjà un programme qui écoute sur le port 80, il est tout à fait possible de demander à certbot de l'arrêter avant de procéder au renouvellement puis de le redémarrer avec les options --pre-hook "systemctl stop program" et l'option --post-hook "systemctl start program".

$ sudo certbot renew --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2" --deploy-hook "/path/to/deploy-cert.sh"

Partie IV - Testez votre résolveur avec l'outil Homer

Pour s'assurer que le résolveur fonctionne de manière nominal, il est possible d'utiliser Homer.

Homer est un outil développé par l'Afnic, qui permet de tester et débugger un résolveur DoT/DoH en ligne de commande.

Homer est un logiciel libre et le code est disponible sur la forge logicielle Framagit.

L'outil nécessite python3, et certains modules associés :

$ sudo apt-get install python3 python3-pycurl python3-dnspython python3-openssl python3-netaddr

Il ne reste plus qu'à récupérer Homer et à le lancer.

$ git clone https://framagit.org/bortzmeyer/homer
$ cd homer
$ ./homer.py https://doh-demo.rd.nic.fr afnic.fr
id 0
opcode QUERY
rcode NOERROR
flags QR RD RA
edns 0
payload 4096
option ECS ::/0 scope/0
;QUESTION
afnic.fr. IN AAAA
;ANSWER
afnic.fr. 600 IN AAAA 2001:67c:2218:302::51:231
;AUTHORITY
;ADDITIONAL

Total elapsed time: 0.07 seconds (65.68 ms/request)
$ ./homer.py --dot dot-demo.rd.nic.fr framagit.org
id 59643
opcode QUERY
rcode NOERROR
flags QR RD RA
edns 0
payload 4096
;QUESTION
framagit.org. IN AAAA
;ANSWER
framagit.org. 2730 IN AAAA 2a01:4f8:231:4c99::75
;AUTHORITY
;ADDITIONAL

Total elapsed time: 0.01 seconds (7.99 ms/request)

Homer peut aussi être utilisé pour tester la bonne configuration du résolveur :

$ ./homer.py --check --dot dot-demo.rd.nic.fr framasoft.org
OK

$ ./homer.py --check https://doh-demo.rd.nic.fr chatons.org
OK

Dans le cas où votre résolveur est mal configuré, Homer s'arrête est affiche l'erreur rencontrée. Par exemple pour un certificat non configuré :

$ ./homer.py --dot 198.51.100.19 framasoft.org
198.51.100.19: Certificate error: "198.51.100.19 is not in the certificate
Could not connect to "198.51.100.19"

Il est toutefois possible de demander à Homer de ne pas vérifier le certificat avec l'option -k | --insecure :

$ ./homer.py --insecure --dot 198.51.100.19 framasoft.org
id 35430
opcode QUERY
rcode NOERROR
flags QR RD RA
edns 0
payload 4096
option ECS ::/0 scope/0
;QUESTION
framasoft.org. IN AAAA
;ANSWER
framasoft.org. 3600 IN AAAA 2a01:4f8:141:3421::212
;AUTHORITY
;ADDITIONAL

Total elapsed time: 0.04 seconds (41.83 ms/request)

Partie V - NGINX Reverse proxy

Il est possible d'utiliser NGINX pour diriger le flux vers le serveur DoH en local. Pour ce faire, modifier le fichier dnsdist.conf comme ci.

-- Create local DOH server listener in DNS over HTTPS mode, otherwise the information coming from nginx won't be processed well (see nginx conf)
addDOHLocal('0.0.0.0:5300', nil, nil, '/', { reusePort=true })
addDOHLocal('[::]:5300', nil, nil, '/', { reusePort=true })

Le serveur écoute sur le port 5300

Du côté NGINX, créer un fichier de configuration pour le proxy reverse

pstream dns-backend {
	server 127.0.0.1:5300;
	keepalive 30;
}

server {
	listen 443 ssl http2;
	listen \[::\]:443 ssl http2;
	ssl_certificate /etc/letsencrypt/live/dns.adriatis.org/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/dns.adriatis.org/privkey.pem;
	ssl_dhparam /etc/nginx/ssl/server.dhparam;

	server_name <nom_du_serveur_doh>;

	location / {
    	proxy_set_header X-Real-IP $remote_addr;
	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	proxy_set_header Host $http_host;
	    proxy_set_header X-NginX-Proxy true;
    	proxy_set_header Connection "";
	    proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
	    proxy_redirect off;
    	proxy_set_header X-Forwarded-Proto $scheme;
	    proxy_read_timeout 86400;
    	grpc_pass grpc://dns-backend;
	}
}

Ici on utilise grpc_pass grpc://dns-backend parce qu'à partir de la version 1.9 de dnsdist, il n'y a plus de support HTTP/1 mais HTTP/2. Or, NGINX ne supporte que HTTP/1. La solution de contournement consiste à utiliser grpc_pass.

Partie VI - Utilisez votre résolveur

Vous voilà désormais en possession d'un résolveur DoT/DoH public.

DoT/DoH est supporté par plusieurs navigateurs : Firefox, Chrome, Edge et Opera mais également par plusieurs systèmes d'exploitation : Android et prochainement iOS / MacOS et Windows 10.

Les indications pour configurer son navigateur peuvent varier. Nous vous laissons le soin de vous renseigner selon les outils que vous utilisez.

Description
Tutoriel pour configurer votre propre résolveur, activer sa disponibilité via les protocoles DoT et DoH et le tester grâce à l'outil "Homer" développé par l'Afnic.
Readme 86 KiB