![]()
J’utilise Pi-hole depuis quelque temps déjà, à la fois comme serveur DNS et serveur DHCP, le tout dans un container Docker, et ça fonctionne parfaitement. Voir cet article pour l’installation en mode Docker qui nécessite un paramétrage réseau particulier pour que le serveur DHCP fonctionne sur mon LAN (adaptateur macvlan).
Le blocage des pubs est assez efficace, je vois clairement une différence quand je suis à la maison ou quand je suis à l’extérieur ! Et pour la TV, c’est vraiment très utile, ces smartTVs étant extrêmement “bavardes” (c’est assez incroyable d’ailleurs). On arrive même à bloquer les pubs syr le Replay sur certaines chaînes. J’aurais bien du mal à me passer d’un tel service désormais !
Mais voilà, après les pubs, un nouveau problème devient de plus en plus préoccupant : les DNS menteurs. On voit beaucoup d’articles passer à ce sujet, avec des décisions de justice forçant les fournisseurs de service DNS à bloquer certaines adresses. Et donc récemment, c’est Quad9 qui s’est fendu d’un communiqué Ce n’est qu’un au revoir, la France pour expliquer qu’il ne fournirait plus son service aux utilisateurs localisés en france. C’est bien dommage, parce que c’était celui que j’utilisais.
Il fallait donc s’adapter à ce nouveau problème, et la meilleure façon d’y parvenir est apparemment d’utiliser Unbound pour la résolution DNS. Couplé avec Pi-hole, on arrive à un truc pas mal. J’ai commencé par lire la page de documentation de Pi-hole sur Unbound qui est vraiment très complète, et mérite d’être lue pour bien comprendre le sujet.
Cet article va donc expliquer brièvement le principe de la résolution DNS, et comment fonctionne Unbound, puis présentera l’installation des deux composants Pi-hole et Unbound en un seul container, afin d’en simplifier la mise en œuvre.
DNS
La résolution DNS, c’est la base de toute requête sur internet : il s’agit de transformer un nom en une adresse. En d’autres termes, c’est l’annuaire de l’internet. Si vous n’obtenez pas l’adresse, vous n’accédez pas au site. C’est aussi simple que ça.
Internet est structuré avec une arborescence de serveurs DNS, chaque type ayant un rôle bien défini :
- Root : ce sont les serveurs DNS racines, le point de départ qui donne l’adresse des serveurs TLD.
- TLD : ce sont les serveurs DNS de premier niveau (TLD) qui gèrent les extensions de type
.com,.net,.org,.bzh, etc… - Authoritative : ce sont les serveurs finaux qui détiennent l’autorité et les enregistrements finaux sur le domaine interrogé.

À cette organisation, il faut ajouter le serveur DNS qui répond à vos demandes, qui est un DNS Récursif. Par défaut, c’est celui de votre fournisseur internet (FAI) défini via votre Box. Mais vous pouvez en définir un autre, comme celui de Google, de Cloudflare, d’OpenDNS, etc… La liste est longue, voir la page de Sebsauvage à ce sujet.
NoteSi votre box le permet, c’est très facile de changer le DNS à ce niveau pour tout votre réseau local. Dans le cas contraire, on peut le modifier manuellement sur chaque poste, ou monter un serveur comme Pi-hole qui fera office de serveur DHCP+DNS.
Le rôle du DNS récursif est de servir de relais entre l’organisation DNS proprement dite, afin de limiter le trafic et d’optimiser les performances. C’est lui qui interroge à votre place les vrais serveurs, et il conserve les réponses en mémoire (cache) afin d’éviter des demandes redondantes. On voit vite que c’est le point central de toute la résolution, puisque tout passe par lui :

ImportantOn voit que le serveur DNS récursif, que ce soit celui de votre fournisseur ou celui que vous avez défini, occupe une position stratégique, puisque tout passe par lui (principe du man in the middle attack).
Dès lors, quand des fournisseurs de services DNS vous proposent des services DNS gratuits et “privés”, qui vous dit qu’ils vont tenir leurs promesses, que ce soit en terme d’authenticité des réponses (faux sites) ou de traçage de votre navigation à des fins commerciales ? Le choix d’un DNS alternatif ne doit donc pas être fait à la légère.
Dès lors, la bonne question à se poser c’est : QUI PEUT-ON CROIRE ? (Whom can you trust?)
AttentionC’est aussi le type de serveur dédormais ciblé par les récentes décisions de justice prises suite aux plaintes d’acteurs comme beIN, Canal+ ou Ligue1+ pour bloquer les offres de streaming et autres IPTV qui les empêchent (disent-ils) de générer plus de revenus : les pauvres, on les plaint, c’est vrai que le football manque cruellement d’argent ! 🤑.
D’autant que ces décisions de justice bloquent des sites tout à fait légitimes comme c’est arrivé récemment en Espagne, puisque une adresse IP peut héberger plusieurs type de contenu grâce au CDN, comme le fait Cloudflare par exemple.
Et pour ceux (comme Quad9) qui ont une réputation solide, une vraie éthique, avec la volonté d’offrir un service neutre et passif, comme le veut la philosophie d’internet, ces décisions de justice les obligent à ne plus fournir leurs services en France (voir le communiqué de Quad.9). Il va sans dire que les DNS récursifs des FAI français (Orange, Bouygues, Free, SFR) se plient d’entrée à ces décisions de justice, ils n’ont d’ailleurs guère le choix.
Bref, il fallait faire quelque chose.
Unbound

