Aller au contenu principal

Déploiement Infrastructure DNS - Technitium Clustering + AdGuard

Version 2.0 - Mise à jour avec Technitium Clustering (remplace Primary/Secondary classique)

🎯 Architecture cible

┌─────────────────────────────────────────────────────────────────┐
│ DHCP Configuration (Technitium Primary Node) │
│ DNS Primaire: 192.168.1.210 (jit-technitium - Primary Node) │
│ DNS Secondaire: 192.168.1.173 (technitium-truenas - Secondary) │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ LXC Proxmox 1 - Technitium Primary Node (192.168.1.210) │
│ Hostname: jit-technitium │
├─────────────────────────────────────────────────────────────────┤
│ - Rôle: Primary Node du Cluster + DHCP │
│ - Cluster: jit-dns-cluster │
│ - Zones avec wildcards: │
│ ├─ *.homelab.j-it.be → 192.168.1.212 │
│ ├─ *.nas.j-it.be → 192.168.1.173 │
│ └─ *.docker.j-it.be → 192.168.1.100 │
│ - Forwarder: 192.168.1.211 (AdGuard) │
│ - DHCP: Actif (distribue DNS 192.168.1.210 et 192.168.1.173) │
│ - Services publics: Forward → AdGuard → OVH DNS │
│ - Ports: 53 (DNS), 5380 (HTTP), 53443 (HTTPS Clustering) │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ LXC Proxmox 2 - AdGuard Home (192.168.1.211) │
│ Hostname: jit-adguard │
├─────────────────────────────────────────────────────────────────┤
│ - Rôle: Blocage publicitaire │
│ - Upstream: Cloudflare DoH, Google DoH │
│ - Forward vers Internet pour tout ce qui n'est pas bloqué │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ TrueNAS Docker - Technitium Secondary Node (192.168.1.173) │
│ Hostname: technitium-truenas │
├─────────────────────────────────────────────────────────────────┤
│ - Rôle: Secondary Node du Cluster (failover) │
│ - Cluster: jit-dns-cluster (rejoint automatiquement) │
│ - Synchronisation automatique complète depuis Primary Node: │
│ ├─ Zones (*.homelab, *.nas, *.docker) │
│ ├─ Settings │
│ ├─ Apps │
│ └─ Administration │
│ - Forwarder: 1.1.1.1, 8.8.8.8 (direct, pas AdGuard) │
│ - Services publics: Forward → Internet direct → OVH DNS │
│ - Ports: 53 (DNS), 5380 (HTTP), 53443 (HTTPS Clustering) │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ DNS OVH (Public) - Géré chez OVH │
├─────────────────────────────────────────────────────────────────┤
│ - n8n.j-it.be → IP_PUBLIQUE │
│ - portainer.j-it.be → IP_PUBLIQUE │
│ - traefik.j-it.be → IP_PUBLIQUE │
│ - www.j-it.be → IP_PUBLIQUE │
│ - (tous les services exposés publiquement) │
└─────────────────────────────────────────────────────────────────┘

📝 Note: Le Clustering Technitium synchronise TOUTE la configuration
automatiquement, pas seulement les zones DNS.

📋 Plan de déploiement

Phase 1 : Déploiement Proxmox (LXC)

1.1 Technitium DNS (LXC Primary)

Script community à utiliser:

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/technitiumdns.sh)"

Configuration lors du déploiement:

  • Hostname: jit-technitium
  • IP: 192.168.1.210
  • Gateway: 192.168.1.1
  • CPU: 1 vCPU
  • RAM: 512 MB
  • Disk: 8 GB
  • DNS: 192.168.1.1 (temporaire, sera changé après config)

Post-installation:

  1. Accéder à l'interface web: http://192.168.1.210:5380
  2. Configurer le mot de passe admin
  3. Générer le token API (Settings → API)
  4. Sauvegarder le token pour Ansible

1.2 AdGuard Home (LXC)

Script community à utiliser:

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/adguard.sh)"

Configuration lors du déploiement:

  • Hostname: jit-adguard
  • IP: 192.168.1.211
  • Gateway: 192.168.1.1
  • CPU: 1 vCPU
  • RAM: 512 MB
  • Disk: 4 GB
  • DNS: 192.168.1.1 (temporaire)

