summaryrefslogtreecommitdiff
path: root/modules/unbound.nix
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2024-04-21 02:15:42 +0300
committerAzat Bahawi <azat@bahawi.net>2024-04-21 02:15:42 +0300
commite6ed60548397627bf10f561f9438201dbba0a36e (patch)
treef9a84c5957d2cc4fcd148065ee9365a0c851ae1c /modules/unbound.nix
parent9ac64328603d44bd272175942d3ea3eaadcabd04 (diff)
2024-04-21
Diffstat (limited to 'modules/unbound.nix')
-rw-r--r--modules/unbound.nix225
1 files changed, 225 insertions, 0 deletions
diff --git a/modules/unbound.nix b/modules/unbound.nix
new file mode 100644
index 0000000..e71d48c
--- /dev/null
+++ b/modules/unbound.nix
@@ -0,0 +1,225 @@
+{
+ config,
+ lib,
+ pkgs,
+ this,
+ ...
+}:
+with lib;
+let
+ cfg = config.nixfiles.modules.unbound;
+in
+{
+ options.nixfiles.modules.unbound = {
+ enable = mkEnableOption "Unbound";
+
+ domain = mkOption {
+ description = "Domain name sans protocol scheme.";
+ type = with types; str;
+ default = config.networking.domain;
+ };
+ };
+
+ config =
+ let
+ adblock-conf = "${config.services.unbound.stateDir}/adblock.conf";
+ in
+ mkIf cfg.enable {
+ ark.directories = [ config.services.unbound.stateDir ];
+
+ nixfiles.modules.redis.enable = true;
+
+ services = {
+ unbound = {
+ enable = true;
+
+ package = pkgs.unbound-with-systemd.override {
+ withRedis = true;
+ withTFO = true;
+ };
+
+ checkconf = false;
+ settings = {
+ server = {
+ interface = with this.wireguard; [
+ "127.0.0.1"
+ "::1"
+ ipv4.address
+ ipv6.address
+ ];
+
+ local-zone = concatLists (
+ mapAttrsToList (h: _: [ "\"${h}.${cfg.domain}\" redirect" ]) my.configurations
+ );
+ local-data = concatLists (
+ mapAttrsToList (
+ hostname:
+ let
+ domain = "${hostname}.${cfg.domain}";
+ in
+ attr:
+ (optionals (hasAttr "wireguard" attr) (
+ with attr.wireguard;
+ [
+ "\"${domain} 604800 IN A ${ipv4.address}\""
+ "\"${domain} 604800 IN AAAA ${ipv6.address}\""
+ "\"${domain}. A ${ipv4.address}\""
+ "\"${domain}. AAAA ${ipv6.address}\""
+ ]
+ ++ concatMap (domain: [
+ "\"${domain}. A ${ipv4.address}\""
+ "\"${domain}. AAAA ${ipv6.address}\""
+ ]) attr.domains
+ ))
+ ) my.configurations
+ );
+ local-data-ptr = concatLists (
+ mapAttrsToList (
+ hostname:
+ let
+ domain = "${hostname}.${cfg.domain}";
+ in
+ attr:
+ (optionals (hasAttr "wireguard" attr) (
+ with attr.wireguard;
+ [
+ "\"${ipv4.address} ${domain}\""
+ "\"${ipv6.address} ${domain}\""
+ ]
+ ++ concatMap (domain: [
+ "\"${ipv4.address} ${domain}\""
+ "\"${ipv6.address} ${domain}\""
+ ]) attr.domains
+ ))
+ ) my.configurations
+ );
+
+ private-domain = map (domain: "${domain}.") [
+ cfg.domain
+ "local"
+ ];
+ private-address = with config.nixfiles.modules.wireguard; [
+ ipv4.subnet
+ ipv6.subnet
+ ];
+
+ access-control = with config.nixfiles.modules.wireguard; [
+ "0.0.0.0/0 refuse"
+ "::/0 refuse"
+ "127.0.0.0/8 allow"
+ "::1/128 allow"
+ "${ipv4.subnet} allow"
+ "${ipv6.subnet} allow"
+ ];
+
+ cache-min-ttl = 0;
+
+ serve-expired = true;
+ serve-expired-reply-ttl = 0;
+
+ prefetch = true;
+ prefetch-key = true;
+
+ hide-identity = true;
+ hide-version = true;
+
+ extended-statistics = true;
+
+ log-replies = false;
+ log-tag-queryreply = false;
+ log-local-actions = false;
+
+ verbosity = 0;
+
+ include = ''"${adblock-conf}"'';
+ };
+
+ forward-zone = [
+ {
+ name = ".";
+ forward-tls-upstream = true;
+ forward-addr =
+ let
+ mkDnsOverTls =
+ ips: auth:
+ map (
+ ip:
+ concatStrings [
+ ip
+ "@"
+ auth
+ ]
+ ) ips;
+ in
+ mkDnsOverTls dns.const.quad9.default "853#dns.quad9.net";
+ }
+ ];
+
+ cachedb = with config.services.redis.servers.default; {
+ backend = "redis";
+ redis-server-host = bind;
+ redis-server-port = port;
+ };
+ };
+
+ enableRootTrustAnchor = true;
+
+ localControlSocketPath = "/run/unbound/unbound.socket";
+ };
+
+ prometheus.exporters.unbound = {
+ enable = true;
+ listenAddress = mkDefault this.wireguard.ipv4.address;
+ port = 9167;
+ inherit (config.services.unbound) group user;
+ unbound.host = "unix://${config.services.unbound.localControlSocketPath}";
+ };
+ };
+
+ systemd = {
+ services = {
+ unbound.after = [ "unbound-adblock-update.service" ];
+
+ unbound-adblock-update = {
+ serviceConfig = with config.services.unbound; {
+ Type = "oneshot";
+ User = user;
+ Group = group;
+ ExecStart = getExe (
+ pkgs.writeShellApplication {
+ name = "unbound-adblock-update";
+ runtimeInputs = [
+ pkgs.curl
+ package
+ ];
+ text = ''
+ curl \
+ -s \
+ -o ${adblock-conf} \
+ "https://raw.githubusercontent.com/hagezi/dns-blocklists/main/unbound/multi.blacklist.conf"
+
+ if [[ -f "${localControlSocketPath}" ]]; then
+ unbound-control reload
+ fi
+ '';
+ }
+ );
+ };
+ };
+ };
+
+ timers.unbound-adblock-update = {
+ requires = [ "network-online.target" ];
+ after = [ "network-online.target" ];
+ timerConfig = {
+ OnCalendar = "daily";
+ Persistent = true;
+ Unit = "unbound-adblock-update.service";
+ };
+ wantedBy = [ "timers.target" ];
+ };
+ };
+
+ boot.kernel.sysctl."net.ipv4.tcp_fastopen" = mkOverride 200 3;
+ };
+}