Post

🟢 🇫🇷 OVH Debian (vps-5351f610) Nebula LightHouse + DNS (dot doh) xoyaz.xyz

🟢 🇫🇷 OVH Debian (vps-5351f610) Nebula LightHouse + DNS (dot doh) xoyaz.xyz

vps-5351f610.vps.ovh.net
4 vCPU Cores
8 Go RAM
75 Go SSD NVME
1 Backup auto
Location: Gravelines
IP: 51.254.133.45
IPv6: 2001:41d0:305:2100::f148
OS: Debian 13
Nom d’utilisateur : debian

OVH VPS-1

OVH

Première connexion

Après avoir récupére le mot de passe sur sur le site OVH

Se connecter utilisateur debian via SSH

1
ssh debian@51.254.133.45

La procédure nous demande la création d’un nouveau mot de passe puis reconnexion utilisateur “debian”

Modifier le mot de passe root

1
2
3
sudo -s
passwd
exit

Autoriser la connexion root en créant le fichier /etc/ssh/sshd_config.d/10-root.conf

1
echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/10-root.conf

Redémarrer le service sshd

1
systemctl restart sshd

Se déconnecter de la session SSH en cours

Se connecter en root via SSH

1
ssh root@51.254.133.45

Mise à jour debian

Mise à jour

1
apt update && apt upgrade -y

Renommer utilisateur debian en userb

Renommer l’utilisateur debian en userb

1
2
3
4
# Renommer l’utilisateur
usermod -l userb debian
# Renommer le dossier /home
usermod -d /home/userb -m userb

Modifier les accès sudo en remplaçant debian par userb

1
sed -i 's/debian/userb/g' /etc/sudoers.d/90-cloud-init-users

Modifier le paramétrage SSH pour interdire la connexion root

1
2
3
4
# Supprimer le PermitRootLogin yes
rm /etc/ssh/sshd_config.d/10-root.conf
# Redémarrer le serveur sshd: 
systemctl restart sshd

Date et heure + Synchro

Reconfigurer locales

Activer uniquement fr_FR.UTF-8

1
dpkg-reconfigure locales

Default fr_FR.UTF-8 et en_US.UTF-8

1
2
3
4
Generating locales (this might take a while)...
  en_US.UTF-8... done
  fr_FR.UTF-8... done
Generation complete.

Activer le fuseau Europe/Paris

1
timedatectl set-timezone Europe/Paris

Horloge système synchronisée : timedatectl

1
2
3
4
5
6
7
               Local time: Wed 2026-01-14 20:32:00 CET
           Universal time: Wed 2026-01-14 19:32:00 UTC
                 RTC time: Wed 2026-01-14 19:32:00
                Time zone: Europe/Paris (CET, +0100)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Motd

Motd

1
rm /etc/motd && nano /etc/motd
1
2
3
4
5
6
7
8
9
10
11
12
   ___ __   __ _  _  __   __ ___  ___       _           
  / _ \\ \ / /| || | \ \ / /| _ \/ __| ___ / |          
 | (_) |\ V / | __ |  \ V / |  _/\__ \|___|| |          
  \___/  \_/  |_||_|   \_/  |_|  |___/     |_|          
  ___        _     _               _  ____              
 |   \  ___ | |__ (_) __ _  _ _   / ||__ /              
 | |) |/ -_)| '_ \| |/ _` || ' \  | | |_ \              
 |___/ \___||_.__/|_|\__,_||_||_| |_||___/              
  ___  _     ___  ___  _ _     _  ____ ____   _ _   ___ 
 | __|/ |   |_  )| __|| | |   / ||__ /|__ /  | | | | __|
 |__ \| | _  / / |__ \|_  _|_ | | |_ \ |_ \ _|_  _||__ \
 |___/|_|(_)/___||___/  |_|(_)|_||___/|___/(_) |_| |___/

Outils

Quelques outils

1
apt install rsync curl tmux jq figlet git tree -y

Hostname

