nixos/acme: Run postRun script as root

This commit is contained in:
Lucas Savva 2020-09-04 18:48:47 +01:00
parent 1b6cfd9796
commit 67a5d660cb
No known key found for this signature in database
GPG Key ID: F9CE6D3DCDC78F2D
2 changed files with 21 additions and 11 deletions

View File

@ -168,7 +168,7 @@ let
selfsignService = {
description = "Generate self-signed certificate for ${cert}";
after = [ "acme-selfsigned-ca.service" "acme-fixperms.service" ];
wants = [ "acme-selfsigned-ca.service" "acme-fixperms.service" ];
requires = [ "acme-selfsigned-ca.service" "acme-fixperms.service" ];
path = with pkgs; [ minica ];
@ -232,6 +232,15 @@ let
# Only try loading the credentialsFile if the dns challenge is enabled
EnvironmentFile = mkIf useDns data.credentialsFile;
# Run as root (Prefixed with +)
ExecStartPost = "+" + (pkgs.writeShellScript "acme-postrun" ''
cd /var/lib/acme/${escapeShellArg cert}
if [ -e renewed ]; then
rm renewed
${data.postRun}
fi
'');
};
# Working directory will be /tmp
@ -255,9 +264,8 @@ let
# Copy all certs to the "real" certs directory
CERT='certificates/${keyName}.crt'
CERT_CHANGED=no
if [ -e "$CERT" ] && ! cmp -s "$CERT" out/fullchain.pem; then
CERT_CHANGED=yes
touch out/renewed
echo Installing new certificate
cp -vp 'certificates/${keyName}.crt' out/fullchain.pem
cp -vp 'certificates/${keyName}.key' out/key.pem
@ -265,12 +273,6 @@ let
ln -sf fullchain.pem out/cert.pem
cat out/key.pem out/fullchain.pem > out/full.pem
fi
if [ "$CERT_CHANGED" = "yes" ]; then
cd out
set +euo pipefail
${data.postRun}
fi
'';
};
};
@ -344,7 +346,7 @@ let
example = "cp full.pem backup.pem";
description = ''
Commands to run after new certificates go live. Note that
these commands run as the acme user and configured group.
these commands run as the root user.
Executed in the same directory with the new certificate.
'';
@ -648,7 +650,7 @@ in {
# Create some targets which can be depended on to be "active" after cert renewals
systemd.targets = mapAttrs' (cert: conf: nameValuePair "acme-finished-${cert}" {
wantedBy = [ "default.target" ];
wants = [ "acme-${cert}.service" "acme-selfsigned-${cert}.service" ];
requires = [ "acme-${cert}.service" "acme-selfsigned-${cert}.service" ];
after = [ "acme-${cert}.service" "acme-selfsigned-${cert}.service" ];
}) certConfigs;
})

View File

@ -79,8 +79,15 @@ in import ./make-test-python.nix ({ lib, ... }: {
# Cert config changes will not cause the nginx configuration to change.
# This tests that the reload service is correctly triggered.
# It also tests that postRun is exec'd as root
specialisation.cert-change.configuration = { pkgs, ... }: {
security.acme.certs."a.example.test".keyType = "ec384";
security.acme.certs."a.example.test".postRun = ''
set -euo pipefail
touch test
chown root:root test
echo testing > test
'';
};
# Now adding an alias to ensure that the certs are updated
@ -283,6 +290,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
switch_to(webserver, "cert-change")
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_connection_key_bits(client, "a.example.test", "384")
webserver.succeed("grep testing /var/lib/acme/a.example.test/test")
with subtest("Can request certificate with HTTPS-01 when nginx startup is delayed"):
switch_to(webserver, "slow-startup")