Merge pull request 'acme-dns.nix: one systemd attrset (statix W20) — lint gate green' (#34) from chore/statix-fix into main
acme-dns.nix: one systemd attrset (statix W20) — lint gate green (#34)
This commit was merged in pull request #34.
This commit is contained in:
+71
-64
@@ -60,79 +60,86 @@ in
|
||||
|
||||
environment.etc."acme-dns/lego.env".source = legoEnvironment;
|
||||
|
||||
# The staging order has completed successfully. This marker permits the
|
||||
# production ACME post-run hook to hand a renewed certificate to Traefik.
|
||||
systemd.tmpfiles.rules = [
|
||||
"f /var/lib/ci-certs/acme-production-enabled 0600 root root -"
|
||||
];
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 53 ];
|
||||
allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
systemd.services.acme-dns = {
|
||||
description = "Restricted authoritative DNS for cc-ci ACME DNS-01";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = "acme-dns";
|
||||
Group = "acme-dns";
|
||||
StateDirectory = "acme-dns";
|
||||
StateDirectoryMode = "0700";
|
||||
WorkingDirectory = "/var/lib/acme-dns";
|
||||
ExecStart = "${pkgs.acme-dns}/bin/acme-dns -c ${acmeDnsConfig}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
ReadWritePaths = [ "/var/lib/acme-dns" ];
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ];
|
||||
|
||||
|
||||
# One `systemd` attrset (statix W20): the tmpfiles marker, the acme-dns daemon and the
|
||||
# traefik handoff oneshot.
|
||||
systemd = {
|
||||
# The staging order has completed successfully. This marker permits the
|
||||
# production ACME post-run hook to hand a renewed certificate to Traefik.
|
||||
tmpfiles.rules = [
|
||||
"f /var/lib/ci-certs/acme-production-enabled 0600 root root -"
|
||||
];
|
||||
|
||||
services.acme-dns = {
|
||||
description = "Restricted authoritative DNS for cc-ci ACME DNS-01";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = "acme-dns";
|
||||
Group = "acme-dns";
|
||||
StateDirectory = "acme-dns";
|
||||
StateDirectoryMode = "0700";
|
||||
WorkingDirectory = "/var/lib/acme-dns";
|
||||
ExecStart = "${pkgs.acme-dns}/bin/acme-dns -c ${acmeDnsConfig}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
ReadWritePaths = [ "/var/lib/acme-dns" ];
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Traefik consumes its wildcard as immutable Swarm secrets, so a renewed
|
||||
# host certificate must be copied and reconciled rather than merely reloaded.
|
||||
# This service is started only by the production-mode ACME postRun hook.
|
||||
systemd.services.cc-ci-acme-traefik-handoff = {
|
||||
description = "Install renewed cc-ci wildcard into Traefik Swarm secrets";
|
||||
after = [ "docker.service" "deploy-proxy.service" ];
|
||||
requires = [ "docker.service" ];
|
||||
path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
UMask = "0077";
|
||||
# Traefik consumes its wildcard as immutable Swarm secrets, so a renewed
|
||||
# host certificate must be copied and reconciled rather than merely reloaded.
|
||||
# This service is started only by the production-mode ACME postRun hook.
|
||||
services.cc-ci-acme-traefik-handoff = {
|
||||
description = "Install renewed cc-ci wildcard into Traefik Swarm secrets";
|
||||
after = [ "docker.service" "deploy-proxy.service" ];
|
||||
requires = [ "docker.service" ];
|
||||
path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
UMask = "0077";
|
||||
};
|
||||
script = ''
|
||||
src=/var/lib/acme/ci.commoninternet.net
|
||||
dst=/var/lib/ci-certs/live
|
||||
test -s "$src/fullchain.pem"
|
||||
test -s "$src/key.pem"
|
||||
install -d -m 0700 "$dst"
|
||||
install -m 0444 "$src/fullchain.pem" "$dst/fullchain.pem.new"
|
||||
install -m 0400 "$src/key.pem" "$dst/privkey.pem.new"
|
||||
mv -f "$dst/fullchain.pem.new" "$dst/fullchain.pem"
|
||||
mv -f "$dst/privkey.pem.new" "$dst/privkey.pem"
|
||||
|
||||
# deploy-proxy performs the health-gated Swarm rollout. Its reconciler
|
||||
# derives a fresh version from the public certificate chain and inserts
|
||||
# the matching ssl_cert/ssl_key secrets before deploying Traefik.
|
||||
systemctl restart deploy-proxy.service
|
||||
|
||||
# A successful rollout no longer references old wildcard versions. Best
|
||||
# effort removal retains any secret Docker still reports as in use.
|
||||
keep="v$(sha256sum "$dst/fullchain.pem" | cut -c1-16)"
|
||||
docker secret ls --format '{{.Name}}' | \
|
||||
grep -E '^traefik_ci_commoninternet_net_ssl_(cert|key)_v' | \
|
||||
grep -v -E "_(ssl_cert|ssl_key)_$keep\$" | \
|
||||
while IFS= read -r stale; do docker secret rm "$stale" || true; done
|
||||
'';
|
||||
};
|
||||
script = ''
|
||||
src=/var/lib/acme/ci.commoninternet.net
|
||||
dst=/var/lib/ci-certs/live
|
||||
test -s "$src/fullchain.pem"
|
||||
test -s "$src/key.pem"
|
||||
install -d -m 0700 "$dst"
|
||||
install -m 0444 "$src/fullchain.pem" "$dst/fullchain.pem.new"
|
||||
install -m 0400 "$src/key.pem" "$dst/privkey.pem.new"
|
||||
mv -f "$dst/fullchain.pem.new" "$dst/fullchain.pem"
|
||||
mv -f "$dst/privkey.pem.new" "$dst/privkey.pem"
|
||||
|
||||
# deploy-proxy performs the health-gated Swarm rollout. Its reconciler
|
||||
# derives a fresh version from the public certificate chain and inserts
|
||||
# the matching ssl_cert/ssl_key secrets before deploying Traefik.
|
||||
systemctl restart deploy-proxy.service
|
||||
|
||||
# A successful rollout no longer references old wildcard versions. Best
|
||||
# effort removal retains any secret Docker still reports as in use.
|
||||
keep="v$(sha256sum "$dst/fullchain.pem" | cut -c1-16)"
|
||||
docker secret ls --format '{{.Name}}' | \
|
||||
grep -E '^traefik_ci_commoninternet_net_ssl_(cert|key)_v' | \
|
||||
grep -v -E "_(ssl_cert|ssl_key)_$keep\$" | \
|
||||
while IFS= read -r stale; do docker secret rm "$stale" || true; done
|
||||
'';
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
|
||||
Reference in New Issue
Block a user