Hostname xoyaz.xyz

1
hostnamectl set-hostname xoyaz.xyz

Vérifier: hostnamectl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 Static hostname: xoyaz.xyz
       Icon name: computer-vm
         Chassis: vm 🖴
      Machine ID: 576c980dfde948a79e8997eefa039c78
         Boot ID: 56b1562d718543e0a78bc9c5be88bae7
    Product UUID: 576c980d-fde9-48a7-9e89-97eefa039c78
    AF_VSOCK CID: 1
  Virtualization: kvm
Operating System: Debian GNU/Linux 13 (trixie)        
          Kernel: Linux 6.12.48+deb13-cloud-amd64
    Architecture: x86-64
 Hardware Vendor: OpenStack Foundation
  Hardware Model: OpenStack Nova
 Hardware Serial: 576c980d-fde9-48a7-9e89-97eefa039c78
Firmware Version: 1.16.3-debian-1.16.3-2~bpo12+1
   Firmware Date: Tue 2014-04-01
    Firmware Age: 11y 9month 2w 1d                    

Déconnexion ‘root’

Se déconnecter de la session ssh root

OpenSSH, clé et script

OpenSSH
connexion avec clé
sur l'ordinateur de bureau Générer une paire de clé curve25519-sha256 (ECDH avec Curve25519 et SHA2) pour une liaison SSH avec le serveur.

1
ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/vps-5351f610

Envoyer les clés publiques sur le serveur KVM

1
ssh-copy-id -i ~/.ssh/vps-5351f610.pub userb@51.254.133.45

sur le serveur KVM On se connecte via SSH

1
ssh userb@51.254.133.45

Créer la configuration utilisateur SSH dans le VPS

1
sudo nano /etc/ssh/sshd_config.d/10-userb.conf

Ajouter le contenu suivant

1
2
3
#PasswordAuthentication yes
Port = 55045
PasswordAuthentication no

Relancer le serveur

1
sudo systemctl restart sshd

Test connexion

1
ssh -p 55045 -i ~/.ssh/vps-5351f610 userb@51.254.133.45

Historique de la ligne de commande

Ajoutez la recherche d’historique de la ligne de commande au terminal Se connecter en utilisateur debian Tapez un début de commande précédent, puis utilisez shift + up (flèche haut) pour rechercher l’historique filtré avec le début de la commande.

1
2
3
# Global, tout utilisateur
echo '"\e[1;2A": history-search-backward' | sudo tee -a /etc/inputrc
echo '"\e[1;2B": history-search-forward' | sudo tee -a /etc/inputrc

Parefeu

Texte alternatif

Alternative: Configurer le pare-feu sous Linux avec Iptables

Installation UFW sur Debian / Ubuntu

1
sudo apt install ufw

Les règles

1
2
3
4
5
# Pour autoriser un port personnalisé et correspondant à votre accès SSH
sudo ufw allow 55045/tcp  # port SSH
sudo ufw allow https      # port 443
# Activer le parefeu
sudo ufw enable

Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Vérifier : sudo ufw status

1
2
3
4
5
6
7
8
Status: active

To                         Action      From
--                         ------      ----
55045/tcp                  ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
55045/tcp (v6)             ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             

OVH DNS xoyaz.xyz

OVH: Domaine xoyaz.xyz , DNSSEC Actif

1
2
3
4
5
6
7
8
$TTL 3600
@	IN SOA dns106.ovh.net. tech.ovh.net. (2026011800 86400 3600 3600000 300)
        IN NS     ns106.ovh.net.
        IN NS     dns106.ovh.net.
        IN A     51.254.133.45
        IN AAAA     2001:41d0:305:2100::f148
*        IN A     51.254.133.45
*        IN AAAA     2001:41d0:305:2100::f148

Borgbackup

BorgBackup VPS

Timer, service et bash

1
2
3
/etc/systemd/system/borgbackup-xoyaz.timer
/etc/systemd/system/borgbackup-xoyaz.service
/root/.borg/borgbackup-xoyaz.sh

