{ hostRegistry, config, pkgs, ... }: let systemctl = "${pkgs.systemd}/bin/systemctl"; deployCommand = "${systemctl} start deploy-c3d2-dns"; reloadCommand = "${systemctl} reload bind"; restartCommand = "${systemctl} restart bind"; in { c3d2 = { isInHq = false; hq.statistics.enable = true; }; networking.hostName = "bind"; networking.useNetworkd = true; networking.interfaces.eth0.ipv4.addresses = [{ address = hostRegistry.hosts.${config.networking.hostName}.ip4; prefixLength = 26; }]; networking.defaultGateway = "172.20.73.1"; networking.firewall.allowedTCPPorts = [ # DNS 53 # HTTP(s) 80 443 ]; networking.firewall.allowedUDPPorts = [ # DNS 53 ]; # DNS server services.bind = { enable = true; extraConfig = '' include "${config.users.users.c3d2-dns.home}/c3d2-dns/zones.conf"; # for collectd statistics-channels { inet 127.0.0.1 port 8053; }; ''; }; systemd.services.bind = { serviceConfig = { Restart = "always"; RestartSec = "1s"; }; }; # BIND statistics in Grafana services.collectd.plugins.bind = '' URL "http://127.0.0.1:8053/"; ParseTime false OpCodes true QTypes true ServerStats true ZoneMaintStats true ResolverStats false MemoryStats true ''; # Build user users.groups.c3d2-dns = {}; users.users.c3d2-dns = { isSystemUser = true; group = "c3d2-dns"; home = "/var/lib/c3d2-dns"; }; systemd.tmpfiles.rules = [ "d ${config.users.users.c3d2-dns.home} 0755 c3d2-dns ${config.users.users.c3d2-dns.group} - -" "d /var/lib/bind/slave 0755 named nogroup - -" ]; # Build script systemd.services.deploy-c3d2-dns = let inherit (pkgs.bind-secrets) giteaToken sshPrivkey; in { wantedBy = [ "multi-user.target" ]; before = [ "bind.service" ]; path = with pkgs; [ git nix curl ]; script = '' mkdir -p .ssh cp ${builtins.toFile "id_ed25519" sshPrivkey} .ssh/id_ed25519 echo "gitea.c3d2.de ${hostRegistry.hosts.gitea.publicKey}" > .ssh/known_hosts chmod 0600 .ssh/id_ed25519 # Build at least once touch deploy-pending [ -d c3d2-dns ] || git clone --depth=1 gitea@gitea.c3d2.de:c3d2-admins/c3d2-dns.git cd c3d2-dns # Loop in case the webhook was called while we were building while [ -e ../deploy-pending ]; do rm ../deploy-pending git checkout . git pull REV=$(git rev-parse HEAD) set +e curl -X POST \ "https://gitea.c3d2.de/api/v1/repos/c3d2-admins/c3d2-dns/statuses/$REV?token=${giteaToken}" \ -H "accept: application/json" \ -H "Content-Type: application/json" \ -d "{ \"context\": \"c3d2-dns\", \"description\": \"reloading...\", \"state\": \"pending\"}" # Fix legacy paths (TODO) for f in *.conf ; do sed -e 's#/home/git/#${config.users.users.c3d2-dns.home}/#g' -i $f done # Allow creation of .jnl files by BIND for DynDNS chmod a+w zones # Take action if systemctl is-active -q bind; then /run/wrappers/bin/sudo ${reloadCommand} MSG=reload else /run/wrappers/bin/sudo ${restartCommand} MSG=restart fi if [ $? = 0 ]; then STATUS="{ \"context\": \"c3d2-dns\", \"description\": \""$MSG"ed\", \"state\": \"success\"}" else STATUS="{ \"context\": \"c3d2-dns\", \"description\": \"$MSG failure\", \"state\": \"failure\"}" fi curl -X POST \ "https://gitea.c3d2.de/api/v1/repos/c3d2-admins/c3d2-dns/statuses/$REV?token=${giteaToken}" \ -H "accept: application/json" \ -H "Content-Type: application/json" \ -d "$STATUS" set -e done ''; serviceConfig = { User = "c3d2-dns"; Group = config.users.users.c3d2-dns.group; PrivateTmp = true; ProtectSystem = "full"; ReadWritePaths = config.users.users.c3d2-dns.home; WorkingDirectory = config.users.users.c3d2-dns.home; }; }; # Privileged commands triggered by webhook/deploy-c3d2-dns security.sudo.extraRules = [ { users = [ "c3d2-dns" ]; commands = [ { command = deployCommand; options = [ "NOPASSWD" ]; } { command = reloadCommand; options = [ "NOPASSWD" ]; } { command = restartCommand; options = [ "NOPASSWD" ]; } ]; } ]; # Web server just for the webhook services.nginx = { enable = true; virtualHosts = { # hooks, logs "bind.serv.zentralwerk.org" = { default = true; enableACME = true; forceSSL = true; locations."/hooks/".proxyPass = "http://localhost:9000/hooks/"; }; }; }; # Webhook service systemd.services.webhook = let hooksJson = pkgs.writeText "hooks.json" (builtins.toJSON [ { id = "deploy-c3d2-dns"; execute-command = pkgs.writeShellScript "deploy-c3d2-dns" '' # Request (re-)deployment touch ${config.users.users.c3d2-dns.home}/deploy-pending # Start deploy-c3d2-dns.service if not already running exec /run/wrappers/bin/sudo ${deployCommand} ''; } ]); in { wantedBy = [ "multi-user.target" ]; serviceConfig = { ExecStart = "${pkgs.webhook}/bin/webhook -hooks ${hooksJson} -verbose -ip 127.0.0.1"; User = "c3d2-dns"; Group = config.users.users.c3d2-dns.group; PrivateTmp = true; ProtectSystem = "full"; }; }; }