Dans ce tutoriel, nous allons installer Pi-hole — un bloqueur de publicités et de trackers à l’échelle du réseau — puis le coupler à Unbound, un résolveur DNS récursif local. L’objectif : ne plus dépendre d’un serveur DNS tiers (Google, Cloudflare…) et avoir la main complète sur les résolutions DNS de ton réseau.

🔧 Prérequis

  • Un serveur ou machine sous Ubuntu 22.04 / Debian 12 (ici : labnathan)
  • Accès root ou sudo
  • Une IP statique sur la machine (obligatoire pour Pi-hole)
  • Connexion internet active

Partie 1 — Installation de Pi-hole

Étape 1 : Lancer l’installateur automatique

Pi-hole s’installe via un script officiel. Lance la commande suivante en root :

curl -sSL https://install.pi-hole.net | bash

L’installateur démarre. Un écran d’accueil te prévient que ton appareil va être transformé en bloqueur de publicités réseau. Clique sur Accepter pour continuer.

Étape 2 : Soutenir le projet

Un rappel s’affiche : Pi-hole est gratuit et open source, soutenu par les dons. Tu peux contribuer sur pi-hole.net/donate. Accepte et continue.

Étape 3 : IP statique obligatoire

Pi-hole étant un serveur DNS, il doit impérativement avoir une IP fixe. L’installateur te le rappelle à cette étape. Si ce n’est pas encore fait, configure une IP statique via ton DHCP (réservation par adresse MAC) ou directement dans le fichier réseau de la machine avant de continuer.

Étape 4 : Choisir un DNS upstream

L’installateur te demande quel serveur DNS utiliser en amont. Par défaut, Google est proposé. Dans notre cas, on utilisera Unbound — mais cette étape reste nécessaire pour l’installation initiale. Tu peux laisser Google pour l’instant, on remplacera ça juste après.

Étape 5 : Activer les listes de blocage

Pi-hole propose d’inclure la liste StevenBlack’s Unified Hosts List, une blocklist communautaire très complète. Accepte avec Oui — tu pourras en ajouter d’autres après l’installation.

Étape 6 : Activer le logging des requêtes

Le logging te permet de voir en temps réel toutes les requêtes DNS passant par Pi-hole — utile pour diagnostiquer ou analyser le trafic. Laisse sur Oui.

Étape 7 : Niveau de confidentialité FTL

Pi-hole propose 4 niveaux de confidentialité pour le moteur FTL (Faster Than Light) :

Pour un usage personnel avec visibilité maximale, laisse sur Show everything. L’installateur propose Anonymous mode par défaut — remonte sur 0 si tu veux tout voir dans le dashboard.

Étape 8 : Installation terminée !

L’installation se termine et affiche un récapitulatif :

💡 Tu peux changer le mot de passe plus tard avec : pihole -a -p

Partie 2 — Accès au dashboard Pi-hole

Ouvre ton navigateur et rends-toi sur http://192.168.122.127/admin (remplace par l’IP de ta machine). Tu arrives sur la page de connexion Pi-hole.

Une fois connecté, le dashboard s’affiche avec les statistiques en temps réel : requêtes totales, requêtes bloquées, pourcentage de blocage et nombre de domaines dans les listes.

Au premier démarrage, tout est à zéro — c’est normal, aucun client ne pointe encore vers Pi-hole.

Partie 3 — Installation d’Unbound

Unbound va remplacer le DNS upstream (Google/Cloudflare) par un résolveur local et récursif. Il interroge directement les serveurs racine du DNS mondial, sans passer par un intermédiaire. C’est la solution la plus respectueuse de la vie privée.

Installer Unbound

apt install unbound -y

Configurer Unbound pour Pi-hole

Crée le fichier de configuration dédié :

nano /etc/unbound/unbound.conf.d/pi-hole.conf

Colle-y la configuration suivante :

