{ ... }: # AdGuard Home — network DNS (adblock) + DHCP. # Forwards to the local unbound recursive resolver (services/unbound.nix). # Config is nix-owned (mutableSettings = false): the web UI can view but not # persist changes — edit here and redeploy. EXCEPTION: DHCP static leases live # in AdGuard's separate leases.json, so add those in the UI (they persist). { services.adguardhome = { enable = true; openFirewall = true; # opens the web + DNS ports mutableSettings = false; # AdGuardHome.yaml is authoritative from nix # allowDHCP is implied by settings.dhcp.enabled (grants NET_RAW/NET_BIND). settings = { # Web UI on :3000. Admin login — replace with YOUR bcrypt hash: # nix run nixpkgs#apacheHttpd -- htpasswd -B -n -b admin 'yourpassword' # (take the part after "admin:"). For repo hygiene, move this to sops later. http.address = "0.0.0.0:3000"; users = [ { name = "admin"; password = "$2y$10$REPLACE-WITH-BCRYPT-HASH"; } ]; dns = { bind_hosts = [ "0.0.0.0" ]; port = 53; # Recursive resolution via local unbound — no public upstream. upstream_dns = [ "127.0.0.1:5335" ]; bootstrap_dns = [ "1.1.1.1" "9.9.9.9" ]; upstream_mode = "load_balance"; }; filtering.filtering_enabled = true; filters = [ { enabled = true; id = 1; name = "AdGuard DNS filter"; url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt"; } { enabled = true; id = 2; name = "AdAway Default Blocklist"; url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt"; } ]; # ---- DHCP (replaces pihole's) ---- dhcp = { enabled = true; interface_name = "eth0"; local_domain_name = "sol"; # clients resolve as .sol dhcpv4 = { gateway_ip = "10.0.0.1"; subnet_mask = "255.255.255.0"; range_start = "10.0.0.50"; range_end = "10.0.0.200"; lease_duration = 86400; }; }; # Static lease: add jupiter (10.0.0.20) via the UI once — persists in # leases.json. Needs jupiter's eth MAC (`ip link` on jupiter). }; }; networking.firewall.allowedUDPPorts = [ 67 ]; # DHCP (DNS/web via openFirewall) }