Historiquement, le logiciel DNS issu du monde UNIX, le plus utilisé sur Internet, s’appelle BIND. Il est sait tout faire, et peut être très complexe à paramétrer. Sa première version date de 1984.
Unbound (jeu de mot par rapport à BIND vous l’aurez noté, classique de l’humour de geek 😄) a été créé en 2004 par NLnet Labs comme une alternative moderne, légère, et axée sur la sécurité (validation DNSSEC). C’est un DNS exclusivement récursif qui va donc remplacer celui que vous utilisez. Il fera lui-même les requêtes aux DNS Root, TLS et Authoritative.

DNSSEC
ImportantDNSSEC permet de s’assurer que la réponse est authentique en y ajoutant une signature numérique. Il est important de noter que ces requêtes ne sont pas chiffrées.
Si DNSSEC assure l’authenticité de la réponse, il ne chiffre pas les requêtes DNS, celles-ci passent en clair, et ceci pour une bonne raison : ces requêtes DNS aux root serveurs doivent s’effectuer sur le port UDP 53, non chiffré (cela fait partie des spécifications). Votre fournisseur internet peut donc savoir à quels sites vous accédez, mais rien d’autre puisque de nos jours, le contenu d’une communication est chiffré avec HTTPS.
Chiffrement DOT - DOH
Il est néanmoins possible de chiffrer ses requêtes DNS (que ce soit avec DOT ou DOH), mais dans ce cas Unbound n’a plus vraiment d’utilité puisque vous devrez alors interroger un autre DNS récursif qui fera lui-même les requêtes aux serveurs root (et à qui vous devrez faire confiance). On revient donc au problème de départ, sauf que nos communications avec le serveur DNS sont désormais chiffrées et votre FAI ne peut plus les voir. Sachant que votre FAI voit passer les adresses IP des sites auxquels vous accédez une fois la résolution d’adresse effectuée, cela ne change pas grand chose, et je ne suis pas vraiment convaincu de l’utilité du chiffrement.
ImportantIl faut donc simplement choisir la solution qui vous convient le mieux, et éviter de tomber dans la paranoïa. Disons que c’est soit Unbound pour accéder au root serveurs directement, soit le chiffrement des requêtes en faisant confiance à un résolveur DNS alternatif.
En ce qui me concerne, c’est surtout l’authenticité des réponses DNS qui m’importe, et Unbound répond très bien à cette problématique.
Docker
J’ai choisi le dépôt de mpgirro/docker-Pi-hole-unbound qui me paraît le mieux maintenu et le plus à jour. Comme j’avais déjà un serveur Pi-hole configuré en mode Docker, j’ai comparé les deux fichiers compose.yaml : celui proposé par docker-Pi-hole-unbound (ici), et celui que j’utilisais, correctement configuré pour remplir également le rôle de serveur DHCP (macvlan). Et j’ai ajouté/modifié à ce dernier les entrées pertinentes, ce qui donne désormais :
services:
Pi-hole-unbound:
container_name: Pi-hole-unbound
image: mpgirro/Pi-hole-unbound:latest
ports:
- 443:443/tcp
# DNS Ports
- 53:53/tcp
- 53:53/udp
# Default HTTP Port
- 80:80/tcp
# Default HTTPs Port. FTL will generate a self-signed certificate
- 443:443/tcp
# Uncomment the below if using Pi-hole as your DHCP Server
- 67:67/udp
# - ${Pi-hole_WEBPORT:-80}:${Pi-hole_WEBPORT:-80}/tcp #Allows use of different port to access Pi-hole web interface when other docker containers use port 80
# - 5335:5335/tcp # Uncomment to enable unbound access on local server
# - 22/tcp # Uncomment to enable SSH
environment:
# Set the appropriate timezone for your location (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), e.g:
- TZ=Europe/Paris
- Pi-hole_UID=996
- Pi-hole_GID=100
- ADMIN_EMAIL=user@mail.com
# Set a password to access the web interface. Not setting one will result in a random password being assigned
- FTLCONF_webserver_api_password=xxxxxxxx
- FTLCONF_webserver_interface_theme=${WEBTHEME:-default-light}
- FTLCONF_dns_revServers=${REV_SERVER:-false},${REV_SERVER_CIDR},${REV_SERVER_TARGET},${REV_SERVER_DOMAIN}
- FTLCONF_dns_upstreams=127.0.0.1#5335
- FTLCONF_dns_dnssec="true"
- FTLCONF_dns_listeningMode=single
# Volumes store your data between container upgrades
volumes:
# For persisting Pi-hole's databases and common configuration file
- /srv/dev-disk-by-uuid-xxxxx-yyyy-zzzz-7697ca5/AppData/Pi-hole/etc_Pi-hole-unbound:/etc/Pi-hole:rw
- /srv/dev-disk-by-uuid-xxxxx-yyyy-zzzz-7697ca5/AppData/Pi-hole/etc_Pi-hole_dnsmask-unbound.d:/etc/dnsmask.d:rw
cap_add:
- NET_ADMIN
restart: unless-stopped
networks:
macvlan-ntw:
ipv4_address: 192.168.x.y
networks:
macvlan-ntw:
external: true
volumes:
etc_Pi-hole-unbound: null
etc_Pi-hole_dnsmasq-unbound: null
Essentiellement, à part le nom et la source du container, ce sont les paramètres FTLCONF_dns_* qui font pointer Pi-hole sur Unbound.
Avec Dockge, j’ai tout simplement créé un nouveau container à partir de ce fichier. Puis j’ai arrêté mon container Pi-hole existant, et démarré ce nouveau Pi-hole-unbound. Auparavant, j’avais copié mes baux d’adresses statiques et je les ai collées dans le nouveau serveur. J’ai aussi ajouté les trois listes de filtrages que j’utilise, et c’est à peu près tout. Côté DNS dans Pi-hole, il n’y a rien à définir puisque Unbound l’est déjà dans le fichier compose.yaml : FTLCONF_dns_upstreams=127.0.0.1#5335, et que l’on retrouve via l’interface :

