# SPDX-FileCopyrightText: 2023-2024 Simon Bruder # # SPDX-License-Identifier: AGPL-3.0-or-later { config, lib, pkgs, ... }: let cfg = pkgs.callPackage ./common.nix { }; in { services.dnsmasq = { enable = true; settings = { bogus-priv = true; # do not forward revese lookups of internal addresses domain-needed = true; # do not forward names without domain interface = lib.mapAttrsToList (name: config: "br-${name}") cfg.vlan; # only respond to queries from own interfaces no-hosts = true; # do not resolve hosts from /etc/hosts no-resolv = true; # only use explicitly configured resolvers dhcp-fqdn = true; # only insert qualified names of DHCP clients into DNS cache-size = 10000; domain = [ "invalid.sbruder.de" # used when no rule below matches ] ++ (lib.flatten (lib.mapAttrsToList (name: { domain, subnet, ... }: [ "${domain},br-${name}" # only this is not enough "${domain},${subnet.v4.cidr}" "${domain},${subnet.v6.cidr}" ]) cfg.vlan)); # Allow resolving the router interface-name = lib.mapAttrsToList (name: { domain, ... }: "${config.networking.hostName}.${domain},br-${name}") cfg.vlan; dhcp-range = lib.flatten (lib.mapAttrsToList (name: { subnet, ... }: [ "tag:br-${name},${subnet.v4.withoutLastComponent}2,${subnet.v4.withoutLastComponent}254,12h" # DHCPv4 "tag:br-${name},${subnet.v6.net},ra-stateless,ra-names" # SLAAC (for addresses) / DHCPv6 (for DNS) ]) cfg.vlan); dhcp-option = lib.flatten (lib.mapAttrsToList (name: { subnet, ... }: [ # Gateway "tag:br-${name},option:router,${subnet.v4.gateway}" "tag:br-${name},option6:dns-server,${subnet.v6.gateway}" # NTP server (runs on gateway) "tag:br-${name},option:ntp-server,${subnet.v4.gateway}" "tag:br-${name},option6:ntp-server,${subnet.v6.gateway}" ]) cfg.vlan); server = [ "127.0.0.1#5053" ]; # Authoritative zones for external reachability (only AAAA records) auth-server = "shinobu.shinonome-lab.de,2001:470:73b9::1"; auth-zone = map (vlan: "${vlan.domain},${vlan.subnet.v6.cidr}") (lib.attrValues cfg.vlan); }; }; systemd.services.dnsmasq.after = [ "systemd-networkd.service" ]; networking.firewall.allowedUDPPorts = [ 53 67 ]; networking.firewall.allowedTCPPorts = [ 53 ]; services.prometheus.exporters.dnsmasq = { enable = true; listenAddress = config.sbruder.wireguard.home.address; leasesPath = "/var/lib/dnsmasq/dnsmasq.leases"; }; services.https-dns-proxy = { enable = true; provider = { kind = "custom"; ips = [ "9.9.9.9" "149.112.112.112" ]; url = "https://dns.quad9.net/dns-query"; }; }; }