Nebula lighthouse

Réseau

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether fa:16:3e:d4:bd:98 brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname enxfa163ed4bd98
    inet 51.254.133.45/32 metric 100 scope global dynamic ens3
       valid_lft 71910sec preferred_lft 71910sec
    inet6 2001:41d0:305:2100::f148/128 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fed4:bd98/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
4: nebula1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1300 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none 
    inet 10.239.100.254/24 brd 10.239.100.255 scope global nebula1
       valid_lft forever preferred_lft forever

Résolveur

systemd-resolved

Le résolveur que votre machine utilise par défaut est défini dans le fichier /etc/systemd/resolved.conf et utilise l’adresse IP 127.0.0.53.

Nous pouvons tester cela en utilisant la fouille à “example.com” et en regardant le sortie.

1
dig example.com

Près du bas de la sortie, nous pouvons voir 127.0.0.53Adresse IP.

1
;; SERVER: 127.0.0.53#53(127.0.0.53)

Pour changer cela, nous allons modifier le resolved.conf. Bien que la simple modification de ce fichier fonctionnera tant que la machine ne redémarre pas, nous devons nous assurer que cette modification est persistante. Pour ce faire, nous devons modifier l’entrée DNS afin qu’elle soit égale à 127.0.0.1 (ou toute adresse IP à laquelle Unbound est lié dans votre configuration) afin que la machine utilise Unbound par défaut. Ainsi, l’interface ressemblerait à ceci dans la configuration Unbound :

1
2
3
server:
    # specify the interface to answer queries from by ip-address.
    interface: 127.0.0.1

Pour tester que Unbound est en cours d’exécution, nous pouvons demander à Dig d’utiliser un serveur spécifique avec le @.

1
dig example.com @127.0.0.1

Si Unbound est en cours d’exécution, la sortie doit contenir l’adresse que nous avons spécifiée dans la configuration:

1
;; SERVER: 127.0.0.1#53(127.0.0.1)

Si nous changions resolved.conf maintenant, le résolveur par défaut serait persistant jusqu’à ce que le routeur veuille le mettre à jour. Pour nous assurer que cela ne fonctionne pas, nous devons également définir le DNSStubListener sur non afin qu’il ne soit pas modifié par notre routeur (comme avec un « résolveur recommandé » mentionné ci-dessous). Nous souhaitons également activer l’option DNSSEC afin de pouvoir vérifier l’intégrité des réponses que nous recevons à nos requêtes DNS. Avec votre éditeur de texte préféré (par exemple nano ) nous pouvons modifier le fichier :

1
nano /etc/systemd/resolved.conf

Ici, sous l’en-tête [Resolve], nous ajoutons/substituons nos modifications aux options :

1
2
3
4
5
6
7
8
9
10
11
[Resolve]
DNS=127.0.0.1
#FallbackDNS=
#Domains=
DNSSEC=yes
#DNSOverTLS=no
#MulticastDNS=no
#LLMNR=no
#Cache=no-negative
DNSStubListener=no
#DNSStubListenerExtra=

Ou mieux créer un nouveau resolved.conf.drépertoire à l’intérieur /etc/systemden utilisant:

1
sudo mkdir -p /etc/systemd/resolved.conf.d/

Ajouter un nouveau fichier /etc/systemd/resolved.conf.d/unbound.conf avec le contenu suivant:

1
2
3
4
[Resolve]
DNS=127.0.0.1
DNSSEC=yes
DNSStubListener=no

Pour que le système commence à utiliser notre configuration modifiée, Nous devons ensuite créer un lien symbolique pour écraser /etc/resolv.confà celui que nous avons modifié.

il existe déjà un lien symbolique entre /etc/resolv.conf et /run/systemd/resolve/resolv.conf

1
2
ls -la /etc/resolv.conf
lrwxrwxrwx 1 root root 39  1 nov.  11:47 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

Si pas de lien