Pi-hole en HTTPS
J’en ai profité pour régler un problème qui traînait depuis ma première installation de Pi-hole. Quand j’accédais à l’interface graphique, j’étais obligé de créer une exception de sécurité pour pouvoir me connecter en HTTP et pas en HTTPS.
En fait, je n’ai aucun besoin extérieur de mon serveur Pi-hole, il n’est donc pas défini dans mon proxy. Je l’adresse habituellement par son adresse IP, soit 192.168.1.xx/admin/login. Et là, Firefox m’informe d’un risque de sécurité :

Il faut alors cliquer sur “Avancé”, et choisir “Accéder vers 192.168.1.xx (risqué)”. Cela crée une exception que Firefox mémorise, on peut donc considérer le problème comme résolu. Sauf que on aura toujours le petit message “Non sécurisé” dans la barre d’adresse, et que des navigateurs (comme Vanadium de GrapheneOS) ne permettent carrément pas ce type de contournement.
C’est en voyant le port 443 défini dans le fichier compose.yaml de Pi-hole-unbound que je me suis repenché là-dessus. Et j’ai vite trouvé la solution sur cette page où tout est très bien expliqué. J’ai choisi le plus simple, ajouter le certificat à Firefox, mon navigateur. Il est possible d’ajouter le certificat au niveau système, mais je n’ai pas creusé cette piste.
Depuis la v6, Pi-hole crée son propre certificat auto-signé pendant l’installation. Il suffit de le récupérer et de l’ajouter manuellement au navigateur. Comme j’utilise un container Docker, je le retrouve dans le volume déclaré :
NAS:>$ pwd
/srv/dev-disk-by-uuid-xxxxx-yyyy-zzzz-7697ca5/AppData/Pi-hole/etc_Pi-hole-unbound
NAS:>$ ls tls*
tls_ca.crt tls.crt tls.pem
C’est le fichier tls_ca.crt qui nous intéresse, et qu’il faut récupérer puis ajouter à Firefox, dans “Paramètres - Vie privée et sécurité” puis “Sécurité logicielle et des connexions - Paramètres avancés”. Enfin, dans “Certificats - Gérer les certificats - Importer” et l’on va chercher notre fichier tls_ca.crt. On vérifie ensuite qu’il apparaît bien dans la liste :

ImportantPour que cela fonctionne, il faut que le serveur Pi-hole soit bien défini comme serveur DNS sur votre machine. Sinon le domaine
pi.holene sera pas reconnu. En effet, c’est le nom par défaut que s’attribue Pi-hole au démarrage, et qui est définin dans le fichierPi-hole.toml(dans le même dossier que les certificats):[webserver] # On which domain is the web interface served? # # Allowed values are: # A valid domain domain = "pi.hole"
Et voilà, le serveur pi.hole est désormais accessible en HTTPS en utilisant son nom de domaine (et non plus son adresse IP).

AstuceSur Android (GrapheneOS), c’est au niveau système qu’il faut ajouter le certificat : il faut aller dans les paramètres Système - Sécurité et confidentialité - Autres options de sécurité et confidentialité - Chiffrement et identifiants - Installer un certificat - Certificat CA.
Conclusion
Comme toujours avec Docker et l’aide de Dockge, le serveur a été très facile à mettre en œuvre. Et j’ai pu en profiter pour revoir un peu les principes de base d’une résolution DNS et me rafraîchr les idées.
Unbound apporte énormément de simplicité, puisqu’il n’y a rien à configurer de son côté ! Installé dans un même container avec Pi-hole, c’est vraiment une bonne solution. Et c’est l’assurance d’obtenir les adresses authentiques des sites, dans le pur esprit de l’internet libre, non censuré.
Et cerise sur le gâteau, je peux désormais accéder au serveur Pi-hole via HTTPS, ce que j’aurais du faire depuis longtemps.