From 2cdfec2086caa0ac4dfe99f2bc6ae566f62c7f52 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 17 Mar 2026 17:59:52 +0100 Subject: [PATCH 1/4] blocking-nameserver: Init --- .../nixos/services/nameservers/blocking.nix | 95 +++++++++++++++++++ .../nixos/services/nameservers/recursive.nix | 38 +++----- 2 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 modules/nixos/services/nameservers/blocking.nix diff --git a/modules/nixos/services/nameservers/blocking.nix b/modules/nixos/services/nameservers/blocking.nix new file mode 100644 index 0000000..2686bdc --- /dev/null +++ b/modules/nixos/services/nameservers/blocking.nix @@ -0,0 +1,95 @@ +{ + config, + lib, + allHosts, + ... +}: +let + cfg = config.custom.services.blocking-nameserver; + netCfg = config.custom.networking; + + recursiveNameservers = + allHosts + |> lib.attrValues + |> lib.filter (host: host.config.custom.services.recursive-nameserver.enable) + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}:${toString host.config.custom.services.recursive-nameserver.port}" + ); +in +{ + options.custom.services.blocking-nameserver = { + enable = lib.mkEnableOption ""; + port = lib.mkOption { + type = lib.types.port; + default = 53; + }; + gui = { + domain = lib.mkOption { + type = lib.types.nonEmptyStr; + default = ""; + }; + port = lib.mkOption { + type = lib.types.port; + default = 58479; + }; + }; + }; + + config = lib.mkIf cfg.enable { + services = { + adguardhome = { + enable = true; + mutableSettings = false; + + host = "127.0.0.1"; + inherit (cfg.gui) port; + + settings = { + dns = { + bind_hosts = [ netCfg.overlay.address ]; + inherit (cfg) port; + + upstream_dns = + if (recursiveNameservers != [ ]) then recursiveNameservers else [ "9.9.9.9#dns.quad9.net" ]; + upstream_mode = "parallel"; + bootstrap_dns = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; + + filtering = { + protection_enabled = true; + filtering_enabled = true; + }; + filters = lib.singleton { + enabled = true; + url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt"; + }; + }; + }; + + nebula.networks.mesh.firewall.inbound = lib.singleton { + inherit (cfg) port; + proto = "any"; + host = "any"; + }; + }; + + systemd.services.adguardhome = { + enableStrictShellChecks = false; + requires = [ netCfg.overlay.systemdUnit ]; + after = [ netCfg.overlay.systemdUnit ]; + }; + + custom = { + services.caddy.virtualHosts.${cfg.gui.domain}.port = lib.mkIf (cfg.gui.domain != null) cfg.gui.port; + + meta.sites.${cfg.gui.domain} = lib.mkIf (cfg.gui.domain != null) { + title = "Adguard Home"; + icon = "sh:adguard-home"; + }; + }; + }; +} diff --git a/modules/nixos/services/nameservers/recursive.nix b/modules/nixos/services/nameservers/recursive.nix index 894c2e1..5ce0e40 100644 --- a/modules/nixos/services/nameservers/recursive.nix +++ b/modules/nixos/services/nameservers/recursive.nix @@ -1,7 +1,5 @@ { config, - inputs, - pkgs, lib, allHosts, ... @@ -10,27 +8,21 @@ let cfg = config.custom.services.recursive-nameserver; netCfg = config.custom.networking; - blocklist = - pkgs.runCommand "blocklist.conf" { } '' - echo "server:" > $out - cat ${inputs.blocklist}/hosts \ - | grep '^0.0.0.0 ' \ - | awk '$2 != "0.0.0.0" {print " local-zone: \"" $2 "\" refuse"}' \ - >> $out - '' - |> toString; - privateNameservers = allHosts |> lib.attrValues - |> lib.filter (host: host.config.custom.services.private-nameserver.enable); + |> lib.filter (host: host.config.custom.services.private-nameserver.enable) + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}@${toString host.config.custom.services.private-nameserver.port}" + ); in { options.custom.services.recursive-nameserver = { enable = lib.mkEnableOption ""; port = lib.mkOption { type = lib.types.port; - default = 53; + default = 5336; }; blockAds = lib.mkEnableOption ""; }; @@ -41,13 +33,10 @@ in services = { unbound = { enable = true; - settings = { - server = { - interface = [ "${netCfg.overlay.address}@${toString cfg.port}" ]; - access-control = [ "${toString netCfg.overlay.networkCidr} allow" ]; - prefetch = true; - }; - include-toplevel = lib.mkIf cfg.blockAds blocklist; + settings.server = { + interface = [ "${netCfg.overlay.address}@${toString cfg.port}" ]; + access-control = [ "${toString netCfg.overlay.networkCidr} allow" ]; + prefetch = true; }; }; @@ -73,12 +62,7 @@ in stub-zone = lib.singleton { name = netCfg.overlay.domain; - stub-addr = - privateNameservers - |> lib.map ( - host: - "${host.config.custom.networking.overlay.address}@${toString host.config.custom.services.private-nameserver.port}" - ); + stub-addr = privateNameservers; }; }; }) From 1c0cb61cdfb39170f676e2c4cfa5fa18b23dc667 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 17 Mar 2026 18:03:53 +0100 Subject: [PATCH 2/4] srv-core, vps-ns: Enable blocking-nameserver --- hosts/srv-core/configuration.nix | 5 +++-- hosts/vps-ns/configuration.nix | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/hosts/srv-core/configuration.nix b/hosts/srv-core/configuration.nix index 5bdf6fe..e912bac 100644 --- a/hosts/srv-core/configuration.nix +++ b/hosts/srv-core/configuration.nix @@ -17,10 +17,11 @@ }; services = { - recursive-nameserver = { + blocking-nameserver = { enable = true; - blockAds = true; + gui.domain = "adguard.${config.custom.networking.overlay.fqdn}"; }; + recursive-nameserver.enable = true; private-nameserver.enable = true; syncthing = { diff --git a/hosts/vps-ns/configuration.nix b/hosts/vps-ns/configuration.nix index 98d0660..d19b173 100644 --- a/hosts/vps-ns/configuration.nix +++ b/hosts/vps-ns/configuration.nix @@ -1,4 +1,4 @@ -{ self, ... }: +{ config, self, ... }: { imports = [ self.nixosModules.server-profile ]; @@ -21,10 +21,11 @@ }; services = { - recursive-nameserver = { + blocking-nameserver = { enable = true; - blockAds = true; + gui.domain = "adguard.${config.custom.networking.overlay.fqdn}"; }; + recursive-nameserver.enable = true; private-nameserver.enable = true; public-nameserver = { enable = true; From 5f8b5c04b334c7dce13830361fac936a8cc0c0a7 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 17 Mar 2026 18:04:34 +0100 Subject: [PATCH 3/4] networking/overlay: Use blocking-nameservers as default nameservers --- modules/nixos/networking/overlay.nix | 27 +++++++++++++++++++-------- tests/overlay/default.nix | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/modules/nixos/networking/overlay.nix b/modules/nixos/networking/overlay.nix index 007e012..d2166a6 100644 --- a/modules/nixos/networking/overlay.nix +++ b/modules/nixos/networking/overlay.nix @@ -6,6 +6,24 @@ }: let cfg = config.custom.networking.overlay; + + blocking-nameservers = + allHosts + |> lib.attrValues + |> lib.filter (host: host.config.custom.services.blocking-nameserver.enable) + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}:${toString host.config.custom.services.blocking-nameserver.port}" + ); + + recursive-nameservers = + allHosts + |> lib.attrValues + |> lib.filter (host: host.config.custom.services.recursive-nameserver.enable) + |> lib.map ( + host: + "${host.config.custom.networking.overlay.address}:${toString host.config.custom.services.recursive-nameserver.port}" + ); in { options.custom.networking.overlay = { @@ -60,14 +78,7 @@ in dnsServers = lib.mkOption { type = lib.types.listOf lib.types.nonEmptyStr; - default = - allHosts - |> lib.attrValues - |> lib.filter (host: host.config.custom.services.recursive-nameserver.enable) - |> lib.map ( - host: - "${host.config.custom.networking.overlay.address}:${toString host.config.custom.services.recursive-nameserver.port}" - ); + default = if (blocking-nameservers != [ ]) then blocking-nameservers else recursive-nameservers; }; implementation = lib.mkOption { diff --git a/tests/overlay/default.nix b/tests/overlay/default.nix index 5d91468..a7ff7e3 100644 --- a/tests/overlay/default.nix +++ b/tests/overlay/default.nix @@ -105,7 +105,7 @@ client2.wait_for_unit("${client2NetCfg.overlay.systemdUnit}") lighthouse.wait_for_unit("unbound.service") - lighthouse.wait_for_open_port(53, "${lighthouseNetCfg.overlay.address}") + lighthouse.wait_for_open_port(${toString nodes.lighthouse.custom.services.recursive-nameserver.port}, "${lighthouseNetCfg.overlay.address}") server.wait_for_unit("sshd.service") client2.wait_for_unit("sshd.service") From c25c4341b3f1edd1e9c4f9bcdd324dd68ecb0211 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 17 Mar 2026 18:38:34 +0100 Subject: [PATCH 4/4] glance: Refactor site widgets --- modules/nixos/web-services/glance.nix | 51 +++++++++++++-------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/modules/nixos/web-services/glance.nix b/modules/nixos/web-services/glance.nix index c184e05..0cd3a12 100644 --- a/modules/nixos/web-services/glance.nix +++ b/modules/nixos/web-services/glance.nix @@ -8,18 +8,33 @@ let cfg = config.custom.web-services.glance; - observabilityTitles = [ - "Alloy" - "Prometheus" - "Alertmanager" - ]; + perHostDomains = + perHostSitesWidget.widgets |> lib.concatMap (widget: widget.sites) |> lib.map (site: site.domain); - hosts = allHosts |> lib.attrValues; + perHostSitesWidget = + allHosts + |> lib.attrValues + |> lib.map (host: { + type = "monitor"; + cache = "1m"; + title = host.config.networking.hostName; + sites = + host.config.custom.meta.sites + |> lib.attrValues + |> lib.filter (site: site.domain |> lib.hasSuffix host.config.custom.networking.overlay.fqdn); + }) + |> lib.filter ({ sites, ... }: sites != [ ]) + |> (widgets: { + type = "split-column"; + max-columns = widgets |> lib.length; + inherit widgets; + }); applicationSitesWidget = - hosts + allHosts + |> lib.attrValues |> lib.concatMap (host: host.config.custom.meta.sites |> lib.attrValues) - |> lib.filter (service: !lib.elem service.title observabilityTitles) + |> lib.filter (service: !lib.elem service.domain perHostDomains) |> lib.groupBy ( service: service.domain |> self.lib.isPrivateDomain |> (isPrivate: if isPrivate then "Private" else "Public") @@ -38,24 +53,6 @@ let inherit widgets; }); - observabilitySitesWidget = - hosts - |> lib.map (host: { - type = "monitor"; - cache = "1m"; - title = host.config.networking.hostName; - sites = - host.config.custom.meta.sites - |> lib.attrValues - |> lib.filter (service: lib.elem service.title observabilityTitles); - }) - |> lib.filter ({ sites, ... }: sites != [ ]) - |> (widgets: { - type = "split-column"; - max-columns = widgets |> lib.length; - inherit widgets; - }); - githubWorkflowFiles = "${self}/.github/workflows" |> builtins.readDir @@ -129,7 +126,7 @@ in autofocus = false; } applicationSitesWidget - observabilitySitesWidget + perHostSitesWidget ]; } {