1
sudo ln -fs /run/systemd/resolve/resolv.conf /etc/resolv.conf

Note

Assurez-vous que votre Unbound s’exécute à l’adresse IP à partir de la modification resolv.conf avant la prochaine étape, sinon vous pourriez casser votre internet connexion.

Avec le fichier resolv.conf modifié, nous pouvons redémarrer systemd à l’aide du nouveau résolveur configuration avec:

1
systemctl restart systemd-resolved

Si vous rencontrez des problèmes tels que « Failed to set DNS configuration » signalés par un service appelé unbound-resolvconf (disponible sur certaines distributions), vous pouvez arrêter, désactiver ou masquer ce service en toute sécurité.

Ceci n’est nécessaire que si :

  • Vous avez déjà configuré systemd-resolved avec succès.
  • La commande dig fonctionne comme prévu.

Pour désactiver l’exécution du service unbound-resolvconf :

1
sudo systemctl disable unbound-resolvconf.service

En cas de succès, le système d’exploitation doit utiliser notre instance Unbound par défaut. Un test rapide sans spécifier l’adresse du serveur Unbound devrait donner le même résultat que celui indiqué ci-dessus (avec @127.0.0.1).

1
dig example.com

Ici, nous demandons à l’outil dig de rechercher l’adresse IP, par exemple.com. Nous n’avons pas précisé où Dig doit poser cette question, elle est donc transmise au résolveur par défaut de la machine.

1
dig example.com

Cela devrait ressembler à l’IP 127.0.0.1 spécifiée précédemment.

1
;; SERVER: 127.0.0.1#53(127.0.0.1)

Unbound

Pour l’installation complète Unbound qui ajoute la mise à jour des serveurs “racine”, le blocage des publicités et des DMP (Data Management Platforms), voir lien Résolveur DNS Unbound

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 5353.

Créer le fichier de configuration /etc/unbound/unbound.conf.d/unbound-xoyaz.conf avec le contenu suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
    interface: ::1

    port: 5353

    # support IPv4
    do-ip4: yes
    # support IPv6
    do-ip6: yes
    # support udp
    do-udp: yes
    # support tcp
    do-tcp: yes

    # Lancer sous forme de Daemon
    do-daemonize: yes

    # 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)
    # Pour mieux protéger la vie privée
    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

Vérifier la validité du fichier de configuration avec la commande suivante :

1
sudo unbound-checkconf /etc/unbound/unbound.conf.d/unbound-xoyaz.conf

unbound-checkconf: no errors in /etc/unbound/unbound.conf.d/unbound-xoyaz.conf

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

Démarrer et activer le résolveur.

1
sudo systemctl enable  unbound --now

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.

1
dig @127.0.0.1 -p 5353 A afnic.fr  # IPV4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; <<>> DiG 9.20.18-1~deb13u1-Debian <<>> @127.0.0.1 -p 5353 A afnic.fr
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12063
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
afnic.fr.		600	IN	A	51.178.83.21

;; Query time: 424 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1) (UDP)
;; WHEN: Tue Jan 27 08:59:22 CET 2026
;; MSG SIZE  rcvd: 53
1
dig @127.0.0.1 -p 5353 AAAA afnic.fr  # IPV6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; <<>> DiG 9.20.18-1~deb13u1-Debian <<>> @127.0.0.1 -p 5353 AAAA afnic.fr
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62073
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
afnic.fr.		600	IN	AAAA	2001:41d0:404:200::2df6

;; Query time: 8 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1) (UDP)
;; WHEN: Tue Jan 27 09:01:09 CET 2026
;; MSG SIZE  rcvd: 65

Une réponse est bien renvoyée. Le résolveur fonctionne.Vérifier que tout est opérationnel en IPv4, et en utilisant UDP et TCP.

1
2
dig +notcp @127.0.0.1 -p 5353 A afnic.fr  # connexion UDP en IPv4 au résolveur
dig +tcp @127.0.0.1 -p 5353 A afnic.fr    # connexion TCP en IPv4 au résolveur

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