Post-installation:

  1. Accéder à l'interface web: http://192.168.1.211:3000
  2. Suivre le wizard de configuration
  3. Configurer upstream DNS: Cloudflare DoH (https://dns.cloudflare.com/dns-query)
  4. Activer les listes de blocage par défaut

Phase 2 : Déploiement TrueNAS (Docker)

2.1 Préparation TrueNAS

# Se connecter en SSH sur TrueNAS
ssh root@192.168.1.173

# Créer le volume Docker (pas de répertoires, on utilise un volume nommé)
docker volume create technitium-data

# Vérifier que Docker est installé
docker --version

2.2 Déploiement manuel (si pas Ansible)

# Lancer le conteneur avec TOUS les ports nécessaires
docker run -d \
--name technitium-truenas \
--hostname technitium-truenas \
--restart unless-stopped \
-p 53:53/udp \
-p 53:53/tcp \
-p 5380:5380/tcp \
-p 53443:53443/tcp \
-e DNS_SERVER_DOMAIN=technitium-truenas.j-it.be \
-e DNS_SERVER_ADMIN_PASSWORD=ChangeThisPassword123! \
-v technitium-data:/etc/dns \
technitium/dns-server:latest

# Vérifier que le conteneur tourne
docker ps | grep technitium

# Vérifier les logs
docker logs -f technitium-truenas

# ⚠️ IMPORTANT: Vérifier que le port 53443 est bien accessible
nc -zv 192.168.1.173 53443
# Doit retourner: Connection to 192.168.1.173 53443 port [tcp/*] succeeded!

⚠️ Port 53443 crucial : Ce port est utilisé pour la communication HTTPS entre les nœuds du cluster. Sans lui, le Secondary ne pourra pas rejoindre le cluster.

2.3 Déploiement via Ansible (recommandé)

Voir la section "Playbook Ansible" ci-dessous.

Phase 3 : Configuration Technitium Cluster

3.0 Comprendre le Clustering Technitium

🔄 Clustering vs DNS Primary/Secondary classique

AspectDNS Classique (AXFR/IXFR)Technitium Clustering
SynchronisationZones uniquementZones + Settings + Apps + Tout
ConfigurationManuelle sur SecondaryAutomatique
ModificationsUniquement sur PrimarySur n'importe quel nœud
Zones expiréesPeut arriverN'arrive jamais
ComplexitéPlus complexePlus simple
Port requis53 UDP/TCP53 UDP/TCP + 53443 TCP

Architecture du Cluster :

Primary Node (192.168.1.210)
├─ Crée le cluster "jit-dns-cluster"
├─ Gère la coordination
├─ Synchronise vers Secondary Nodes
└─ URL: https://jit-technitium.jit-dns-cluster:53443

Secondary Node (192.168.1.173)
├─ Rejoint le cluster existant
├─ Réplique TOUTE la configuration automatiquement
├─ Peut répondre aux requêtes DNS
└─ URL: https://technitium-truenas.jit-dns-cluster:53443

Synchronisation automatique:
├─ ✅ Zones DNS (*.homelab, *.nas, *.docker)
├─ ✅ Settings (Forwarders, DHCP, etc.)
├─ ✅ Apps installées
├─ ✅ Allowed/Blocked lists
└─ ✅ Administration (users, permissions)

3.1 Configuration du Primary Node (Proxmox - 192.168.1.210)

Interface Web: http://192.168.1.210:5380

3.1.1 Activer HTTPS (obligatoire pour le clustering)

Settings → Web Service:

Enable HTTPS: Yes
HTTPS Port: 53443
HTTP to HTTPS Redirect: Yes (optionnel)
Certificate: [Laisser générer un certificat self-signed automatiquement]

Cliquer sur "Save" puis redémarrer le service web.

⚠️ Important : Après activation, l'interface sera accessible sur https://192.168.1.210:53443 (acceptez le certificat self-signed dans votre navigateur).

3.1.2 Créer les zones DNS (avant le clustering)

⚠️ Créez vos zones MAINTENANT, avant de créer le cluster. Elles seront automatiquement synchronisées vers le Secondary lors du join.

1. Zone: homelab.j-it.be

  • Aller dans ZonesAdd Zone
  • Zone Name: homelab.j-it.be
  • Type: Primary Zone
  • Cliquer sur Add
  • Ajouter un enregistrement wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.212
    • TTL: 3600
    • Cliquer sur Add Record

2. Zone: nas.j-it.be

  • Zone Name: nas.j-it.be
  • Type: Primary Zone
  • Record wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.173
    • TTL: 3600

3. Zone: docker.j-it.be

  • Zone Name: docker.j-it.be
  • Type: Primary Zone
  • Record wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.100
    • TTL: 3600
3.1.3 Configurer les Forwarders

Settings → Forwarders:

Enable Forwarders: Yes
Forwarder:
- Protocol: UDP
- Forwarder: 192.168.1.211
- Port: 53

Cliquer sur "Save"

3.1.4 Configurer le DHCP

DHCP → Scopes → Add Scope:

Scope Name: LAN
Network Address: 192.168.1.0
Subnet Mask: 255.255.255.0
Lease Type: Dynamic
Start IP Address: 192.168.1.100
End IP Address: 192.168.1.250
Lease Time: 1 day (86400 seconds)
Offer Delay Time: 0 ms
Router: 192.168.1.1
DNS Servers: 192.168.1.210, 192.168.1.173
Domain Name: j-it.be

Cocher "Enable This Scope" puis Save.

3.1.5 Créer le Cluster

Settings → Clustering → Create Cluster:

Cluster Name: jit-dns-cluster
Cluster Domain: jit-dns-cluster
(Un nouveau domaine sera créé dans vos zones)

Primary Node IP Addresses: 192.168.1.210
(Ajoutez toutes les IPs de cette machine, une par ligne)

Enable DNS-over-HTTPS: No
(Optionnel, peut être activé plus tard)

Enable DNS-over-TLS: No
(Optionnel, peut être activé plus tard)

Cliquer sur "Create Cluster"

Résultat :

  • ✅ Le cluster "jit-dns-cluster" est créé
  • ✅ Une nouvelle zone jit-dns-cluster apparaît dans les zones
  • ✅ Le Primary Node devient jit-technitium.jit-dns-cluster
  • ✅ Des enregistrements TLSA sont créés pour DANE authentication
  • ✅ Le Primary est prêt à accepter des Secondary Nodes

Vérifier :

Settings → Clustering → Cluster Info

Cluster Status: Active
Cluster Name: jit-dns-cluster
Nodes: 1 (Primary Node)

3.2 Joindre le Secondary Node (TrueNAS - 192.168.1.173)

Interface Web: http://192.168.1.173:5380

3.2.1 Activer HTTPS sur le Secondary (recommandé)

Settings → Web Service:

Enable HTTPS: Yes
HTTPS Port: 53443
Certificate: [Laisser générer automatiquement]

Sauvegarder et redémarrer.

3.2.2 Joindre le Cluster

⚠️ AVERTISSEMENT IMPORTANT :

Le processus de join va ÉCRASER COMPLÈTEMENT la configuration actuelle du Secondary pour les sections suivantes :

  • Allowed
  • Blocked
  • Apps
  • Settings
  • Administration

Assurez-vous que le Secondary est vierge ou faites un backup !

Settings → Clustering → Join Cluster:

Secondary Node IP Addresses: 192.168.1.173
(Toutes les IPs de cette machine, une par ligne)

Primary Node URL: https://192.168.1.210:53443
⚠️ Utilisez l'IP, pas le hostname, pour éviter les problèmes DNS

Primary Node IP Address (Optional): 192.168.1.210
✅ Recommandé pour éviter les problèmes de résolution DNS

Certificate Validation:
☑️ Ignore Certificate Validation Errors
✅ OBLIGATOIRE si vous utilisez des certificats self-signed

Primary Node Username: admin

Primary Node Password: [le mot de passe admin du Primary Node]

Cliquer sur "Join Cluster"

⏱️ Le processus va prendre 2-5 minutes selon la taille de la configuration à synchroniser.

Vous verrez un message : "Joining cluster... Please wait."

Ne fermez pas la page pendant le processus !

3.2.3 Vérifier le Cluster

Une fois le join terminé, sur les DEUX instances :

Settings → Clustering → Cluster Info

Vous devriez voir :

Cluster Status: Active
Cluster Name: jit-dns-cluster
Nodes: 2

Node 1 (Primary):
- Name: jit-technitium.jit-dns-cluster
- IP Address: 192.168.1.210
- Role: Primary Node

Node 2 (Secondary):
- Name: technitium-truenas.jit-dns-cluster
- IP Address: 192.168.1.173
- Role: Secondary Node

Vérifier les zones sur le Secondary :

Zones → List Zones

Vous devriez voir:
✅ homelab.j-it.be (synchronisée)
✅ nas.j-it.be (synchronisée)
✅ docker.j-it.be (synchronisée)
✅ jit-dns-cluster (zone du cluster)

Les wildcards doivent être présents dans chaque zone !

3.2.4 Configurer des Forwarders différents (optionnel)

Le Secondary peut avoir des forwarders différents du Primary. C'est utile en cas de failover si le Primary (avec AdGuard) tombe.

Settings → Forwarders:

Enable Forwarders: Yes
Forwarder 1:
- Protocol: HTTPS
- Forwarder: https://1.1.1.1/dns-query
Forwarder 2:
- Protocol: HTTPS
- Forwarder: https://8.8.8.8/dns-query

Note : En mode normal, le Primary répond et utilise AdGuard (blocage pub). Si le Primary tombe, le Secondary prend le relais avec Cloudflare direct (pas de blocage pub mais DNS fonctionne).

3.3 Configuration terminée ! ✅

Le Cluster est maintenant opérationnel :

  • ✅ 2 nœuds actifs (Primary et Secondary)
  • ✅ Synchronisation automatique complète et bidirectionnelle
  • ✅ Les 3 zones wildcard sont présentes sur les deux nœuds
  • ✅ Settings, Apps, Administration synchronisés
  • ✅ Modifications possibles sur n'importe quel nœud
  • ✅ DHCP actif sur le Primary Node
  • ✅ Pas de zones "expirées" - c'est automatique

Flux de résolution DNS :

Client demande: test.homelab.j-it.be
├─ Primary Node (192.168.1.210) : Zone locale → 192.168.1.212 ✅
└─ Secondary Node (192.168.1.173) : Zone locale → 192.168.1.212 ✅

Client demande: n8n.j-it.be
├─ Primary Node → Forward → AdGuard (192.168.1.211) → OVH DNS ✅
└─ Secondary Node → Forward → Cloudflare → OVH DNS ✅

Client demande: www.google.com
├─ Primary Node → Forward → AdGuard → Internet ✅
└─ Secondary Node → Forward → Cloudflare → Internet ✅

Next step : Configurer AdGuard et tester

3.0 Stratégie : Wildcards uniquement

Architecture DNS :

DNS OVH (public) - Géré chez OVH :
├─ n8n.j-it.be → IP_PUBLIQUE
├─ portainer.j-it.be → IP_PUBLIQUE
├─ traefik.j-it.be → IP_PUBLIQUE
├─ projects.j-it.be → IP_PUBLIQUE
└─ www.j-it.be → IP_PUBLIQUE

Technitium (interne) - Zones Primary avec wildcards :
├─ *.homelab.j-it.be → 192.168.1.212
├─ *.nas.j-it.be → 192.168.1.173
└─ *.docker.j-it.be → 192.168.1.100

Pour tout le reste :
└─ Forward → AdGuard → Internet → OVH DNS

Comportement :

  • Services publics (n8n.j-it.be, portainer.j-it.be) : résolus via OVH
  • Wildcards internes (test.homelab.j-it.be) : résolus localement
  • Internet (www.google.com) : résolu via AdGuard puis Internet

Synchronisation automatique :

  • Les 3 zones wildcard se synchronisent automatiquement vers le Secondary ✅
  • Aucune configuration manuelle nécessaire sur TrueNAS ✅

3.1 Configuration du Primary (Proxmox - 192.168.1.210)

Interface Web: http://192.168.1.210:5380

3.1.1 Créer les zones Primary (wildcards uniquement)

1. Zone: homelab.j-it.be

  • Aller dans ZonesAdd Zone
  • Zone Name: homelab.j-it.be
  • Type: Primary Zone
  • Cliquer sur Add
  • Ajouter un enregistrement wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.212
    • TTL: 3600

2. Zone: nas.j-it.be

  • Zone Name: nas.j-it.be
  • Type: Primary Zone
  • Record wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.173
    • TTL: 3600

3. Zone: docker.j-it.be

  • Zone Name: docker.j-it.be
  • Type: Primary Zone
  • Record wildcard:
    • Name: *
    • Type: A
    • IPv4 Address: 192.168.1.100
    • TTL: 3600

C'est tout ! Pas besoin d'autres zones.

Résultat :

  • Wildcards internes : test.homelab.j-it.be, dev.docker.j-it.be, etc.
  • Services publics : n8n.j-it.be, portainer.j-it.be → via OVH DNS
  • Ces 3 zones se synchroniseront automatiquement vers le Secondary ✅
3.1.2 Configurer Zone Transfer

Settings → Zone Transfer Settings:

Allow Zone Transfer: Enabled
Allow Zone Transfer From: Any
Notify: Enabled
Notify Servers: 192.168.1.173

Pour chaque zone créée:

  • Aller dans Zones → Sélectionner la zone
  • Zone OptionsZone Transfer
  • Cocher Allow Zone Transfer
  • Ajouter 192.168.1.173 dans Allow Zone Transfer to
  • Cocher Notify
  • Ajouter 192.168.1.173 dans Also Notify
3.1.3 Configurer les Forwarders

Settings → Forwarders:

Enable Forwarders: Yes
Forwarder 1:
- Protocol: UDP
- Address: 192.168.1.211
- Port: 53
3.1.4 Configurer le DHCP

DHCP → Scopes → Add Scope:

Scope Name: LAN
Network Address: 192.168.1.0
Subnet Mask: 255.255.255.0
Start IP: 192.168.1.100
End IP: 192.168.1.250
Lease Time: 86400 seconds (24 hours)
Router: 192.168.1.1
DNS Servers: 192.168.1.210, 192.168.1.173
Domain Name: j-it.be

Activer le scope:

  • Cocher Enable This Scope
  • Sauvegarder
3.1.5 Configuration terminée pour le Primary

Vérifications :

  • ✅ 3 zones Primary créées : homelab, nas, docker (avec wildcards)
  • ✅ Zone Transfer configuré pour 192.168.1.173
  • ✅ Forwarders configurés vers AdGuard (192.168.1.211)
  • ✅ DHCP configuré et activé

Résolution DNS :

  • Wildcards internes : *.docker.j-it.be, *.homelab.j-it.be, *.nas.j-it.be → IPs locales
  • Services publics : n8n.j-it.be, portainer.j-it.be → Forward → AdGuard → OVH DNS
  • Internet : www.google.com → Forward → AdGuard → Internet

Next step : Configurer le Secondary sur TrueNAS

3.2 Configuration du Secondary (TrueNAS - 192.168.1.173)

Interface Web: http://192.168.1.173:5380

3.2.1 Créer les zones Secondary

✅ Simple : Seulement 3 zones à créer, synchronisation automatique !

1. Zone: homelab.j-it.be

  • Aller dans ZonesAdd Zone
  • Zone Name: homelab.j-it.be
  • Type: Secondary Zone
  • Primary Name Server Addresses: 192.168.1.210
  • Zone Transfer Protocol: Tcp
  • Cliquer sur Add

2. Zone: nas.j-it.be

  • Zone Name: nas.j-it.be
  • Type: Secondary Zone
  • Primary Name Server Addresses: 192.168.1.210

3. Zone: docker.j-it.be

  • Zone Name: docker.j-it.be
  • Type: Secondary Zone
  • Primary Name Server Addresses: 192.168.1.210

Vérifier la synchronisation:

  • Les zones devraient se synchroniser automatiquement dans les 30 secondes
  • Vérifier dans Zones que le statut est "Refreshed" ou "Synchronized"
  • Vérifier les SOA Serial Numbers (doivent matcher le Primary)
3.2.2 Configurer les Forwarders

Settings → Forwarders:

Enable Forwarders: Yes
Forwarder 1:
- Protocol: HTTPS
- Address: https://1.1.1.1/dns-query
Forwarder 2:
- Protocol: HTTPS
- Address: https://8.8.8.8/dns-query

Note : Le Secondary forward directement vers Internet (pas vers AdGuard). En mode failover, vous n'aurez pas de blocage pub, mais le DNS fonctionnera.

3.2.3 Configuration terminée ! ✅

Le Secondary est maintenant :

  • ✅ Complètement synchronisé avec le Primary (3 zones wildcard)
  • ✅ Prêt à prendre le relais si Proxmox tombe
  • ✅ À jour automatiquement à chaque changement sur le Primary
  • ✅ Forward vers Internet pour tous les services publics (n8n.j-it.be, etc.)

3.3 Configuration AdGuard Home (192.168.1.211)

Interface Web: http://192.168.1.211

3.3.1 Configuration initiale

Settings → DNS Settings:

Upstream DNS servers:

https://dns.cloudflare.com/dns-query
tls://1.1.1.1
https://dns.google/dns-query

Bootstrap DNS servers:

1.1.1.1
8.8.8.8

Rate limiting: 30 (requêtes par seconde)

3.3.2 Listes de blocage

Filters → DNS blocklists:

Activer les listes par défaut:

  • ✅ AdGuard DNS filter
  • ✅ AdAway Default Blocklist
  • ✅ Peter Lowe's List
  • ✅ Dandelion Sprout's Anti-Malware List
3.3.3 Configuration avancée

Settings → General Settings:

Query logs retention: 24 hours
Statistics retention: 24 hours

Settings → Encryption:

  • Optionnel: Configurer DNS-over-HTTPS (DoH) et DNS-over-TLS (DoT) si nécessaire

Phase 4 : Validation et tests

4.1 Tests DNS depuis un client

Pré-requis: Configurer un client avec DNS = 192.168.1.210

# Test résolution wildcards (zones locales)
nslookup test.homelab.j-it.be 192.168.1.210
# Attendu: 192.168.1.212

nslookup random.docker.j-it.be 192.168.1.210
# Attendu: 192.168.1.100

nslookup xyz.nas.j-it.be 192.168.1.210
# Attendu: 192.168.1.173

# Test résolution services publics (via OVH)
nslookup n8n.j-it.be 192.168.1.210
# Attendu: IP_PUBLIQUE (depuis OVH, via AdGuard)

nslookup portainer.j-it.be 192.168.1.210
# Attendu: IP_PUBLIQUE (depuis OVH, via AdGuard)

nslookup traefik.j-it.be 192.168.1.210
# Attendu: IP_PUBLIQUE (depuis OVH, via AdGuard)

# Test résolution Internet
nslookup www.google.com 192.168.1.210
# Attendu: IP publique Google

nslookup www.j-it.be 192.168.1.210
# Attendu: IP publique de votre site (via OVH)

# Test failover (depuis TrueNAS Secondary)
nslookup test.homelab.j-it.be 192.168.1.173
# Attendu: 192.168.1.212 (zone secondary sync ✅)

nslookup n8n.j-it.be 192.168.1.173
# Attendu: IP_PUBLIQUE (forward vers Internet, pas de sync nécessaire ✅)

4.2 Test Zone Transfer

# Vérifier la synchronisation (depuis un client Linux)
dig @192.168.1.173 homelab.j-it.be AXFR

# Vérifier les SOA Serial Numbers (doivent être identiques)
dig @192.168.1.210 homelab.j-it.be SOA +short
dig @192.168.1.173 homelab.j-it.be SOA +short

4.3 Test blocage publicitaire

# Test depuis un client avec DNS = 192.168.1.210
nslookup ads.doubleclick.net 192.168.1.210
# Attendu: 0.0.0.0 ou NXDOMAIN

# Vérifier dans l'interface AdGuard
# http://192.168.1.211 → Query Log
# Vous devriez voir les requêtes bloquées

4.4 Test DHCP

Sur votre routeur/switch:

  1. Désactiver le serveur DHCP actuel
  2. Attendre quelques minutes
  3. Sur un nouveau client (ou renouveler le bail):
# Windows
ipconfig /release
ipconfig /renew
ipconfig /all
# Vérifier que DNS 1 = 192.168.1.210 et DNS 2 = 192.168.1.173

# Linux
sudo dhclient -r
sudo dhclient
cat /etc/resolv.conf
# Vérifier nameserver 192.168.1.210 et 192.168.1.173

4.5 Test de failover

Simuler une panne de Proxmox:

# Arrêter le LXC Technitium Primary
pct stop <ID_LXC_TECHNITIUM>

# Depuis un client, tester la résolution
nslookup test.homelab.j-it.be
# Devrait fonctionner via 192.168.1.173 (TrueNAS)

# Redémarrer le Primary
pct start <ID_LXC_TECHNITIUM>

# Vérifier que la synchronisation reprend

🔄 Fonctionnement du Cluster Technitium

Concept de Primary/Secondary

Technitium utilise le modèle DNS classique :

  1. Primary (Master): 192.168.1.210 (jit-technitium)

    • Zones autoritaires en lecture/écriture
    • Source de vérité pour les zones
    • Notifie les secondaires lors de changements (NOTIFY)
    • Permet les Zone Transfers (AXFR/IXFR)
  2. Secondary (Slave): 192.168.1.173 (technitium-truenas)

    • Zones en lecture seule
    • Synchronisation automatique via Zone Transfer
    • Peut répondre aux requêtes DNS (load balancing)
    • Prend le relais si Primary indisponible

Processus de synchronisation

┌─────────────────────────────────────────────────────────┐
│ Modification sur Primary (192.168.1.210) │
│ - Ajout d'un enregistrement DNS │
│ - Modification d'une zone │
└────────────────┬────────────────────────────────────────┘


┌──────────────────────────────┐
│ SOA Serial Number updated │
│ (incrémenté automatiquement) │
└────────────┬─────────────────┘


┌────────────────────────────┐
│ NOTIFY envoyé au Secondary │
│ (192.168.1.173) │
└────────────┬───────────────┘


┌────────────────────────────────────────────────────────┐
│ Secondary reçoit NOTIFY │
│ 1. Compare SOA Serial Number │
│ 2. Si différent, initie AXFR (full) ou IXFR (incr.) │
│ 3. Télécharge les changements │
│ 4. Applique les changements localement │
└────────────────────────────────────────────────────────┘

Types de Zone Transfer

AXFR (Full Zone Transfer):

  • Transfert complet de la zone
  • Utilisé pour la première synchronisation
  • Utilisé si IXFR échoue
  • Plus lourd en bande passante

IXFR (Incremental Zone Transfer):

  • Transfert uniquement des changements
  • Plus efficace pour les grosses zones
  • Basé sur les numéros de série SOA
  • Utilisé pour les mises à jour

Mécanisme de failover DNS côté client

Client DHCP reçoit:
├─ DNS 1: 192.168.1.210 (Primary)
└─ DNS 2: 192.168.1.173 (Secondary)

Comportement:
1. Client interroge DNS 1 (192.168.1.210)
├─ Si réponse dans timeout (2-5 sec) → Utilise DNS 1
└─ Si pas de réponse → Bascule vers DNS 2 (192.168.1.173)

2. Client peut utiliser les deux en parallèle (OS dépendant)
└─ Windows: Essaie DNS 1, puis DNS 2 si échec
└─ Linux: Peut faire round-robin selon config

Configuration HA (High Availability)

Stratégie en production:

Scenario Normal:
Primary (Proxmox): Active - 100% des requêtes
Secondary (TrueNAS): Standby - 0% des requêtes (sync uniquement)
AdGuard (Proxmox): Active - blocage pub

Scenario Proxmox Down:
Primary (Proxmox): Indisponible
Secondary (TrueNAS): Active - 100% des requêtes
└─ Zones en lecture seule
└─ Pas de modifications possibles
└─ Forwarders vers Internet direct (pas AdGuard)
└─ Pas de blocage pub pendant cette période

Scenario Proxmox UP (après panne):
Primary (Proxmox): Active
Secondary (TrueNAS): Sync automatique des changements
└─ Récupère tous les changements manqués (s'il y en a eu)
└─ Retour en mode standby

Limitations et clarifications

✅ Ce qui se synchronise automatiquement (Primary → Secondary) :

  1. Zones DNS complètes (les 3 zones wildcard)
  2. Enregistrements dans les zones (A, AAAA, CNAME, MX, TXT, etc.)
  3. Wildcards (*.homelab.j-it.be, *.nas.j-it.be, *.docker.j-it.be)
  4. SOA, NS records

⚠️ Ce qui NE se synchronise PAS (mais ce n'est pas un problème) :

  1. Configuration globale (Forwarders, Settings)

    • À configurer manuellement sur chaque instance (fait une seule fois)
    • Ou via Ansible
  2. Configuration DHCP

    • DHCP actif uniquement sur Primary
  3. Services publics (n8n.j-it.be, portainer.j-it.be, etc.)

    • Ces services ne sont PAS gérés par Technitium
    • Ils sont résolus via DNS public OVH
    • Le Secondary les résout aussi via forward vers Internet
    • ✅ Pas de synchronisation nécessaire !

💡 Architecture simplifiée :

Zones Technitium (sync automatique):
├─ *.homelab.j-it.be → 192.168.1.212
├─ *.nas.j-it.be → 192.168.1.173
└─ *.docker.j-it.be → 192.168.1.100

Services publics (via OVH, pas de sync nécessaire):
├─ n8n.j-it.be → Forward → AdGuard → OVH
├─ portainer.j-it.be → Forward → AdGuard → OVH
└─ traefik.j-it.be → Forward → AdGuard → OVH

Monitoring du Cluster

Script de vérification manuelle:

#!/bin/bash
# check-dns-health.sh

echo "=== DNS Health Check ==="
echo ""

# Check Primary
echo "1. Checking Primary (192.168.1.210)..."
dig @192.168.1.210 test.homelab.j-it.be +short
if [ $? -eq 0 ]; then
echo "✅ Primary is UP"
else
echo "❌ Primary is DOWN"
fi

# Check Secondary
echo "2. Checking Secondary (192.168.1.173)..."
dig @192.168.1.173 test.homelab.j-it.be +short
if [ $? -eq 0 ]; then
echo "✅ Secondary is UP"
else
echo "❌ Secondary is DOWN"
fi

# Check Zone Sync
echo "3. Checking Zone Synchronization..."
PRIMARY_SOA=$(dig @192.168.1.210 homelab.j-it.be SOA +short | awk '{print $3}')
SECONDARY_SOA=$(dig @192.168.1.173 homelab.j-it.be SOA +short | awk '{print $3}')

if [ "$PRIMARY_SOA" == "$SECONDARY_SOA" ]; then
echo "✅ Zones are synchronized (Serial: $PRIMARY_SOA)"
else
echo "⚠️ Zones are OUT OF SYNC (Primary: $PRIMARY_SOA, Secondary: $SECONDARY_SOA)"
fi

# Check AdGuard
echo "4. Checking AdGuard (192.168.1.211)..."
dig @192.168.1.211 www.google.com +short
if [ $? -eq 0 ]; then
echo "✅ AdGuard is UP"
else
echo "❌ AdGuard is DOWN"
fi

echo ""
echo "=== End of Health Check ==="

À automatiser avec:

  • Cron job quotidien
  • n8n workflow avec alertes Gotify
  • Beszel monitoring

📝 Fichiers de configuration

Docker Compose (TrueNAS)

Fichier: /mnt/pool/docker/technitium/docker-compose.yml

version: '3.8'

services:
technitium-secondary:
image: technitium/dns-server:latest
container_name: technitium-truenas
hostname: technitium-truenas
restart: unless-stopped

ports:
- "53:53/udp" # DNS UDP
- "53:53/tcp" # DNS TCP (pour AXFR)
- "5380:5380/tcp" # Web Interface

environment:
- DNS_SERVER_DOMAIN=technitium-truenas.j-it.be
- DNS_SERVER_ADMIN_PASSWORD=ChangeThisPassword123!

volumes:
- ./config:/etc/dns

networks:
- dns-network

# Health check
healthcheck:
test: ["CMD", "dig", "@127.0.0.1", "google.com", "+short"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s

networks:
dns-network:
driver: bridge

Playbook Ansible (sans docker-compose, volumes nommés uniquement)

Structure de répertoires:

ansible/
├── inventory/
│ └── hosts.ini
├── group_vars/
│ └── all/
│ └── vault.yml (encrypted)
└── playbooks/
└── deploy-technitium-truenas.yml

Fichier: inventory/hosts.ini

[truenas]
truenas ansible_host=192.168.1.173 ansible_user=root

[truenas:vars]
ansible_python_interpreter=/usr/bin/python3

Fichier: group_vars/all/vault.yml (à encrypter avec ansible-vault)

# Encrypter ce fichier avec: ansible-vault encrypt group_vars/all/vault.yml
vault_technitium_password: "SuperSecretPassword123!"
vault_technitium_api_token: "your-api-token-from-primary-server"

Fichier: playbooks/deploy-technitium-truenas.yml

---
- name: Deploy Technitium DNS Secondary on TrueNAS
hosts: truenas
become: yes

vars:
technitium_container_name: "technitium-truenas"
technitium_image: "technitium/dns-server:latest"
technitium_volume_name: "technitium-data"
technitium_network_name: "technitium-net"
technitium_primary_ip: "192.168.1.210"
technitium_secondary_ip: "192.168.1.173"
technitium_admin_password: "{{ vault_technitium_password }}"
technitium_api_token: "{{ vault_technitium_api_token }}"

# Zones wildcards qui vont se synchroniser automatiquement
dns_zones:
- name: "homelab.j-it.be"
type: "secondary"
- name: "nas.j-it.be"
type: "secondary"
- name: "docker.j-it.be"
type: "secondary"

tasks:
- name: Ensure Docker is installed
package:
name: docker
state: present

- name: Create Docker volume for Technitium data
community.docker.docker_volume:
name: "{{ technitium_volume_name }}"
state: present

- name: Create Docker network for Technitium
community.docker.docker_network:
name: "{{ technitium_network_name }}"
state: present

- name: Pull Technitium DNS image
community.docker.docker_image:
name: "{{ technitium_image }}"
source: pull
force_source: yes

- name: Stop existing Technitium container if running
community.docker.docker_container:
name: "{{ technitium_container_name }}"
state: absent
ignore_errors: yes

- name: Start Technitium DNS container
community.docker.docker_container:
name: "{{ technitium_container_name }}"
image: "{{ technitium_image }}"
state: started
restart_policy: unless-stopped
hostname: "technitium-truenas"
networks:
- name: "{{ technitium_network_name }}"
ports:
- "53:53/udp" # DNS UDP
- "53:53/tcp" # DNS TCP (pour AXFR)
- "5380:5380/tcp" # HTTP Web Interface
- "53443:53443/tcp" # HTTPS API (pour Clustering)
env:
DNS_SERVER_DOMAIN: "technitium-truenas.j-it.be"
DNS_SERVER_ADMIN_PASSWORD: "{{ technitium_admin_password }}"
volumes:
- "{{ technitium_volume_name }}:/etc/dns"
healthcheck:
test: ["CMD", "dig", "@127.0.0.1", "google.com", "+short"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s

- name: Wait for Technitium to be ready
uri:
url: "http://{{ technitium_secondary_ip }}:5380"
status_code: 200
register: result
until: result.status == 200
retries: 30
delay: 10

- name: Configure secondary zones via API
uri:
url: "http://{{ technitium_secondary_ip }}:5380/api/zones/create"
method: POST
body_format: form-urlencoded
body:
token: "{{ technitium_api_token }}"
zone: "{{ item.name }}"
type: "Secondary"
primaryNameServerAddresses: "{{ technitium_primary_ip }}"
status_code: [200, 400]
loop: "{{ dns_zones }}"
register: zone_creation
failed_when:
- zone_creation.status not in [200, 400]
- '"already exists" not in (zone_creation.json.response | default(""))'

- name: Configure forwarders (direct to Internet, pas AdGuard)
uri:
url: "http://{{ technitium_secondary_ip }}:5380/api/settings/set"
method: POST
body_format: form-urlencoded
body:
token: "{{ technitium_api_token }}"
forwarders: "https://1.1.1.1/dns-query,https://8.8.8.8/dns-query"
forwarderProtocol: "Https"
status_code: 200

- name: Enable zone transfer from primary
uri:
url: "http://{{ technitium_secondary_ip }}:5380/api/settings/set"
method: POST
body_format: form-urlencoded
body:
token: "{{ technitium_api_token }}"
allowRecursion: "true"
allowRecursionOnlyForPrivateNetworks: "true"
status_code: 200

- name: Display deployment summary
debug:
msg:
- "Technitium DNS Secondary deployed successfully!"
- "Container: {{ technitium_container_name }}"
- "Volume: {{ technitium_volume_name }}"
- "Network: {{ technitium_network_name }}"
- "Web UI: http://{{ technitium_secondary_ip }}:5380"
- "Zones configured: {{ dns_zones | map(attribute='name') | list }}"
- ""
- "✅ Zones wildcard synchronisées automatiquement"
- "✅ Services publics (n8n.j-it.be, etc.) résolus via OVH DNS"
- "✅ Pas de configuration manuelle nécessaire"

Commandes Ansible

# Installer les collections Docker pour Ansible
ansible-galaxy collection install community.docker

# Encrypter le fichier vault
ansible-vault encrypt group_vars/all/vault.yml

# Déployer Technitium sur TrueNAS
ansible-playbook -i inventory/hosts.ini playbooks/deploy-technitium-truenas.yml --ask-vault-pass

# Vérifier la connectivité
ansible truenas -i inventory/hosts.ini -m ping

# Vérifier que le conteneur tourne
ansible truenas -i inventory/hosts.ini -m shell -a "docker ps | grep technitium"

# Vérifier le volume Docker
ansible truenas -i inventory/hosts.ini -m shell -a "docker volume ls | grep technitium"

# Voir les logs du conteneur
ansible truenas -i inventory/hosts.ini -m shell -a "docker logs technitium-truenas --tail 50"

Commandes Docker manuelles (si besoin)

# Créer le volume
docker volume create technitium-data

# Lancer le conteneur
docker run -d \
--name technitium-truenas \
--hostname technitium-truenas \
--restart unless-stopped \
-p 53:53/udp \
-p 53:53/tcp \
-p 5380:5380/tcp \
-p 53443:53443/tcp \
-e DNS_SERVER_DOMAIN=technitium-truenas.j-it.be \
-e DNS_SERVER_ADMIN_PASSWORD=ChangeThisPassword123! \
-v technitium-data:/etc/dns \
technitium/dns-server:latest

# Vérifier les logs
docker logs -f technitium-truenas

# Backup du volume
docker run --rm \
-v technitium-data:/data \
-v /mnt/pool/backups:/backup \
alpine tar czf /backup/technitium-backup-$(date +%Y%m%d).tar.gz -C /data .

# Restore du volume
docker run --rm \
-v technitium-data:/data \
-v /mnt/pool/backups:/backup \
alpine tar xzf /backup/technitium-backup-20260106.tar.gz -C /data

🔐 Sécurité

Firewall UFW (TrueNAS)

# Installer UFW si nécessaire
apt-get install ufw

# Permettre DNS depuis le réseau local
ufw allow from 192.168.1.0/24 to any port 53 proto udp comment 'DNS UDP'
ufw allow from 192.168.1.0/24 to any port 53 proto tcp comment 'DNS TCP'

# Permettre l'interface web uniquement depuis le réseau local
ufw allow from 192.168.1.0/24 to any port 5380 proto tcp comment 'Technitium Web'

# Permettre SSH (si nécessaire)
ufw allow from 192.168.1.0/24 to any port 22 proto tcp comment 'SSH'

# Activer UFW
ufw enable

# Vérifier les règles
ufw status numbered

API Token Security

Best practices:

  1. Générer des tokens différents pour Primary et Secondary
  2. Stocker les tokens dans Ansible Vault
  3. Rotation des tokens tous les 90 jours
  4. Ne jamais commiter les tokens en clair dans Git

Backup réguliers

# Script de backup (à automatiser via cron)
#!/bin/bash
# backup-technitium.sh

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/mnt/pool/backups/technitium"

# Créer le répertoire de backup
mkdir -p $BACKUP_DIR

# Backup TrueNAS
docker exec technitium-truenas tar czf /etc/dns/backup-truenas-$DATE.tar.gz /etc/dns/config.json
docker cp technitium-truenas:/etc/dns/backup-truenas-$DATE.tar.gz $BACKUP_DIR/

# Backup Proxmox (via SSH)
ssh root@192.168.1.210 "tar czf /tmp/backup-primary-$DATE.tar.gz /var/lib/technitium"
scp root@192.168.1.210:/tmp/backup-primary-$DATE.tar.gz $BACKUP_DIR/

# Garder seulement les 7 derniers backups
find $BACKUP_DIR -name "backup-*.tar.gz" -mtime +7 -delete

echo "Backup completed: $DATE"

📊 Monitoring avec n8n

Workflow n8n pour monitoring DNS:

{
"name": "DNS Health Check",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"name": "Schedule Every 15min",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [250, 300]
},
{
"parameters": {
"command": "#!/bin/bash\ndig @192.168.1.210 test.homelab.j-it.be +short || echo 'PRIMARY_DOWN'"
},
"name": "Check Primary DNS",
"type": "n8n-nodes-base.executeCommand",
"position": [450, 200]
},
{
"parameters": {
"command": "#!/bin/bash\ndig @192.168.1.173 test.homelab.j-it.be +short || echo 'SECONDARY_DOWN'"
},
"name": "Check Secondary DNS",
"type": "n8n-nodes-base.executeCommand",
"position": [450, 400]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.stdout }}",
"operation": "contains",
"value2": "_DOWN"
}
]
}
},
"name": "If Error Detected",
"type": "n8n-nodes-base.if",
"position": [650, 300]
},
{
"parameters": {
"url": "http://192.168.1.100/gotify",
"options": {},
"bodyParametersJson": "={\n \"title\": \"🚨 DNS Alert\",\n \"message\": \"DNS Server Issue Detected:\\n{{ $json.stdout }}\",\n \"priority\": 8\n}"
},
"name": "Send Gotify Alert",
"type": "n8n-nodes-base.httpRequest",
"position": [850, 200]
}
],
"connections": {
"Schedule Every 15min": {
"main": [
[
{
"node": "Check Primary DNS",
"type": "main",
"index": 0
},
{
"node": "Check Secondary DNS",
"type": "main",
"index": 0
}
]
]
},
"Check Primary DNS": {
"main": [
[
{
"node": "If Error Detected",
"type": "main",
"index": 0
}
]
]
},
"Check Secondary DNS": {
"main": [
[
{
"node": "If Error Detected",
"type": "main",
"index": 0
}
]
]
},
"If Error Detected": {
"main": [
[
{
"node": "Send Gotify Alert",
"type": "main",
"index": 0
}
]
]
}
}
}

