Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d233174c |
@@ -5,12 +5,10 @@
|
|||||||
# /srv/cc-ci/.sops/master-age.txt (never in this repo). Lets us re-key if cc-ci is lost.
|
# /srv/cc-ci/.sops/master-age.txt (never in this repo). Lets us re-key if cc-ci is lost.
|
||||||
keys:
|
keys:
|
||||||
- &host age1h90utdztfc23kx8ewrtrtk80mnddvrf8pg4ppej55rwwwupzhfvqhmp3qa
|
- &host age1h90utdztfc23kx8ewrtrtk80mnddvrf8pg4ppej55rwwwupzhfvqhmp3qa
|
||||||
- &host2 age1tmvgpgc822ezqgxg4x8h6ndph6j9hwpgjpg364zn7lw3t5h694rq5730wa
|
|
||||||
- &master age1cmk26t9e30ls8594s8txgmf2exenydmntfxqpcd3qdqm3ru2lpnqpdkdz9
|
- &master age1cmk26t9e30ls8594s8txgmf2exenydmntfxqpcd3qdqm3ru2lpnqpdkdz9
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/.*\.(yaml|json|env)$
|
- path_regex: secrets/.*\.(yaml|json|env)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *host
|
- *host
|
||||||
- *host2
|
|
||||||
- *master
|
- *master
|
||||||
|
|||||||
+71
-64
@@ -60,79 +60,86 @@ in
|
|||||||
|
|
||||||
environment.etc."acme-dns/lego.env".source = legoEnvironment;
|
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 = {
|
networking.firewall = {
|
||||||
allowedTCPPorts = [ 53 ];
|
allowedTCPPorts = [ 53 ];
|
||||||
allowedUDPPorts = [ 53 ];
|
allowedUDPPorts = [ 53 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.acme-dns = {
|
|
||||||
description = "Restricted authoritative DNS for cc-ci ACME DNS-01";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
# One `systemd` attrset (statix W20): the tmpfiles marker, the acme-dns daemon and the
|
||||||
after = [ "network-online.target" ];
|
# traefik handoff oneshot.
|
||||||
wants = [ "network-online.target" ];
|
systemd = {
|
||||||
serviceConfig = {
|
# The staging order has completed successfully. This marker permits the
|
||||||
User = "acme-dns";
|
# production ACME post-run hook to hand a renewed certificate to Traefik.
|
||||||
Group = "acme-dns";
|
tmpfiles.rules = [
|
||||||
StateDirectory = "acme-dns";
|
"f /var/lib/ci-certs/acme-production-enabled 0600 root root -"
|
||||||
StateDirectoryMode = "0700";
|
];
|
||||||
WorkingDirectory = "/var/lib/acme-dns";
|
|
||||||
ExecStart = "${pkgs.acme-dns}/bin/acme-dns -c ${acmeDnsConfig}";
|
services.acme-dns = {
|
||||||
Restart = "on-failure";
|
description = "Restricted authoritative DNS for cc-ci ACME DNS-01";
|
||||||
RestartSec = "5s";
|
wantedBy = [ "multi-user.target" ];
|
||||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
after = [ "network-online.target" ];
|
||||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
wants = [ "network-online.target" ];
|
||||||
NoNewPrivileges = true;
|
serviceConfig = {
|
||||||
PrivateTmp = true;
|
User = "acme-dns";
|
||||||
PrivateDevices = true;
|
Group = "acme-dns";
|
||||||
ProtectHome = true;
|
StateDirectory = "acme-dns";
|
||||||
ProtectSystem = "strict";
|
StateDirectoryMode = "0700";
|
||||||
ReadWritePaths = [ "/var/lib/acme-dns" ];
|
WorkingDirectory = "/var/lib/acme-dns";
|
||||||
RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ];
|
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
|
# Traefik consumes its wildcard as immutable Swarm secrets, so a renewed
|
||||||
# host certificate must be copied and reconciled rather than merely reloaded.
|
# host certificate must be copied and reconciled rather than merely reloaded.
|
||||||
# This service is started only by the production-mode ACME postRun hook.
|
# This service is started only by the production-mode ACME postRun hook.
|
||||||
systemd.services.cc-ci-acme-traefik-handoff = {
|
services.cc-ci-acme-traefik-handoff = {
|
||||||
description = "Install renewed cc-ci wildcard into Traefik Swarm secrets";
|
description = "Install renewed cc-ci wildcard into Traefik Swarm secrets";
|
||||||
after = [ "docker.service" "deploy-proxy.service" ];
|
after = [ "docker.service" "deploy-proxy.service" ];
|
||||||
requires = [ "docker.service" ];
|
requires = [ "docker.service" ];
|
||||||
path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ];
|
path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
UMask = "0077";
|
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 = {
|
security.acme = {
|
||||||
|
|||||||
+1
-1
Submodule secrets updated: 638c28dae8...2ce5f86c02
Reference in New Issue
Block a user