Frontal DNS (dnsdist)


dnsdist est un répartiteur de charge pour serveurs DNS avec la particularité de gérer DoH et DoT. Le but est donc de l’installer sur la même machine qu’Unbound et de le mettre devant : Unbound n’écoutera que localement et dnsdist, lui, sera ouvert au public

DNS DoT DoH

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 (encapsulation du protocole DNS dans une session TLS pour DoT ou HTTPS pour DoH.)

DNS

Les requêtes DNS sont envoyées en texte brut, ce qui signifie que tout le monde peut les lire. Le DNS sur HTTPS et le DNS sur TLS chiffrent les requêtes et les réponses du DNS pour que la navigation des utilisateurs reste sécurisée et privée. Cependant, les deux approches ont leurs avantages et leurs inconvénients.

DNS sur HTTPS et le DNS sur TLS

Le DNS sur TLS et le DNS sur HTTPS</u> sont deux normes développées pour le chiffrement du trafic DNS en texte brut afin d’empêcher les parties malveillantes, les annonceurs, les FAI et autres de pouvoir interpréter les données. Pour poursuivre l’analogie, ces normes visent à enfermer les cartes postales envoyées par courrier dans une enveloppe, pour que quiconque puisse envoyer une carte postale sans craindre les indiscrétions d’un tiers.

DoH vs DoT
Outre DNS sur HTTPS, il existe un autre protocole qui vise également à chiffrer les requêtes DNS. C’est ce qu’on appelle DNS sur TLS (DoT).
Pour les personnes vivant dans des pays où la censure d’Internet est sévère, il est plus avantageux d’utiliser DoH.

  • DoT fonctionne sur le port TCP 853 , qui peut être facilement bloqué par un pare-feu national.
  • DoH fonctionne sur le port TCP 443 , qui est le port standard pour les sites Web HTTPS, ce qui rend DoH très difficile à bloquer, car si le port TCP 443 est bloqué, alors presque tous les sites Web HTTPS seront également bloqués.
  • DoH permet aux applications Web d’accéder aux informations DNS via les API de navigateur existants, de sorte qu’aucun résolveur de stub n’est nécessaire.

Installer dnsdist

Installation et configuration d’un frontal DoT/DoH qui transmettra les requêtes DNS à un résolveur local écoutant sur le port 5353 de l’interface local 127.0.0.1 (dnsdist se trouve être une très bonne solution pour remplir ce rôle.).

1
sudo apt install dnsdist

Version

1
2
3
4
dnsdist --version

dnsdist 1.9.10 (Lua 5.1.4 [LuaJIT 2.1.1737090214])
Enabled features: AF_XDP cdb dns-over-tls(openssl) dns-over-https(nghttp2) dnscrypt ebpf fstrm ipcipher libedit libsodium lmdb protobuf re2 recvmmsg/sendmmsg snmp systemd

Pour une utilisation dns doh et dot, il faut ouvrir les ports tcp 53, 443 et 853

1
2
3
sudo ufw allow dns
sudo ufw allow https
sudo ufw allow 853/tcp

Status: sudo ufw status

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Status: active

To                         Action      From
--                         ------      ----
55045/tcp                  ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
54254/udp                  ALLOW       Anywhere                  
DNS                        ALLOW       Anywhere                  
853/tcp                    ALLOW       Anywhere                  
55045/tcp (v6)             ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             
54254/udp (v6)             ALLOW       Anywhere (v6)             
DNS (v6)                   ALLOW       Anywhere (v6)             
853/tcp (v6)               ALLOW       Anywhere (v6)             

Configurer dnsdist

Créer le fichier de configuration IPV4 /etc/dnsdist/dnsdist.conf pour une utilisation avec les certificats qui seront générés par acme dans le dossier /etc/dnsdist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
-- le resolveur 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)"})

