Il n'est plus nécessaire de présenter pi-hole.net tant cet outil rends le contrôle et la réduction des trackers/publicité facile.
En migrant mon instance pi-Hole vers docker, je me suis heurté à un soucis imprévu, l'image officielle ne contient pas de serveur “upstream” intégré (c'est en discussion pour une future révision); elle est parfaitement fonctionnelle avec des DNS upstream tel que google, quad9, cloudflare, mais si l'on veut réellement être indépendant, il manque son propre référentiel.
il existe des images Pihole modifiées, mais celle-ci peuvent ne pas suivre la cadence d'update ou contenir des packages en plus que l'on ne désire pas.
Avec docker, il est très facile d'ajouter un container “unbound” et de le configurer en serveur upstream, pour ensuite faire pointer pi-Hole sur ce container.
Le stack doit être basé sur des images officielles et maintenues, pour l'image de pi-hole, c'est facile, ça sera l'image officielle, pour ce qui est unbound, il y a un peu plus de choix; j'ai choisis celle de Matthew Vance.
J'ai décidé de composer mon propre “stack” pour lier les deux containers tout en gardant une configuration un peu particulière: je veux que le serveur unbound soit sur un port différent : 5335 du serveur dns.
Les raisons sont multiples, mais la plus évidente est d'éviter que unbound soit publier par accident sur le réseau (ce DNS serveur n'est absolument pas filtré et peut donc présenter des risques importants).
pour parvenir a ce résultat, il va falloir modifier les configurations du serveur unbound, mais aussi de modifier le healthcheck de ce container.
cette architecture est décrite dans le fichier compose (en fin d'article), mais il est important de préciser quelques paramètres, notamment votre timezone pour les deux containers.
dans la partie service “unbound”:
environment: - "TZ=Europe/Brussels"
dans la partie service “pi-hole”, il convient également de préciser le mot de passe de votre pi-hole, sans quoi pi-hole génèrera un mot de passe aléatoire qu'il faudra retrouver dans les logs.
environment: - "TZ=Europe/Brussels" - "WEBPASSWORD=[MONPASSWORD]"
Le container de Matthew contient tout ce qu'il faut pour avoir un unbound serveur avec un résolveur privé et un indicateur de healthcheck
.
Par défaut l'image de Matthew utilise les résolvers de cloudflare, ce qui ne me convient pas; le serveur “écoute” sur le port udp:53 (port par défaut des DNS) et docker vérifie la santé du container en testant ce même port, il conviendra donc de modifier ces paramètres en éditant les fichiers de configuration qui sont stocké dans un volume persistant:
volumes: - "unbound-etc:/opt/unbound/etc/unbound"
Nous allons donc modifier certains fichiers “par défaut” de Matthew.
Je me suis inspiré de la documentation de pi-Hole concernant l'usage de unbound comme résolveur.
on va surtout modifier les paramètres d'écoute du serveur, en remplaçant le binding localhost 127.0.0.1
par tout les interfaces 0.0.0.0
et en vérifiant le port d'écoute 53
# Listen to for queries from clients and answer from this network interface # and port. interface: 0.0.0.0 port: 53 do-ip4: yes do-udp: yes do-tcp: yes # May be set to yes if you have IPv6 connectivity do-ip6: yes
Ces paramètres sont également a configurer dans le fichier compose, pour valider le healthcheck:
healthcheck: test: drill @127.0.0.1 -p 53 cloudflare.com || exit 1 interval: 30s timeout: 30s retries: 3 start_period: 10s
On va également vérifier et adapter les droits d'accès a notre serveur DNS:
########################################################################### # SECURITY SETTINGS ########################################################################### # Only give access to recursion clients from LAN IPs access-control: 127.0.0.1/32 allow access-control: 192.168.0.0/16 allow access-control: 172.16.0.0/12 allow access-control: 10.0.0.0/8 allow # access-control: fc00::/7 allow # access-control: ::1/128 allow
On va retirer la référence au “forwarder” de Matthew, en commentant l'inclusion du fichier:
########################################################################### # FORWARD ZONE ########################################################################### #include: /opt/unbound/etc/unbound/forward-records.conf
j'invite le lecteur a aller consulter ce fichier, il contient énormément d'informations et de proposition de DNS externes assez détaillés. vous y trouverez plusieurs classifications de serveurs sources déjà filtrés (malware, adulte, etc.) ainsi que d'autres forwarder (quad9, etc.)
Pour ma facilité de test (et ne pas de voir a chaque fois redémarrer le container complétement, j'ai autorisé le contrôle, mais en production ce paramètre peut être laissé par défaut sur no
:
remote-control: control-enable: yes
Pour accéder à l'interface de Pi-Hole, il suffit de se connecter via un browser (en http) sur l'ip du host docker en précisant le port (8053) et l'uri /admin (par exemple: http://192.168.1.253:8053/admin), vous serez accueilli par une page de login:
il suffit de référencé votre mot de passe, et de se connecter, et de directement aller vers les “settings”, “DNS”:
Par défaut, Pi-Hole ne réponds que aux clients situé sur le même réseau et sub-net (172.20.x.x), il transmet ensuite les requêtes aux serveurs de Google, ces paramètres ne conviennent pas, mais nous allons les changer:
172.20.0.200
; (si vous changer le port de unbound
le format devient x.x.x.x#port
, ce format est très important).Permit all origins
, (Respond only on interface eth0
est sans doute suffisant, à vous de tester).Il nous suffit de configurer les clients pour utiliser ce serveur DNS Pi-Hole.
networks: infrastructure: external: true name: "infrastructure" services: unbound: command: - "/unbound.sh" healthcheck: test: drill @127.0.0.1 cloudflare.com || exit 1 interval: 30s timeout: 30s retries: 3 start_period: 10s container_name: dns_unbound environment: - "PATH=/opt/unbound/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - "NAME=unbound" - "SUMMARY=is a validating, recursive, and caching DNS resolver." - "DESCRIPTION=is a validating, recursive, and caching DNS resolver." - "TZ=Europe/Brussels" expose: - "5335/tcp" - "5335/udp" hostname: "97b5d3c8a2cc" image: "mvance/unbound:latest" ipc: "private" labels: maintainer: "Matthew Vance" org.opencontainers.image.description: "a validating, recursive, and caching DNS resolver" org.opencontainers.image.licenses: "MIT" org.opencontainers.image.source: "https://github.com/MatthewVance/unbound-docker" org.opencontainers.image.title: "mvance/unbound" org.opencontainers.image.url: "https://github.com/MatthewVance/unbound-docker" org.opencontainers.image.vendor: "Matthew Vance" org.opencontainers.image.version: "" logging: driver: "json-file" options: {} networks: infrastructure: ipv4_address: 172.20.0.200 restart: "unless-stopped" volumes: - "unbound-etc:/opt/unbound/etc/unbound" working_dir: "/opt/unbound" dns-pihole: container_name: dns_pihole entrypoint: - "/s6-init" environment: - "PATH=/opt/pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - "phpver=php" - "PHP_ERROR_LOG=/var/log/lighttpd/error-pihole.log" - "IPv6=True" - "S6_KEEP_ENV=1" - "S6_BEHAVIOUR_IF_STAGE2_FAILS=2" - "S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0" - "FTLCONF_LOCAL_IPV4=0.0.0.0" - "FTL_CMD=no-daemon" - "DNSMASQ_USER=pihole" - "TZ=Europe/Brussels" - "WEBPASSWORD=[MONPASSWORD]" hostname: "pi-Hole" image: "pihole/pihole:latest" ipc: "private" labels: org.opencontainers.image.created: "2024-06-16T19:54:20.386Z" org.opencontainers.image.description: "Pi-hole in a docker container" org.opencontainers.image.licenses: "NOASSERTION" org.opencontainers.image.revision: "4149693092ea364c7aab6c30ba0b308e4bc45716" org.opencontainers.image.source: "https://github.com/pi-hole/docker-pi-hole" org.opencontainers.image.title: "docker-pi-hole" org.opencontainers.image.url: "https://github.com/pi-hole/docker-pi-hole" org.opencontainers.image.version: "2024.06.0" logging: driver: "json-file" options: {} networks: infrastructure: ipv4_address: 172.20.0.201 ports: - "53:53/tcp" - "53:53/udp" - "8053:80/tcp" restart: "unless-stopped" volumes: - "pihole_config:/etc/pihole" - "pihole_dnsmasq:/etc/dnsmasq.d" volumes: unbound-etc: pihole_config: pihole_dnsmasq: