nixos/acme: reduce dependency on tmpfiles

systemd-tmpfiles is no longer required for
most of the critical paths in the module. The
only one that remains is the webroot
acme-challenge directory since there's no
other good place for this to live and forcing
users to do the right thing alone will only
create more issues.
This commit is contained in:
Lucas Savva 2020-12-13 22:19:53 +00:00
parent 85769a8cd8
commit 351065f970

View File

@ -59,9 +59,9 @@ let
''; '';
}; };
# Previously, all certs were owned by whatever user was configured in # Ensures that directories which are shared across all certs
# config.security.acme.certs.<cert>.user. Now everything is owned by and # exist and have the correct user and group, since group
# run by the acme user. # is configurable on a per-cert basis.
userMigrationService = { userMigrationService = {
description = "Fix owner and group of all ACME certificates"; description = "Fix owner and group of all ACME certificates";
@ -74,8 +74,13 @@ let
done done
'') certConfigs); '') certConfigs);
# We don't want this to run every time a renewal happens serviceConfig = {
serviceConfig.RemainAfterExit = true; # We don't want this to run every time a renewal happens
RemainAfterExit = true;
# These StateDirectory entries negate the need for tmpfiles
StateDirectory = "acme acme/.lego acme/.lego/accounts";
};
}; };
certToConfig = cert: data: let certToConfig = cert: data: let
@ -146,7 +151,7 @@ let
); );
in { in {
inherit accountHash accountDir cert selfsignedDeps; inherit accountHash cert selfsignedDeps;
webroot = data.webroot; webroot = data.webroot;
group = data.group; group = data.group;
@ -226,10 +231,14 @@ let
serviceConfig = commonServiceConfig // { serviceConfig = commonServiceConfig // {
Group = data.group; Group = data.group;
# AccountDir dir will be created by tmpfiles to ensure correct permissions # Keep in mind that these directories will be deleted if the user runs
# And to avoid deletion during systemctl clean # systemctl clean --what=state
# acme/.lego/${cert} is listed so that it is deleted during systemctl clean # acme/.lego/${cert} is listed for this reason.
StateDirectory = "acme/${cert} acme/.lego/${cert} acme/.lego/${cert}/${certDir}"; StateDirectory =
"acme/${cert} " +
"acme/.lego/${cert} " +
"acme/.lego/${cert}/${certDir} " +
"acme/.lego/accounts/${accountHash} ";
# Needs to be space separated, but can't use a multiline string because that'll include newlines # Needs to be space separated, but can't use a multiline string because that'll include newlines
BindPaths = BindPaths =
@ -667,18 +676,14 @@ in {
systemd.timers = mapAttrs' (cert: conf: nameValuePair "acme-${cert}" conf.renewTimer) certConfigs; systemd.timers = mapAttrs' (cert: conf: nameValuePair "acme-${cert}" conf.renewTimer) certConfigs;
# .lego and .lego/accounts specified to fix any incorrect permissions systemd.tmpfiles.rules = unique (
systemd.tmpfiles.rules = [ flatten (
"d /var/lib/acme/.lego - acme acme" mapAttrsToList (
"d /var/lib/acme/.lego/accounts - acme acme" cert: conf:
] ++ (unique (concatMap (conf: [ optional (conf.webroot != null) "d ${conf.webroot}/.well-known/acme-challenge - acme ${conf.group}"
"d ${conf.accountDir} - acme acme" ) certConfigs
] ++ (optionals (conf.webroot != null) [ )
"d ${conf.webroot} - acme ${conf.group}" );
"d ${conf.webroot}/.well-known - acme ${conf.group}"
"d ${conf.webroot}/.well-known/acme-challenge - acme ${conf.group}"
])
) (attrValues certConfigs)));
systemd.targets = let systemd.targets = let
# Create some targets which can be depended on to be "active" after cert renewals # Create some targets which can be depended on to be "active" after cert renewals