-- DNSdist écoute sur port 53 pour DNS classique
setLocal("51.254.133.45:53", {})

-- configuration de DoT
addTLSLocal("51.254.133.45:853", "/etc/dnsdist/dns-server.pem", "/etc/dnsdist/dns-server.key", {
 minTLSVersion="tls1.2"
})
addTLSLocal("[2001:41d0:305:2100::f148]:853", "/etc/dnsdist/dns-server.pem", "/etc/dnsdist/dns-server.key", {
 minTLSVersion="tls1.2"
})

-- configuration de DoH
addDOHLocal("51.254.133.45:443", "/etc/dnsdist/dns-server.pem", "/etc/dnsdist/dns-server.key", "/dns-query", {
 minTLSVersion="tls1.2",
 reusePort=true 
})
addDOHLocal("[2001:41d0:305:2100::f148]:443", "/etc/dnsdist/dns-server.pem", "/etc/dnsdist/dns-server.key", "/dns-query", {
 minTLSVersion="tls1.2",
 reusePort=true 
})

-- Configuration de sécurité
setMaxTCPClientThreads(20)
setMaxTCPQueriesPerConnection(20)
setMaxTCPConnectionDuration(30)

-- Désactiver le sondage de sécurité via DNS 
setSecurityPollSuffix("")

-- Cache pour améliorer les performances
pc = newPacketCache(10000, {
    maxTTL=86400,
    minTTL=60,
    temporaryFailureTTL=60,
    staleTTL=60
})
getPool(""):setCache(pc)

print("DNSdist configuration loaded - DoH on port 443, DoT on port 853")

-- Accès console de dnsdist
setKey("secret")
controlSocket("127.0.0.1:5199")

Pour créer le secret: openssl rand -base64 32

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

L’option setSecurityPollSuffix("") a été ajoutée pour contourner l’erreur suivante :
Error while retrieving the security update for version dnsdist-1.6.1: Unable to get a valid Security Status update

Explication : Le paquet Debian pour dnsdist désactive l’interrogation de sécurité en lui attribuant une chaîne vide dans le fichier de configuration par défaut. Nous devons faire de même pour le fichier dnsdist.conf afin que l’interrogation de sécurité soit désactivée et que le journal systemd de dnsdist reste propre.

Vérifier que le fichier de configuration est valide avec la commande :

1
2
3
4
sudo dnsdist --check-config

DNSdist configuration loaded - DoH on port 443, DoT on port 853
Configuration '/etc/dnsdist/dnsdist.conf' OK!

dnsdist est 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 unbound écoutant le port 5353 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

1
grep dnsdist /etc/group

_dnsdist:x:105:

Avec le protocole de création des certificats Acme
Autoriser les droits en écriture à l’utilisateur sur le dossier /etc/dnsdist

1
2
3
4
5
6
# Vérifier à quel groupe appartient l'utilisateur
# id --> uid=1000(userb) gid=1000(debian)
# ajout utilisateur au groupe _dnsdist
sudo usermod -a -G _dnsdist $USER
# droits _dnsdist, utilisateur appartient au groupe debian
sudo chown $USER:_dnsdist -R /etc/dnsdist

Certificat Let’s Encrypt

LetsEncrypt.png

Prérequis

1
2
3
4
5
# Installer cron
sudo apt install cron
# Désactiver exim
sudo systemctl stop exim4
sudo systemctl disable exim4

Droits utilisateur pour copier les certifictas dans le dossier /etc/dnsdist
L’utitlisateur userb fait parti du groupe debian

1
2
sudo chown _dnsdist:debian -R /etc/dnsdist
sudo chmod 775 -R /etc/dnsdist

Acme.sh Suivre la procédure Acme.sh - Certificats Let’s Encrypt

Installer acme

1
2
3
4
# Git
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install

Fermer puis réouvrir la session

Génération des certificats

1
2
3
acme.sh --dns dns_ovh --server letsencrypt \
 --issue --keylength ec-384 \
 -d 'xoyaz.xyz' -d '*.xoyaz.xyz'

