π Migratie van Pi-hole naar een High-Availability Technitium DNS Cluster
Na de recente migratie van mijn homelab DNS-infrastructuur van Pi-hole naar een High-Availability (HA) Technitium DNS-cluster, deel ik in dit projectverslag de complete architectuur, bevindingen en real-world benchmark-resultaten.
Bij het ontwerpen van een homelab DNS-architectuur sta je voor cruciale keuzes. Omdat mijn twee DNS-instanties op sterk verschillende hardwaregeneraties draaien, was een grondige prestatietest vereist om de optimale netwerkbalans te vinden.
π₯οΈ De Hardware & Netwerktopologie
Mijn Proxmox VE-omgeving maakt gebruik van twee fysiek gescheiden hosts met een duidelijke asymmetrie in rekenkracht:
-
Node 1 (Lenovo ThinkStation P520): Uitgerust met een Intel Xeon W-2135 CPU (gelanceerd in 2017).
-
Node 2 (AOOSTAR WTR Pro Max): Uitgerust met een AMD Ryzen 7 8845HS CPU (gelanceerd in 2024).
De Ryzen CPU uit 2024 is aanzienlijk krachtiger dan de Xeon uit 2017. Om deze hardware-asymmetrie optimaal te benutten, is de DHCP-scope van mijn router zo geconfigureerd dat de AOOSTAR-instantie (192.168.11.51) als Primaire DNS-server wordt uitgegeven, and de Lenovo-instantie (192.168.11.50) als Secundaire DNS-server.
Hierdoor wordt het bulkverkeer afgehandeld door de snelste processor, terwijl de oudere hardware stand-by staat als een naadloze failover-node. Beide servers blijven continu perfect synchroon lopen via de ingebouwde Technitium Cluster Sync applicatie.
π‘οΈ De Architectuur: Encryptie vs. Autonomie
Het doel van deze inrichting is absolute privacy binnen het lokale netwerk, gecombineerd met volledige onafhankelijkheid van publieke upstream DNS-providers (zoals Cloudflare, Google of Quad9). Dit vereist een strakke scheiding tussen inkomend en uitgaand verkeer:
1. Inkomend (Client naar Homelab): DNS-over-HTTPS (DoH)
Om het lokale netwerkverkeer te versleutelen, is Nginx Proxy Manager (NPM) ingezet binnen de Docker VM. NPM handles de inkomende beveiligde HTTPS-verbindingen af op poort 443 met behulp van een geldig Let's Encrypt Wildcard-certificaat.
Om complexe databasefouten of SSL-handshake-problemen (ERR_SSL_UNRECOGNIZED_NAME_ALERT) te voorkomen, is NPM bewust eenvoudig gehouden:
* Er zijn twee recht toe recht aan Proxy Hosts aangemaakt (dns1.example.com en dns2.example.com).
* NPM stuurt het verkeer op de achtergrond rechtstreeks door naar de Technitium LXC-containers op een specifieke DNS-over-HTTP poort (8053).
-
Split-Horizon DNS: Om dit lokaal bereikbaar te maken zonder internet-omweg, is er binnen Technitium een lokale zone ingericht voor
patad.nldiedns1endns2direct naar het lokale IP-adres van NPM laat verwijzen. -
Client Identificatie: In Technitium zijn de opties EDNS Client Subnet (ECS) and de X-Real-IP header geactiveerd. Hierdoor tonen de Technitium-logs exact welke lokale client de aanvraag doet, in plaats van dat overal het IP-adres van de proxy verschijnt.
2. Uitgaand (Homelab naar Internet): Pure Recursie + DNSSEC
Alle upstream forwarders zijn volledig uitgeschakeld. Technitium acteert als een Recursieve DNS-server. Dit betekent dat de server zelfstandig and direct de wereldwijde Root-servers, TLD-servers (Top-Level Domain) en geautoriseerde Name-servers raadpleegt.
Omdat de wereldwijde publieke DNS-infrastructuur momenteel nog geen TLS ondersteunt voor recursieve queries, maakt dit uitgaande verkeer gebruik van standaard UDP. Om absolute veiligheid tegen cache-poisoning en spoofing te garanderen, is DNSSEC-validatie strikt afgedwongen. Technitium valideert elke respons cryptografisch vanaf de root-server tot aan het eindstation.
π Benchmark Resultaten
Om de prestaties in de praktijk te meten, is een uitgebreid PowerShell-script geschreven. Het script leegt de lokale Windows DNS-cache vΓ³Γ³r elke aanvraag en plakt een willekeurig voorvoegsel (prefix) voor het doeldomein (bijv. ://google.com). Dit omzeilt de lokale cache van Technitium volledig and dwingt het cluster om voor elke controle een live, rauwe uitgaande recursie-query uit te voeren.
De testsuite bestaat uit exact 100 unieke top-domeinen verspreid over 5 verschillende geografische en regelgevende zones: Nederland (.nl), Duitsland (.de), Frankrijk (.fr), de Verenigde Staten (.com/.gov) and het Verenigd Koninkrijk (.uk).
De resultaten zijn fenomenaal:
-
dns1.example.com(Primair / 2024 AOOSTAR CPU): Behaalde een verbluffend gemiddelde van slechts 3 tot 5 milliseconden per query. Omdat deze server het primaire netwerkverkeer afhandelt, waren de wereldwijde root-hintstructuren al warmgedraaid in het RAM-geheugen, waardoor de Ryzen-processor de recursieve paden vrijwel direct berekende. Bovendien maakt Windows gebruik van TLS Session Resumption, waardoor de versleutelings-overhead van de HTTPS-tunnel met NPM tot nul wordt gereduceerd. -
dns2.example.com(Secundair / 2017 Lenovo CPU): Noteerde een solide gemiddelde van 11 to 13 milliseconden. Het kleine verschil van ~8ms is puur de tijd die de Windows-client nodig heeft om een frisse, aparte TLS-handshake met NPM op te starten voor het tweede subdomein. Zodra de socket open is, verloopt de verwerking onmiddellijk. -
Betrouwbaarheid: De test behaalde een succespercentage van 100% met nul pakketverlies of time-outs, wat bewijst dat de Technitium Reverse Proxy Network ACL and NPM zijn perfect op elkaar zijn afgestemd.
π Het PowerShell Benchmark-Script
Gebruik het onderstaande PowerShell-script binnen je Windows-beheeromgeving om de responstijden van je eigen DoH-infrastructuur nauwkeurig door te meten:
# --- REAL SPEEDTEST DNS DOH (HTTPS) WITH LOCAL CACHE FLUSH (100 DOMAINS) ---
\$DNSServers = @("dns2.example.com", "dns1.example.com") # Primaire snelle host wordt eerst getest
\(TestRuns = 1\)ThresholdMs = 75 # Grenswaarde voor rauwe recursieve uitschieters
# Uitgebreide lijst van exact 100 topdomeinen (NL, DE, FR, US, UK)
\$DomainList = @(
# --- Nederland (.nl) - 20 domeinen ---
"tweakers.net", "nu.nl", "nos.nl", "buienradar.nl", "bol.com", "rijksoverheid.nl", "rabobank.nl", "ing.nl", "kpn.com", "ziggo.nl", "coolblue.nl", "marktplaats.nl", "belastingdienst.nl", "nlnetlabs.nl", "surf.nl", "tudelft.nl", "uva.nl", "volkskrant.nl", "telegraaf.nl", "albertheijn.nl",
# --- Duitsland (.de) - 20 domeinen ---
"amazon.de", "spiegel.de", "bild.de", "tagesschau.de", "heise.de", "welt.de", "zeit.de", "focus.de", "golem.de", "computerbase.de", "ebay.de", "bahn.de", "otto.de", "zalando.de", "check24.de", "adac.de", "telekom.com", "bundesregierung.de", "dfb.de", "kit.edu",
# --- Frankrijk (.fr) - 20 domeinen ---
"lemonde.fr", "lefigaro.fr", "leparisien.fr", "lesechos.fr", "liberation.fr", "allocine.fr", "cdiscount.com", "fnac.com", "vinted.fr", "carrefour.fr", "sncf-connect.com", "impots.gouv.fr", "ameli.fr", "gouvernement.fr", "edf.fr", "orange.fr", "free.fr", "sfr.fr", "sorbonne-universite.fr", "lequipe.fr",
# --- Verenigde Staten (.com / .org / .gov) - 20 domeinen ---
"cloudflare.com", "ietf.org", "paypal.com", "verisign.com", "google.com", "microsoft.com", "wikipedia.org", "github.com", "amazon.com", "apple.com", "meta.com", "netflix.com", "nasa.gov", "usa.gov", "whitehouse.gov", "nytimes.com", "cnn.com", "mit.edu", "harvard.edu", "stanford.edu",
# --- Verenigd Koninkrijk (.uk) - 20 domeinen ---
"gov.uk", "bbc.co.uk", "nhs.uk", "ox.ac.uk", "cam.ac.uk", "coop.co.uk", "theguardian.com", "telegraph.co.uk", "hmv.com", "ba.com", "sky.com", "bt.com", "ee.co.uk", "vodafone.co.uk", "tesco.com", "sainsburys.co.uk", "asda.com", "argos.co.uk", "tfl.gov.uk", "manutd.com"
)
# Toestaan van interne homelab certificaten (DoH dwingt HTTPS af)
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {\(true}\)DesktopPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::Desktop)
CSVPath = DesktopPath + "\dns_100_domains_speed_report.csv"
Clear-Host
Write-Host "Starting ULTIMATE 100-Domain DoH Speed Test against Cluster..." -ForegroundColor Cyan
Write-Host "Testing Netherlands, Germany, France, US, and UK via NPM.`n" -ForegroundColor Yellow
$Results = @()
foreach ($Server in $DNSServers) {
Write-Host "Server: $Server" -ForegroundColor Magenta
for ($Run = 1; $Run -le $TestRuns; $Run++) {
$Count = 1
foreach ($Domain in $DomainList) {
# Genereer willekeurige prefix om caching in Technitium volledig te omzeilen
$RandomNumber = Get-Random -Min 100000 -Max 999999
$UniqueDomain = "${RandomNumber}.${Domain}"
# Lokale DNS cache flashen voor een zuivere meting
Clear-DnsClientCache
# DoH query meten via Resolve-DnsName
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
try {
$Response = Resolve-DnsName -Name $UniqueDomain -Server $Server -ErrorAction Stop
$Stopwatch.Stop()
$Duration = $Stopwatch.ElapsedMilliseconds
$Status = "Success"
} catch {
$Stopwatch.Stop()
$Duration = $Stopwatch.ElapsedMilliseconds
$Status = "Failed"
}
# Kleurcodering op basis van snelheid threshold
$Color = "Green"
if ($Duration -gt $ThresholdMs) { $Color = "Red" }
if ($Status -eq "Failed") { $Color = "DarkRed" }
Write-Host "[$Count/100] Domain: $UniqueDomain -> ${Duration}ms ($Status)" -ForegroundColor $Color
$Results += [PSCustomObject]@{
Server = $Server
Run = $Run
Domain = $Domain
UniqueUrl = $UniqueDomain
Duration = $Duration
Status = $Status
}
$Count++
}
}
}
# Resultaten exporteren naar het bureaublad
$Results | Export-Csv -Path $CSVPath -NoTypeInformation -Delimiter ","
Write-Host "`nTest voltooid! Rapport opgeslagen op: \$CSVPath" -ForegroundColor Green