[ci skip] Fix Technitium DNS client IP logging: bypass Traefik L4 proxy

DNS queries were going through Traefik's IngressRouteUDP, replacing
real client IPs with Traefik pod IPs (10.10.169.150) in Technitium logs.
Changed Technitium DNS service from NodePort to LoadBalancer with
externalTrafficPolicy: Local, removed dns-udp entrypoint and
IngressRouteUDP from Traefik, and updated CoreDNS to forward .lan
queries to Technitium's LoadBalancer IP directly.
This commit is contained in:
Viktor Barzin 2026-02-16 21:16:16 +00:00
parent 3d4cdf3203
commit 205eb2704b
No known key found for this signature in database
GPG key ID: 0EB088298288D958
2 changed files with 45 additions and 46 deletions

View file

@ -19,7 +19,7 @@ module "tls_secret" {
}
# CoreDNS Corefile - manages cluster DNS resolution
# The viktorbarzin.lan block forwards to Technitium via NodePort.
# The viktorbarzin.lan block forwards to Technitium via LoadBalancer.
# The cluster.local.viktorbarzin.lan block short-circuits junk queries caused by
# ndots:5 search domain expansion (e.g. redis.redis.svc.cluster.local.viktorbarzin.lan)
# which would otherwise flood Technitium with NxDomain queries.
@ -67,7 +67,7 @@ resource "kubernetes_config_map" "coredns" {
viktorbarzin.lan:53 {
#log
errors
forward . 10.0.20.101:30053 # Technitium NodePort
forward . 10.0.20.204 # Technitium LoadBalancer
cache {
success 10000 300 6
denial 10000 300 60
@ -109,8 +109,24 @@ resource "kubernetes_deployment" "technitium" {
}
}
spec {
node_name = "k8s-node1" # Horrible hack but only way I found to preserve client ip
# if moved, update the corefile for coredns as that's forwarding queries for viktorbarzin.lan
# Prefer nodes running Traefik for network locality
affinity {
pod_affinity {
preferred_during_scheduling_ignored_during_execution {
weight = 100
pod_affinity_term {
label_selector {
match_expressions {
key = "app.kubernetes.io/name"
operator = "In"
values = ["traefik"]
}
}
topology_key = "kubernetes.io/hostname"
}
}
}
}
container {
image = "technitium/dns-server:latest"
name = "technitium"
@ -199,25 +215,18 @@ resource "kubernetes_service" "technitium-dns" {
labels = {
"app" = "technitium"
}
annotations = {
"metallb.universe.tf/allow-shared-ip" : "shared"
}
}
spec {
# type = "LoadBalancer"
# external_traffic_policy = "Cluster"
type = "NodePort"
type = "LoadBalancer"
port {
name = "technitium-dns"
port = 53
node_port = 30053
protocol = "UDP"
name = "technitium-dns"
port = 53
protocol = "UDP"
}
external_traffic_policy = "Local"
selector = {
app = "technitium"
}
}
}

View file

@ -29,6 +29,27 @@ resource "helm_release" "traefik" {
"diun.enable" = "true"
"diun.include_tags" = "^v\\d+(?:\\.\\d+)?(?:\\.\\d+)?.*$"
}
initContainers = [{
name = "download-plugins"
image = "alpine:3"
command = ["sh", "-c", join("", [
"set -e; ",
"STORAGE=/plugins-storage; ",
"mkdir -p \"$STORAGE/archives/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin\"; ",
"mkdir -p \"$STORAGE/archives/github.com/packruler/rewrite-body\"; ",
"wget -q -T 30 -O \"$STORAGE/archives/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/v1.4.2.zip\" ",
"\"https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/archive/refs/tags/v1.4.2.zip\"; ",
"wget -q -T 30 -O \"$STORAGE/archives/github.com/packruler/rewrite-body/v1.2.0.zip\" ",
"\"https://github.com/packruler/rewrite-body/archive/refs/tags/v1.2.0.zip\"; ",
"printf '{\"github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin\":\"v1.4.2\",\"github.com/packruler/rewrite-body\":\"v1.2.0\"}' ",
"> \"$STORAGE/archives/state.json\"; ",
"echo \"Plugins pre-downloaded successfully\"",
])]
volumeMounts = [{
name = "plugins"
mountPath = "/plugins-storage"
}]
}]
}
updateStrategy = {
@ -91,12 +112,6 @@ resource "helm_release" "traefik" {
advertisedPort = 443
}
}
dns-udp = {
port = 5353
exposedPort = 53
protocol = "UDP"
expose = { default = true }
}
whisper-tcp = {
port = 10300
exposedPort = 10300
@ -120,7 +135,6 @@ resource "helm_release" "traefik" {
service = {
type = "LoadBalancer"
annotations = {
# Temporary IP during migration; will move to nginx's 10.0.20.202 once nginx is removed
"metallb.universe.tf/loadBalancerIPs" = "10.0.20.202"
}
spec = {
@ -189,30 +203,6 @@ resource "helm_release" "traefik" {
})]
}
# DNS UDP passthrough to Technitium
resource "kubernetes_manifest" "dns_udp_ingressroute" {
manifest = {
apiVersion = "traefik.io/v1alpha1"
kind = "IngressRouteUDP"
metadata = {
name = "dns-udp"
namespace = kubernetes_namespace.traefik.metadata[0].name
}
spec = {
entryPoints = ["dns-udp"]
routes = [{
services = [{
name = "technitium-dns"
namespace = "technitium"
port = 53
}]
}]
}
}
depends_on = [helm_release.traefik]
}
# Dashboard resources
module "tls_secret" {
source = "../setup_tls_secret"