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:
- Accéder à l'interface web:
http://192.168.1.210:5380 - Configurer le mot de passe admin
- Générer le token API (Settings → API)
- 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:
- Accéder à l'interface web:
http://192.168.1.211:3000 - Suivre le wizard de configuration
- Configurer upstream DNS: Cloudflare DoH (
https://dns.cloudflare.com/dns-query) - 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
| Aspect | DNS Classique (AXFR/IXFR) | Technitium Clustering |
|---|---|---|
| Synchronisation | Zones uniquement | Zones + Settings + Apps + Tout |
| Configuration | Manuelle sur Secondary | Automatique |
| Modifications | Uniquement sur Primary | Sur n'importe quel nœud |
| Zones expirées | Peut arriver | N'arrive jamais |
| Complexité | Plus complexe | Plus simple |
| Port requis | 53 UDP/TCP | 53 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 Zones → Add 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
- Name:
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
- Name:
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
- Name:
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-clusterapparaî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 Zones → Add 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
- Name:
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
- Name:
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
- Name:
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 Options → Zone Transfer
- Cocher Allow Zone Transfer
- Ajouter
192.168.1.173dans Allow Zone Transfer to - Cocher Notify
- Ajouter
192.168.1.173dans 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 Zones → Add 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:
- Désactiver le serveur DHCP actuel
- Attendre quelques minutes
- 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 :
-
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)
-
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) :
- Zones DNS complètes (les 3 zones wildcard)
- Enregistrements dans les zones (A, AAAA, CNAME, MX, TXT, etc.)
- Wildcards (*.homelab.j-it.be, *.nas.j-it.be, *.docker.j-it.be)
- SOA, NS records
⚠️ Ce qui NE se synchronise PAS (mais ce n'est pas un problème) :
-
Configuration globale (Forwarders, Settings)
- À configurer manuellement sur chaque instance (fait une seule fois)
- Ou via Ansible
-
Configuration DHCP
- DHCP actif uniquement sur Primary
-
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:
- Générer des tokens différents pour Primary et Secondary
- Stocker les tokens dans Ansible Vault
- Rotation des tokens tous les 90 jours
- 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
| Service | URL | Credentials |
|---|---|---|
| Technitium Primary | http://192.168.1.210:5380 | admin / [défini lors de l'install] |
| Technitium Secondary | http://192.168.1.173:5380 | admin / [défini dans docker-compose] |
| AdGuard Home | http://192.168.1.211 | [défini lors du wizard] |
Serveurs DNS
| Type | IP | Hostname | Rôle |
|---|---|---|---|
| Primary | 192.168.1.210 | jit-technitium | DNS autoritaire + DHCP |
| Secondary | 192.168.1.173 | technitium-truenas | DNS failover |
| AdGuard | 192.168.1.211 | jit-adguard | Blocage 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:
-
✅ 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
-
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 -
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:
-
Vérifier que HTTPS est activé:
Sur Primary: Settings → Web Service → Enable HTTPS: Yes -
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 -
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 -
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:
-
Vérifier le statut du cluster sur les deux nœuds:
Settings → Clustering → Cluster Info
Devrait afficher:
- Cluster Status: Active
- Nodes: 2 -
Vérifier les logs du Secondary:
docker logs technitium-truenas | grep -i cluster
docker logs technitium-truenas | grep -i sync -
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
-
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.bene résout pas ou résout mal
Vérifications:
-
Vérifier que le domaine existe chez OVH:
dig @dns19.ovh.net n8n.j-it.be
# Doit retourner l'IP publique -
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) -
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 -
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:
-
Vérifier que les listes sont à jour:
AdGuard: Settings → DNS blocklists → Update -
Vérifier les logs:
AdGuard: Query Log
# Rechercher des domaines connus (ads.doubleclick.net) -
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:
-
Vérifier que le scope DHCP est activé:
Primary: DHCP → Scopes → LAN
Status: Enabled ✅ -
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 -
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
-
Technitium DNS Server:
- Documentation officielle: https://technitium.com/dns/help.html
- API Documentation: https://github.com/TechnitiumSoftware/DnsServer/blob/master/APIDOCS.md
- GitHub: https://github.com/TechnitiumSoftware/DnsServer
-
AdGuard Home:
- Documentation: https://github.com/AdguardTeam/AdGuardHome/wiki
- Getting Started: https://github.com/AdguardTeam/AdGuardHome#getting-started
-
Community Scripts Proxmox:
-
DNS Standards:
- RFC 1034: Domain Names - Concepts and Facilities
- RFC 1035: Domain Names - Implementation and Specification
- RFC 5936: DNS Zone Transfer Protocol (AXFR)
- RFC 1996: A Mechanism for Prompt Notification of Zone Changes (NOTIFY)
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