Tutoriel creer son resolveur DoT/DoH
This commit is contained in:
712
README.md
Normal file
712
README.md
Normal file
@@ -0,0 +1,712 @@
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
# Installation
|
||||
|
||||
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 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](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 (IPv4 et IPv6)
|
||||
access-control: 0.0.0.0/0 refuse
|
||||
access-control: 127.0.0.1/32 allow
|
||||
access-control: ::0/0 refuse
|
||||
access-control: ::1 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
|
||||
```
|
||||
|
||||
Il est tout à fait possible de désactiver IPv4 ou IPv6, pour cela ne pas
|
||||
définir l'interface associée et ajouter la règle suivante en fonction :
|
||||
|
||||
```
|
||||
server:
|
||||
do-ip4: no # désactive IPv4
|
||||
do-ip6: no # désactive IPv6
|
||||
```
|
||||
|
||||
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 IPv6, 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
|
||||
$ dig +notcp @::1 AAAA afnic.fr # connexion UDP en IPv6 au résolveur
|
||||
$ dig +tcp @::1 AAAA afnic.fr # connexion TCP en IPv6 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) et/ou `::1` (IPv6).
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
* 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](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
|
||||
|
||||
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/lestencrypt/live/${DOMAIN_DOT}/fullchain.pem /etc/dnsdist/dot-server.crt
|
||||
cp /etc/lestencrypt/live/${DOMAIN_DOT}/privkey.pem /etc/dnsdist/dot-server.key
|
||||
|
||||
# copie du certificat utilisé pour DoH
|
||||
cp /etc/lestencrypt/live/${DOMAIN_DOH}/fullchain.pem /etc/dnsdist/doh-server.crt
|
||||
cp /etc/lestencrypt/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](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 - 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.
|
||||
Reference in New Issue
Block a user