📚 Résumé des URLs et accès

Interfaces Web

ServiceURLCredentials
Technitium Primaryhttp://192.168.1.210:5380admin / [défini lors de l'install]
Technitium Secondaryhttp://192.168.1.173:5380admin / [défini dans docker-compose]
AdGuard Homehttp://192.168.1.211[défini lors du wizard]

Serveurs DNS

TypeIPHostnameRôle
Primary192.168.1.210jit-technitiumDNS autoritaire + DHCP
Secondary192.168.1.173technitium-truenasDNS failover
AdGuard192.168.1.211jit-adguardBlocage pub

Configuration DHCP distribuée

DNS Server 1: 192.168.1.210
DNS Server 2: 192.168.1.173
Gateway: 192.168.1.1
Domain: j-it.be

🔧 Dépannage

Problème: Zone Transfer ne fonctionne pas

⚠️ Ce problème n'existe plus avec le Clustering !

Si vous suivez cette documentation (Clustering), vous n'aurez pas de problèmes de Zone Transfer, car le Clustering n'utilise pas AXFR/IXFR.

Problème: Erreur "RemoteCertificateNameMismatch" lors du join

Symptômes:

Error! The remote certificate is invalid according to the validation procedure:
RemoteCertificateNameMismatch, RemoteCertificateChainErrors