Installation certificats dans les dossiers

1
2
3
4
acme.sh --install-cert -d xoyaz.xyz --ecc \
 --key-file /etc/dnsdist/dns-server.key \
 --fullchain-file /etc/dnsdist/dns-server.pem \
 --reloadcmd "sudo chown _dnsdist -R /etc/dnsdist/dns-server.* && sudo systemctl restart dnsdist.service"

Lors de l’exécution --cron, tout nouveau certificat sera automatiquement installé, et le reloadcmd sera exécuté.

--cron installera automatiquement les certificats sur les informations de renouvellement réussies. Il semble se baser sur la dernière fois que vous avez exécuté --install-cert, alors assurez-vous que vous exécutez manuellement au moins une fois pour être sûr que cron job fonctionnera comme prévu.

Renouvellement automatique

Le cron job crontab -l

1
21 18 * * * "/home/ouestyan/.acme.sh"/acme.sh --cron --home "/home/ouestyan/.acme.sh" > /dev/null

Ports en écoute

Vérifier unbound en écoute sur le port 53

1
2
3
4
ss -tlnp | grep :53

LISTEN 0      256                     127.0.0.1:5353       0.0.0.0:*          
LISTEN 0      256                         [::1]:5353          [::]:*          

Vérifier les ports en écoute

1
ss -tulnp |grep ":53 "
1
2
3
4
5
6
udp   UNCONN 0      0                   51.254.133.45:53         0.0.0.0:*    users:(("dnsdist",pid=915,fd=7))         
udp   UNCONN 0      0                       127.0.0.1:53         0.0.0.0:*    users:(("unbound",pid=811,fd=3))         
udp   UNCONN 0      0                           [::1]:53            [::]:*    users:(("unbound",pid=811,fd=5))         
tcp   LISTEN 0      4096                51.254.133.45:53         0.0.0.0:*    users:(("dnsdist",pid=915,fd=10))        
tcp   LISTEN 0      256                     127.0.0.1:53         0.0.0.0:*    users:(("unbound",pid=811,fd=4))         
tcp   LISTEN 0      256                         [::1]:53            [::]:*    users:(("unbound",pid=811,fd=6))         

Consultation des logs

1
2
3
4
5
6
7
8
# Logs DNSdist en temps réel
journalctl -u dnsdist -f

# Logs unbound en temps réel
journalctl -u unbound -f

# Logs des erreurs uniquement
journalctl -u dnsdist -u unbound | grep -i error

Statistiques dnsdist

1
2
# Affichage des statistiques
echo "showServers();" | dnsdist -c -k "vGRMy/juaM2Qu8NwXDPoxYPEGtJZgJGk+p3WSBicbJo="

Résultat

1
2
3
4
DNSdist configuration loaded - DoH on port 443, DoT on port 853
#   Name                 Address                                      State     Qps    Qlim        Ord         Wt    Queries   Drops Drate   Lat   TCP Outstanding Pools
0   Unbound (local)      127.0.0.1:53                                    up     0.0       0          1          1          1       0   0.0   0.3     -           0 
All                                                                             0.0                                        1       0                               

Test DNS DOT DOH avec kdig

Article original

kdig est un utilitaire en ligne de commande issu de la suite Knot DNS, développé par le registre CZ.NIC. Il se présente comme une alternative moderne au traditionnel dig (issu de BIND9). Son intérêt principal réside dans la prise en charge des protocoles DNS sécurisés (DNSSEC, DoT, DoH) et une sortie en JSON facilitant l’automatisation.