server:
    # --- INTERFACE ET PORT ---

    # Unbound écoute uniquement sur l'adresse locale (loopback)
    # Pi-hole contacte Unbound via 127.0.0.1, pas besoin d'écouter sur le réseau
    interface: 127.0.0.1

    # Port d'écoute d'Unbound — on évite le 53 (déjà pris par Pi-hole/FTL)
    # Pi-hole sera configuré pour envoyer ses requêtes sur ce port
    port: 5335

    # Activer la résolution en IPv4
    do-ip4: yes

    # Désactiver IPv6 (si tu n'as pas d'IPv6 sur ton réseau, laisse sur no)
    do-ip6: no

    # Autoriser les requêtes DNS via UDP (protocole standard, rapide)
    do-udp: yes

    # Autoriser les requêtes DNS via TCP (nécessaire pour les grosses réponses)
    do-tcp: yes


    # --- CONFIDENTIALITÉ ---

    # Ne pas révéler l'identité du serveur (réponse vide à "who are you ?")
    hide-identity: yes

    # Ne pas révéler la version d'Unbound installée
    hide-version: yes


    # --- SÉCURITÉ DNSSEC ---

    # Vérifier que les enregistrements "glue" (NS + IP associée) sont cohérents
    # Protège contre certaines attaques de cache poisoning
    harden-glue: yes

    # Rejeter les réponses qui suppriment silencieusement les données DNSSEC
    # Empêche un attaquant de "retirer" la validation DNSSEC d'une réponse
    harden-dnssec-stripped: yes

    # Désactive la randomisation de la casse des noms de domaine (0x20 encoding)
    # Certains serveurs DNS mal configurés rejettent les requêtes en casse mixte
    use-caps-for-id: no


    # --- PERFORMANCES RÉSEAU ---

    # Taille maximale des paquets EDNS (Extension DNS)
    # 1232 octets est la valeur recommandée depuis 2020 pour éviter la fragmentation
    edns-buffer-size: 1232

    # Précharger les entrées populaires dans le cache avant leur expiration (TTL)
    # Réduit la latence perçue pour les domaines fréquemment visités
    prefetch: yes

    # Nombre de threads de traitement parallèle
    # 1 suffit largement pour un usage domestique
    num-threads: 1


    # --- CACHE DNS ---

    # TTL minimum des entrées en cache (0 = respecter le TTL original du domaine)
    # Mettre une valeur > 0 force un cache plus long même si le domaine dit le contraire
    cache-min-ttl: 0

    # TTL maximum : une entrée ne restera jamais en cache plus de 86400s (24h)
    # Évite de garder des infos DNS obsolètes trop longtemps
    cache-max-ttl: 86400


    # --- CONTRÔLE D'ACCÈS ---

    # Seule l'adresse 127.0.0.1 (Pi-hole) est autorisée à interroger Unbound
    # /32 = une seule IP exacte, pas un sous-réseau
    access-control: 127.0.0.1/32 allow


    # --- DNSSEC ROOT HINTS ---

    # Fichier contenant les adresses des 13 serveurs DNS racine mondiaux
    # Téléchargeable via : wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
    # À mettre à jour tous les 6 mois environ
    root-hints: "/var/lib/unbound/root.hints"


    # --- LOGS ---

    # Niveau de verbosité des logs (0 = silencieux, 5 = très verbeux)
    # Laisser à 0 en production pour ne pas saturer les logs système
    verbosity: 0

Télécharger les root hints

wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root

Redémarrer Unbound

systemctl restart unbound
systemctl enable unbound

Vérifier qu’Unbound répond

Teste la résolution DNS via Unbound sur le port 5335 :

dig pi-hole.net @127.0.0.1 -p 5335

Si tout fonctionne, tu obtiens une réponse avec l’IP de pi-hole.net, le status NOERROR et un query time quasi nul (le cache entre en jeu dès la 2ème requête).

Partie 4 — Connecter Pi-hole à Unbound

Maintenant on dit à Pi-hole d’utiliser Unbound comme DNS upstream au lieu de Google.

Dans le dashboard, va dans Settings → DNS. Dans la section Custom DNS servers, entre :

127.0.0.1#5335

Décoche tous les serveurs prédéfinis (Google, Cloudflare, etc.) et clique sur Save & Apply.

Partie 5 — Vérification du blocage

Pour s’assurer que Pi-hole bloque bien les domaines publicitaires, teste avec nslookup en pointant vers Pi-hole :

nslookup doubleclick.net 192.168.122.127

Un domaine bloqué retourne l’adresse 0.0.0.0 (IPv4) et :: (IPv6) — ce qui signifie que la requête est bien interceptée et neutralisée par Pi-hole.

Partie 6 — Ajouter des listes de blocage supplémentaires

Pi-hole permet d’abonner ton installation à plusieurs blocklists communautaires. Dans le dashboard, va dans Lists.

Tu retrouves déjà la liste StevenBlack installée par défaut. Pour en ajouter d’autres, entre l’URL dans le champ Address et clique sur Add blocklist. Ici on ajoute la liste OISD (une excellente liste polyvalente) :

https://small.oisd.nl/

Une fois la liste ajoutée, un message vert de confirmation s’affiche.

Mettre à jour la base de données (gravity)

Après avoir ajouté de nouvelles listes, il faut reconstruire la base de blocage de Pi-hole :

pihole -g

Pi-hole télécharge et fusionne toutes les listes. Dans notre exemple, on passe à 144 420 domaines bloqués en combinant StevenBlack (87 771 domaines) et OISD (56 649 filtres ABP).

Partie 7 — Configurer les clients du réseau

Pour que Pi-hole intercepte réellement les requêtes DNS de tes appareils, tu dois leur dire d’utiliser l’IP de Pi-hole comme serveur DNS. Deux approches :

Option A — Via le routeur (recommandé)

Dans l’interface de ton box/routeur, remplace les DNS attribués par DHCP par l’IP de Pi-hole (192.168.122.127). Ainsi, tous les appareils du réseau en bénéficient automatiquement.

Option B — Par appareil

Configure manuellement le DNS dans les paramètres réseau de chaque appareil. Moins pratique mais utile pour tester sur un seul poste.

Récapitulatif de l’architecture

Voici le chemin d’une requête DNS dans cette configuration :

Appareil réseau

Pi-hole (port 53)
→ Domaine dans la blocklist ? → Réponse 0.0.0.0 (bloqué)
→ Domaine autorisé ?

Unbound (127.0.0.1:5335)
→ Résolution récursive directe auprès des serveurs racine

Réponse transmise à l'appareil

Commandes utiles

CommandeAction
pihole statusVérifie l’état de Pi-hole
pihole -gMet à jour la base de blocage (gravity)
pihole -a -pChange le mot de passe admin
pihole enableActive le blocage
pihole disable 300Désactive le blocage 300 secondes
systemctl restart unboundRedémarre Unbound
dig domain.com @127.0.0.1 -p 5335Test DNS via Unbound