Cause: Le certificat self-signed du Primary Node ne correspond pas au nom attendu.

Solutions:

  1. ✅ Solution simple (recommandée):

    • Cochez "Ignore Certificate Validation Errors" lors du join
    • Cette option est safe car elle n'est utilisée que pour la connexion initiale
    • Après le join, DANE-EE avec TLSA records sera utilisé automatiquement
  2. Utilisez l'IP au lieu du hostname:

    Primary Node URL: https://192.168.1.210:53443
    (au lieu de https://jit-technitium.jit-dns-cluster:53443)

    Primary Node IP Address: 192.168.1.210
  3. Résolution DNS temporaire (si nécessaire):

    # Sur TrueNAS, ajouter dans /etc/hosts
    echo "192.168.1.210 jit-technitium.jit-dns-cluster" >> /etc/hosts

Problème: Connection refused sur le port 53443

Symptômes:

Error! Connection refused: 192.168.1.210:53443

Cause: Le port 53443 n'est pas mappé dans Docker ou HTTPS n'est pas activé.

Solutions:

  1. Vérifier que HTTPS est activé:

    Sur Primary: Settings → Web Service → Enable HTTPS: Yes
  2. Vérifier que le port est bien mappé (Docker):

    # Vérifier les ports du conteneur
    docker port technitium-truenas

    # Devrait afficher:
    53/tcp -> 0.0.0.0:53
    53/udp -> 0.0.0.0:53
    5380/tcp -> 0.0.0.0:5380
    53443/tcp -> 0.0.0.0:53443 ⚠️ IMPORTANT
  3. Si le port 53443 manque, recréer le conteneur:

    docker stop technitium-truenas
    docker rm technitium-truenas

    docker run -d \
    --name technitium-truenas \
    -p 53:53/udp -p 53:53/tcp \
    -p 5380:5380/tcp \
    -p 53443:53443/tcp \
    -v technitium-data:/etc/dns \
    technitium/dns-server:latest
  4. Tester la connectivité:

    # Depuis TrueNAS
    nc -zv 192.168.1.210 53443

    # Devrait retourner:
    Connection to 192.168.1.210 53443 port [tcp/*] succeeded!

Problème: Le Secondary ne synchronise pas les zones

Symptômes:

  • Les zones n'apparaissent pas sur le Secondary
  • Le Cluster Info montre seulement 1 nœud

Vérifications:

  1. Vérifier le statut du cluster sur les deux nœuds:

    Settings → Clustering → Cluster Info

    Devrait afficher:
    - Cluster Status: Active
    - Nodes: 2
  2. Vérifier les logs du Secondary:

    docker logs technitium-truenas | grep -i cluster
    docker logs technitium-truenas | grep -i sync
  3. Forcer une synchronisation:

    • Sur le Primary, modifier une zone (ajouter un record puis le supprimer)
    • Le Secondary devrait détecter le changement et synchroniser
    • Vérifier dans les logs du Secondary
  4. Vérifier que HTTPS fonctionne sur les deux nœuds:

    curl -k https://192.168.1.210:53443
    curl -k https://192.168.1.173:53443
    # Les deux doivent répondre

Problème: Services publics (n8n.j-it.be) ne résolvent pas

Symptômes:

  • n8n.j-it.be ne résout pas ou résout mal

Vérifications:

  1. Vérifier que le domaine existe chez OVH:

    dig @dns19.ovh.net n8n.j-it.be
    # Doit retourner l'IP publique
  2. Vérifier que les Forwarders sont configurés:

    Settings → Forwarders
    Primary: 192.168.1.211 (AdGuard)
    Secondary: 1.1.1.1, 8.8.8.8 (direct)
  3. Vérifier qu'il n'y a pas de zone locale qui override:

    # Sur Technitium, vérifier qu'il n'y a PAS de zone n8n.j-it.be
    Zones → List Zones
    # Ne devrait contenir que: homelab, nas, docker, jit-dns-cluster
  4. Tester la résolution directement:

    # Depuis le Primary
    dig @192.168.1.210 n8n.j-it.be

    # Depuis le Secondary
    dig @192.168.1.173 n8n.j-it.be

Problème: AdGuard ne bloque plus

Solutions:

  1. Vérifier que les listes sont à jour:

    AdGuard: Settings → DNS blocklists → Update
  2. Vérifier les logs:

    AdGuard: Query Log
    # Rechercher des domaines connus (ads.doubleclick.net)
  3. Vérifier que Technitium forward bien vers AdGuard:

    # Test depuis le Primary
    dig @192.168.1.210 ads.doubleclick.net
    # Devrait être bloqué (0.0.0.0 ou NXDOMAIN)

Problème: Clients ne reçoivent pas les bonnes DNS via DHCP

Solutions:

  1. Vérifier que le scope DHCP est activé:

    Primary: DHCP → Scopes → LAN
    Status: Enabled ✅
  2. Vérifier qu'il n'y a pas d'autre serveur DHCP sur le réseau:

    # Depuis un client Linux
    sudo nmap --script broadcast-dhcp-discover
    # Devrait montrer uniquement 192.168.1.210
  3. Renouveler le bail DHCP sur le client:

    # Windows
    ipconfig /release
    ipconfig /renew
    ipconfig /all
    # Vérifier: DNS Servers = 192.168.1.210, 192.168.1.173

    # Linux
    sudo dhclient -r
    sudo dhclient
    cat /etc/resolv.conf
    # Vérifier: nameserver 192.168.1.210 et 192.168.1.173

Debug avancé : Vérifier l'état du Cluster

# Sur chaque nœud, vérifier l'état via API
curl -k "https://192.168.1.210:53443/api/cluster/status?token=YOUR_TOKEN"
curl -k "https://192.168.1.173:53443/api/cluster/status?token=YOUR_TOKEN"

# Devrait retourner du JSON avec:
# - clusterStatus: "Active"
# - totalNodes: 2
# - primaryNode: "jit-technitium.jit-dns-cluster"

📋 Checklist de déploiement

  • Phase 1: Proxmox LXC

    • Déployer Technitium LXC (192.168.1.210)
    • Déployer AdGuard LXC (192.168.1.211)
    • Accéder aux interfaces web
    • Générer token API Technitium
  • Phase 2: TrueNAS Docker

    • Créer répertoires sur TrueNAS
    • Déployer via docker-compose ou Ansible
    • Vérifier que le conteneur tourne
  • Phase 3: Configuration Technitium Primary

    • Créer 3 zones Primary (homelab, nas, docker)
    • Ajouter wildcards dans chaque zone
    • Configurer Zone Transfer (allow 192.168.1.173)
    • Configurer Forwarders (192.168.1.211)
    • Configurer DHCP
  • Phase 4: Configuration Technitium Secondary

    • Créer 3 zones Secondary
    • Vérifier synchronisation
    • Configurer Forwarders (Cloudflare/Google)
  • Phase 5: Configuration AdGuard

    • Configurer Upstream DNS
    • Activer listes de blocage
    • Configurer rate limiting
  • Phase 6: Tests

    • Test résolution wildcards (*.homelab.j-it.be, etc.)
    • Test résolution services publics (n8n.j-it.be via OVH)
    • Test résolution Internet (www.google.com)
    • Test failover (arrêter Primary)
    • Test Zone Transfer (vérifier SOA)
    • Test blocage pub
    • Test DHCP
  • Phase 7: Production

    • Désactiver DHCP sur routeur
    • Migrer progressivement les clients
    • Monitorer les logs
    • Configurer alertes (n8n/Gotify)
    • Configurer backups automatiques
  • Phase 8: Documentation

    • Documenter les IPs et hostnames
    • Documenter les credentials (dans vault)
    • Documenter les procédures de recovery
    • Éteindre Pi-hole

🎓 Ressources et références


Document créé le: 2026-01-07
Version: 2.0 - Technitium Clustering (remplace Primary/Secondary classique)
Auteur: Jérôme (J-IT)
Infrastructure: Proxmox + TrueNAS + Docker
Technologies: Technitium DNS Clustering, AdGuard Home, Ansible

Changements v2.0:

  • ✅ Remplacement du modèle DNS classique (AXFR/IXFR) par Technitium Clustering
  • ✅ Ajout du port 53443 (HTTPS) pour la communication clustering
  • ✅ Synchronisation complète automatique (zones + settings + apps)
  • ✅ Élimination des problèmes de zones expirées
  • ✅ Simplification du processus de configuration
  • ✅ Playbook Ansible corrigé sans docker-compose, volumes nommés uniquement