Info dig kdig
Présentation Outil historique issu de BIND9, répandu et fiable. Outil moderne fourni par Knot DNS (CZ.NIC).
Fonctionnalités Résolution classique (A, AAAA, MX, etc.), support DNSSEC basique. Support avancé DNSSEC, sortie JSON (+json), ergonomie moderne.
Protocoles supportés DNS (UDP/TCP). DNS + DNSSEC + DoT (DNS over TLS) + DoH (DNS over HTTPS).
Installation Souvent installé par défaut avec BIND utils. Nécessite le paquet knot-dnsutils (Debian/Ubuntu) ou knot (Arch/Fedora).
Usage conseillé Dépannage DNS quotidien, documentation universelle. Tests avancés de DNSSEC et DNS chiffrés, automatisation (JSON).

Installation

1
sudo apt install knot-dnsutils

Exemples d’utilisation

1
2
3
4
5
6
7
8
# Requête classique
kdig A example.com
# Résolution AAAA avec sortie JSON
kdig +json example.com AAAA
#Tester le résolveur DoH (DNS over HTTPS)
kdig +https @doh.xoyaz.xyz#443 example.com A
# Tester e résolveur DoT (DNS over TLS)
kdig +tls @dot.xoyaz.xyz example.com AAAA

Test DNS-over-TLS

1
2
# IPV4
kdig +tls @dot.xoyaz.xyz yannir.xyz A
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP384R1-SHA384)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 53799
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; yannir.xyz.         		IN	A

;; ANSWER SECTION:
yannir.xyz.         	3600	IN	A	144.91.89.149

;; Received 55 B
;; Time 2026-04-29 20:20:04 CEST
;; From 2001:41d0:305:2100::f148@853(TLS) in 14.9 ms
1
2
# IPV6
kdig +tls @dot.xoyaz.xyz yannir.xyz AAAA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP384R1-SHA384)-(AES-256-GCM)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 28100
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; yannir.xyz.         		IN	AAAA

;; ANSWER SECTION:
yannir.xyz.         	3600	IN	AAAA	2a02:c207:2278:6143::1

;; Received 67 B
;; Time 2026-04-29 20:21:36 CEST
;; From 2001:41d0:305:2100::f148@853(TLS) in 13.0 ms

Test DNS-over-HTTPS

1
2
# IPV4
kdig +https @doh.xoyaz.xyz yannir.xyz A
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP384R1-SHA384)-(AES-256-GCM)
;; HTTP session (HTTP/2-POST)-([2001:41d0:305:2100::f148]/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; yannir.xyz.         		IN	A

;; ANSWER SECTION:
yannir.xyz.         	3445	IN	A	144.91.89.149

;; Received 55 B
;; Time 2026-04-29 20:22:39 CEST
;; From 2001:41d0:305:2100::f148@443(HTTPS) in 3.8 ms
1
2
# IPV6
kdig +https @doh.xoyaz.xyz yannir.xyz AAAA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;; TLS session (TLS1.3)-(ECDHE-X25519)-(ECDSA-SECP384R1-SHA384)-(AES-256-GCM)
;; HTTP session (HTTP/2-POST)-([2001:41d0:305:2100::f148]/dns-query)-(status: 200)
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 0
;; Flags: qr rd ra ad; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 1

;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR

;; QUESTION SECTION:
;; yannir.xyz.         		IN	AAAA

;; ANSWER SECTION:
yannir.xyz.         	3490	IN	AAAA	2a02:c207:2278:6143::1

;; Received 67 B
;; Time 2026-04-29 20:23:26 CEST
;; From 2001:41d0:305:2100::f148@443(HTTPS) in 4.9 ms

Configuration des clients

Firefox

  1. Taper about:config dans la barre d’adresse
  2. Chercher network.trr.mode et définisser à 2
  3. Chercher network.trr.uri et définisser à https://doh.iceyan.xyz/dns-query

Chrome

1
2
# Lancement avec DoH
google-chrome --dns-over-https-server=https://dns.mondomaine.tld/dns-query

Android (DNS privé)

  1. Paramètres → Réseau et Internet → Avancé → DNS privé
  2. Sélectionner « Nom d’hôte du fournisseur DNS privé »
  3. Entrer : doh.xoyaz.xyz

Cet article est sous licence CC BY 4.0 par l'auteur.