nixos/acme: fix ReadWritePaths for acme-${domain}.service
Currently ReadWritePaths is only sufficiently specificed for
acme-order-renew-${domain}.service, and not acme-${domain}.service. This
results in service failure if specifying the webroot outside of
/var/lib/acme, for example /var/www/challenges:
acme-example.com-start[1379]: + mkdir -p /var/www/challenges//.well-known/acme-challenge
acme-example.com-start[1382]: mkdir: cannot create directory ‘/var/www/challenges//.well-known’: Read-only file system
systemd[1]: acme-example.com.service: Main process exited, code=exited, status=1/FAILURE
Fix it by adding the webroots to ReadWritePaths in the common
serviceConfig, where it can affect both acme-order-renew-${domain}.service
AND acme-${domain}.service.
Avoid adding subdirs of existing ReadWritePaths entries, because
otherwise systemd will fail to set up the services, for example:
acme-zeroconf.example.test.service: Failed to set up mount namespacing: /run/acme: No such file or directory
(Confusingly, the path shown in the error message isn't necessarily
related to the problematic path.)
This commit is contained in:
@@ -51,6 +51,12 @@ let
|
||||
''
|
||||
+ script;
|
||||
|
||||
# We need to collect all the ACME webroots to grant them write
|
||||
# access in the systemd service.
|
||||
webroots = lib.remove null (
|
||||
lib.unique (map (certAttrs: certAttrs.webroot) (lib.attrValues config.security.acme.certs))
|
||||
);
|
||||
|
||||
# There are many services required to make cert renewals work.
|
||||
# They all follow a common structure:
|
||||
# - They inherit this commonServiceConfig
|
||||
@@ -69,7 +75,9 @@ let
|
||||
ReadWritePaths = [
|
||||
"/var/lib/acme"
|
||||
lockdir
|
||||
];
|
||||
]
|
||||
# Prevent runtime breakage by only adding non-overlapping paths.
|
||||
++ (lib.filter (x: !(lib.strings.hasPrefix "/var/lib/acme/" x)) webroots);
|
||||
PrivateTmp = true;
|
||||
|
||||
WorkingDirectory = "/tmp";
|
||||
@@ -299,12 +307,6 @@ let
|
||||
++ data.extraLegoRenewFlags
|
||||
);
|
||||
|
||||
# We need to collect all the ACME webroots to grant them write
|
||||
# access in the systemd service.
|
||||
webroots = lib.remove null (
|
||||
lib.unique (map (certAttrs: certAttrs.webroot) (lib.attrValues config.security.acme.certs))
|
||||
);
|
||||
|
||||
certificateKey = if data.csrKey != null then "${data.csrKey}" else "certificates/${keyName}.key";
|
||||
in
|
||||
{
|
||||
@@ -469,8 +471,6 @@ let
|
||||
"acme/.lego/accounts/${accountHash}"
|
||||
];
|
||||
|
||||
ReadWritePaths = commonServiceConfig.ReadWritePaths ++ webroots;
|
||||
|
||||
# Needs to be space separated, but can't use a multiline string because that'll include newlines
|
||||
BindPaths = [
|
||||
"${accountDir}:/tmp/accounts"
|
||||
|
||||
Reference in New Issue
Block a user