diff --git a/servers/legion/adguard.tf b/servers/legion/adguard.tf index 5dfd241..ef6d8d0 100644 --- a/servers/legion/adguard.tf +++ b/servers/legion/adguard.tf @@ -42,6 +42,65 @@ resource "kubernetes_persistent_volume_claim" "adguard_data" { } } +# Desired AdGuard settings — applied by init container on every pod start. +# To change DNS upstreams, filter lists, or rewrites: edit here, terraform apply, then push apps/adguard.yaml. +resource "kubernetes_config_map" "adguard_defaults" { + metadata { + name = "adguard-defaults" + namespace = kubernetes_namespace.dns.metadata[0].name + } + + data = { + "AdGuardHome.yaml" = <<-EOT + dns: + bind_hosts: + - 0.0.0.0 + port: 53 + upstream_dns: + - https://dns.cloudflare.com/dns-query + - https://dns.google/dns-query + bootstrap_dns: + - 1.1.1.1 + - 8.8.8.8 + - 9.9.9.10 + - 149.112.112.10 + upstream_mode: load_balance + cache_enabled: true + cache_size: 4194304 + filters: + - enabled: true + url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt + name: AdGuard DNS filter + id: 1 + - enabled: true + url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt + name: AdAway Default Blocklist + id: 2 + - enabled: true + url: https://big.oisd.nl/domainswild + name: OISD Big + id: 3 + - enabled: true + url: https://easylist.to/easylist/easylist.txt + name: EasyList + id: 4 + - enabled: true + url: https://easylist.to/easylist/easyprivacy.txt + name: EasyPrivacy + id: 5 + filtering: + filtering_enabled: true + rewrites: + - domain: '*.nook.family' + answer: ${var.legion_ip} + enabled: true + - domain: '*.neuralplatform.dev' + answer: ${var.legion_ip} + enabled: true + EOT + } +} + # Deployment + Service managed by Argo CD — see servers/legion/apps/adguard.yaml resource "kubernetes_ingress_v1" "adguard" { diff --git a/servers/legion/apps/adguard.yaml b/servers/legion/apps/adguard.yaml index 3c5bdf6..b04e85d 100644 --- a/servers/legion/apps/adguard.yaml +++ b/servers/legion/apps/adguard.yaml @@ -20,29 +20,59 @@ spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet initContainers: - - name: fix-bind-hosts + - name: apply-config image: python:3.12-alpine command: ["python3", "-c"] args: - | - import re, os - config = "/opt/adguardhome/conf/AdGuardHome.yaml" - if os.path.exists(config): - with open(config) as f: - content = f.read() - content = re.sub( - r'(bind_hosts:\n)((?:[ \t]*- .*\n)*)', - 'bind_hosts:\n - 0.0.0.0\n', - content - ) - with open(config, "w") as f: - f.write(content) - print("bind_hosts set to 0.0.0.0") + import yaml, os, shutil + + CONFIG = "/opt/adguardhome/conf/AdGuardHome.yaml" + DEFAULT = "/opt/adguard-defaults/AdGuardHome.yaml" + + with open(DEFAULT) as f: + desired = yaml.safe_load(f) + + if not os.path.exists(CONFIG): + # First run — seed from defaults + shutil.copy(DEFAULT, CONFIG) + print("First run: seeded config from defaults") else: - print("No config yet — AdGuard will create it on first run") + with open(CONFIG) as f: + cfg = yaml.safe_load(f) + + # Enforce bind_hosts + cfg.setdefault("dns", {})["bind_hosts"] = ["0.0.0.0"] + + # Enforce upstream + bootstrap DNS + cfg["dns"]["upstream_dns"] = desired["dns"]["upstream_dns"] + cfg["dns"]["bootstrap_dns"] = desired["dns"]["bootstrap_dns"] + + # Ensure desired filter lists are all present and enabled + existing = {f["url"]: f for f in cfg.get("filters", [])} + for df in desired.get("filters", []): + if df["url"] in existing: + existing[df["url"]]["enabled"] = True + else: + cfg.setdefault("filters", []).append(df) + + # Fix/ensure rewrites + cfg.setdefault("filtering", {}) + existing_rw = {rw["domain"]: rw for rw in cfg["filtering"].get("rewrites", [])} + for rw in desired.get("filtering", {}).get("rewrites", []): + if rw["domain"] in existing_rw: + existing_rw[rw["domain"]]["answer"] = rw["answer"] + else: + cfg["filtering"].setdefault("rewrites", []).append(rw) + + with open(CONFIG, "w") as f: + yaml.dump(cfg, f, default_flow_style=False, allow_unicode=True) + print("Config patched: DNS upstreams, filter lists, rewrites enforced") volumeMounts: - name: config mountPath: /opt/adguardhome/conf + - name: defaults + mountPath: /opt/adguard-defaults containers: - name: adguard image: adguard/adguardhome:latest @@ -75,6 +105,9 @@ spec: - name: data persistentVolumeClaim: claimName: adguard-data + - name: defaults + configMap: + name: adguard-defaults --- apiVersion: v1 kind: Service