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](https://www.rfc-editor.org/rfc/rfc7858) et [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) 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](https://www.afnic.fr/fr/l-afnic-en-bref/actualites/actualites-generales/12284/show/jcsa19-retour-sur-l-edition-2019-de-la-journee-du-conseil-scientifique-de-l-afnic-1.html). 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](https://dnsdist.org/) et [unbound](https://nlnetlabs.nl/projects/unbound/about/). `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](#prérequis) * [Partie I - Résolveur](#partie-i-résolveur) * [Installation](#installation) * [Configuration](#configuration) * [Partie II - Frontal DNS](#partie-ii-frontal-dns) * [Installation](#installation-1) * [Configuration](#configuration-1) * [Utilisation de la console dnsdist](#utilisation-de-la-console-dnsdist) * [Partie III - Gestion des certificats](#partie-iii-gestion-des-certificats) * [Renouvellement des certificats](#renouvellement-des-certificats) * [Automatisation avec cron](#automatisation-avec-cron) * [Automatisation avec un timer systemd](#automatisation-avec-un-timer-systemd) * [Remarques](#remarques) * [Partie V - NGINX Reverse proxy](#partie-v-nginx-reverse-proxy) * [Partie IV - Testez votre résolveur avec l'outil Homer](#partie-iv-testez-votre-résolveur-avec-loutil-homer) * [Partie VI - Utilisez votre résolveur](#partie-vi-utilisez-votre-résolveur) --- ## 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 {#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](https://www.isc.org/bind), [Knot Resolver](https://www.knot-resolver.cz) ou encore [Unbound](https://nlnetlabs.nl/projects/unbound/about/). 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](https://nlnetlabs.nl/documentation/unbound/unbound.conf/). 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 {#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](https://www.powerdns.com) qui développpe le logiciel propose et maintient [ses propres dépôts pour Debian, Raspbian, Ubuntu et CentOS](https://repo.powerdns.com/). Ainsi, voici comment installer la dernière version de dnsdist, actuellement `1.5.0`, tel que défini sur [le site de PowerDNS](https://repo.powerdns.com/) 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 addAction(MaxQPSIPRule(100), DropAction()) ``` L'ensemble des options de configuration est détaillé [sur le site de dnsdist](https://dnsdist.org/index.html). 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](https://dnsdist.org/guides/console.html) 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 {#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](https://fr.wikipedia.org/wiki/Autorit%C3%A9_de_certification). Nous allons utiliser [Let's Encrypt](https://letsencrypt.org/) comme autorité de certification. Let's Encrypt propose par ailleurs un petit utilitaire en ligne de commande [certbot](https://certbot.eff.org) 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](https://certbot.eff.org/instructions). 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 {#partie-iv-testez-votre-résolveur-avec-loutil-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](https://framagit.org/bortzmeyer/homer). 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 {#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 ; 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 {#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](https://support.mozilla.org/en-US/kb/firefox-dns-over-https), [Chrome](https://blog.chromium.org/2020/05/a-safer-and-more-private-browsing-DoH.html), Edge et [Opera](https://blogs.opera.com/desktop/2019/10/opera-65-beta/) mais également par plusieurs systèmes d'exploitation : [Android](https://android-developers.googleblog.com/2018/04/dns-over-tls-support-in-android-p.html) 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.