209 lines
5.5 KiB
Nix
209 lines
5.5 KiB
Nix
{ zentralwerk, config, pkgs, ... }:
|
|
let
|
|
systemctl = "${pkgs.systemd}/bin/systemctl";
|
|
deployCommand = "${systemctl} start deploy-c3d2-dns";
|
|
# wrap reload in freeze/thaw so that zones are reloaded that had
|
|
# been updated by dyndns
|
|
reloadCommand = with pkgs; writeScript "reload-bind" ''
|
|
#! ${runtimeShell}
|
|
|
|
rndc() {
|
|
${bind}/sbin/rndc -k /etc/bind/rndc.key $@
|
|
}
|
|
|
|
rndc freeze
|
|
rndc reload
|
|
rndc thaw
|
|
'';
|
|
in
|
|
{
|
|
c3d2 = {
|
|
hq.statistics.enable = true;
|
|
deployment.server = "server10";
|
|
};
|
|
|
|
system.stateVersion = "22.05";
|
|
|
|
networking = {
|
|
hostName = "bind";
|
|
firewall = {
|
|
allowedTCPPorts = [
|
|
# DNS
|
|
53
|
|
];
|
|
allowedUDPPorts = [
|
|
# DNS
|
|
53
|
|
];
|
|
};
|
|
};
|
|
|
|
sops = {
|
|
defaultSopsFile = ./secrets.yaml;
|
|
secrets."c3d2-dns/gitea-token".owner = config.systemd.services.deploy-c3d2-dns.serviceConfig.User;
|
|
secrets."c3d2-dns/ssh-private-key".owner = config.systemd.services.deploy-c3d2-dns.serviceConfig.User;
|
|
};
|
|
|
|
# DNS server
|
|
services.bind = {
|
|
enable = true;
|
|
extraConfig = ''
|
|
include "${config.users.users.c3d2-dns.home}/c3d2-dns/zones.conf";
|
|
include "${zentralwerk.packages.${pkgs.system}.dns-slaves}";
|
|
|
|
# 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 = {
|
|
wantedBy = [ "multi-user.target" ];
|
|
before = [ "bind.service" ];
|
|
after = [ "network-online.target" ];
|
|
path = with pkgs; [ git nix curl openssh ];
|
|
script = ''
|
|
mkdir -p .ssh
|
|
cp ${config.sops.secrets."c3d2-dns/ssh-private-key".path} .ssh/id_ed25519
|
|
chmod 0600 .ssh/id_ed25519
|
|
|
|
# Build at least once
|
|
touch deploy-pending
|
|
|
|
status() {
|
|
curl -X POST \
|
|
"https://gitea.c3d2.de/api/v1/repos/c3d2-admins/c3d2-dns/statuses/$REV?token=$(cat ${config.sops.secrets."c3d2-dns/gitea-token".path})" \
|
|
-H "accept: application/json" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$1"
|
|
}
|
|
|
|
[ -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
|
|
status "{ \"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
|
|
# Clean up .jnl files
|
|
rm -f zones/*.jnl
|
|
# Take action
|
|
if systemctl is-active -q bind; then
|
|
/run/wrappers/bin/sudo ${reloadCommand}
|
|
fi
|
|
|
|
if [ $? = 0 ]; then
|
|
status "{ \"context\": \"c3d2-dns\", \"description\": \"reloaded\", \"state\": \"success\"}"
|
|
else
|
|
status "{ \"context\": \"c3d2-dns\", \"description\": \"reload failure\", \"state\": \"failure\"}"
|
|
fi
|
|
|
|
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 = toString reloadCommand;
|
|
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";
|
|
};
|
|
};
|
|
}
|