问题
systemd有一个DynamicUser功能,请参见https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser=
我还使用了:PermissionsStartOnly=true
更改权限,因为这需要root。
然而,尽管 ExecStart
知道该动态用户的正确UID,但是 ExecStartPost
和 ExecStartPre
不会知道它,因为它们以root(UID=0)身份运行,所以我不知道如何改变它的所有权。
希望:我想使用systemd的动态用户方面,但是如果不知道UID,我无法将文档的所有权修改为动态用户可以访问。
问题
是否有其他在systemd中可以用来将文件权限映射到此临时用户的方法?
带“静态”用户的代码:
acmeSupplied = fold (identifier: con: if (config.nixcloud.TLS.certs.${identifier}.mode) == "ACME" then con ++ [
(nameValuePair "nixcloud.TLS-acmeSupplied-${identifier}" (let
c = config.nixcloud.TLS.certs.${identifier};
allDomains = concatMapStringsSep " " (x: "--domains=${x}") ( [ c.domain ] ++ c.extraDomains);
email = if (isString c.email) then c.email else "info@${c.domain}";
hash = hashIdentifierACMEOptions identifier;
in {
description = "nixcloud.TLS: create acmeSupplied certificate for ${identifier}";
preStart = ''
mkdir -p ${stateDir}/${identifier}/acmeSupplied/${hash}
chmod 0750 ${stateDir}/${identifier}/acmeSupplied -R
chown nc-lego:${filterIdentifier identifier} ${stateDir}/${identifier} -R
'';
script = ''
cd ${stateDir}/${identifier}/acmeSupplied
${pkgs.nixcloud.lego}/bin/lego ${allDomains} --email=${email} --exclude=dns-01 --exclude=tls-alpn-01 --webroot=/run/nixcloud/lego/${identifier}/challenges --path=${stateDir}/${identifier}/acmeSupplied/${hash} --accept-tos --server=${c.acmeApiEndpoint} run
${pkgs.nixcloud.lego}/bin/lego ${allDomains} --email=${email} --exclude=dns-01 --exclude=tls-alpn-01 --webroot=/run/nixcloud/lego/${identifier}/challenges --path=${stateDir}/${identifier}/acmeSupplied/${hash} --accept-tos --server=${c.acmeApiEndpoint} renew --days 15
'';
postStart = ''
chown nc-lego:${filterIdentifier identifier} ${stateDir}/${identifier} -R
chmod 0750 ${stateDir}/${identifier}/acmeSupplied -R
'';
serviceConfig = {
#DynamicUser = true;
User = "nc-lego";
ReadWritePaths = "-${stateDir}/${identifier}/acmeSupplied";
SupplementaryGroups = "${filterIdentifier identifier}";
PermissionsStartOnly = true;
Type = "oneshot";
RuntimeDirectory = "nixcloud/lego/${identifier}/challenges";
};
before = [ "nixcloud.TLS-acmeSupplied-certificates.target" ];
wantedBy = [ "nixcloud.TLS-acmeSupplied-certificates.target" ];
}))
] else con) [] (attrNames config.nixcloud.TLS.certs);
使用“DynamicUser”进行编码:
acmeSupplied = fold (identifier: con: if (config.nixcloud.TLS.certs.${identifier}.mode) == "ACME" then con ++ [
(nameValuePair "nixcloud.TLS-acmeSupplied-${identifier}" (let
c = config.nixcloud.TLS.certs.${identifier};
allDomains = concatMapStringsSep " " (x: "--domains=${x}") ( [ c.domain ] ++ c.extraDomains);
email = if (isString c.email) then c.email else "info@${c.domain}";
hash = hashIdentifierACMEOptions identifier;
in {
description = "nixcloud.TLS: create acmeSupplied certificate for ${identifier}";
preStart = ''
mkdir -p ${stateDir}/${identifier}/acmeSupplied/${hash}
chmod 0750 ${stateDir}/${identifier}/acmeSupplied -R
chown nixcloud.TLS-acmeSupplied-mail.nix.lt:${filterIdentifier identifier} ${stateDir}/${identifier} -R
'';
script = ''
cd ${stateDir}/${identifier}/acmeSupplied
${pkgs.nixcloud.lego}/bin/lego ${allDomains} --email=${email} --exclude=dns-01 --exclude=tls-alpn-01 --webroot=/run/nixcloud/lego/${identifier}/challenges --path=${stateDir}/${identifier}/acmeSupplied/${hash} --accept-tos --server=${c.acmeApiEndpoint} run
${pkgs.nixcloud.lego}/bin/lego ${allDomains} --email=${email} --exclude=dns-01 --exclude=tls-alpn-01 --webroot=/run/nixcloud/lego/${identifier}/challenges --path=${stateDir}/${identifier}/acmeSupplied/${hash} --accept-tos --server=${c.acmeApiEndpoint} renew --days 15
'';
postStart = ''
chown nixcloud.TLS-acmeSupplied-mail.nix.lt:${filterIdentifier identifier} ${stateDir}/${identifier} -R
chmod 0750 ${stateDir}/${identifier}/acmeSupplied -R
'';
serviceConfig = {
DynamicUser = true;
ReadWritePaths = "-${stateDir}/${identifier}/acmeSupplied";
SupplementaryGroups = "${filterIdentifier identifier}";
PermissionsStartOnly = true;
Type = "oneshot";
RuntimeDirectory = "nixcloud/lego/${identifier}/challenges";
};
before = [ "nixcloud.TLS-acmeSupplied-certificates.target" ];
wantedBy = [ "nixcloud.TLS-acmeSupplied-certificates.target" ];
}))
] else con) [] (attrNames config.nixcloud.TLS.certs);
错误信息:
mailserver-nix-lt> updating GRUB 2 menu...
mailserver-nix-lt> activating the configuration...
mailserver-nix-lt> setting up /etc...
mailserver-nix-lt> setting up tmpfiles
mailserver-nix-lt> reloading the following units: dbus.service
mailserver-nix-lt> warning: the following units failed: nixcloud.TLS-acmeSupplied-mail.nix.lt.service
mailserver-nix-lt>
mailserver-nix-lt> ● nixcloud.TLS-acmeSupplied-mail.nix.lt.service - nixcloud.TLS: create acmeSupplied certificate for mail.nix.lt
mailserver-nix-lt> Loaded: loaded (/nix/store/i4nxkvw8bf9vs2brhj3lyjakxklq0rxg-unit-nixcloud.TLS-acmeSupplied-mail.nix.lt.service/nixcloud.TLS-acmeSupplied-mail.nix.lt.service; enabled; vendor preset: enabled)
mailserver-nix-lt> Active: failed (Result: exit-code) since Thu 2018-10-11 10:55:46 CEST; 22ms ago
mailserver-nix-lt> Process: 20613 ExecStartPre=/nix/store/c69ccjnc2n5y6g1p9q168kjlgf2w3l10-unit-script/bin/nixcloud.TLS-acmeSupplied-mail.nix.lt-pre-start (code=exited, status=1/FAILURE)
mailserver-nix-lt> Main PID: 20243 (code=exited, status=0/SUCCESS)
mailserver-nix-lt>
mailserver-nix-lt> Oct 11 10:55:46 mail.nix.lt systemd[1]: Starting nixcloud.TLS: create acmeSupplied certificate for mail.nix.lt...
mailserver-nix-lt> Oct 11 10:55:46 mail.nix.lt nixcloud.TLS-acmeSupplied-mail.nix.lt-pre-start[20613]: chown: invalid user: ‘nixcloud.TLS-acmeSupplied-mail.nix.lt:nc-mail-nix-lt’
mailserver-nix-lt> Oct 11 10:55:46 mail.nix.lt systemd[1]: nixcloud.TLS-acmeSupplied-mail.nix.lt.service: Control process exited, code=exited status=1
mailserver-nix-lt> Oct 11 10:55:46 mail.nix.lt systemd[1]: nixcloud.TLS-acmeSupplied-mail.nix.lt.service: Failed with result 'exit-code'.
mailserver-nix-lt> Oct 11 10:55:46 mail.nix.lt systemd[1]: Failed to start nixcloud.TLS: create acmeSupplied certificate for mail.nix.lt.
mailserver-nix-lt> error: Traceback (most recent call last):
File "/nix/store/ixarqxfbhr06fp8y8pj5dcm1rhar2j15-nixops-1.6/lib/python2.7/site-packages/nixops/deployment.py", line 731, in worker
raise Exception("unable to activate new configuration")
Exception: unable to activate new configuration
根据文档对于
DynamicUser
的说明:If these options are not used and
dynamic user/group allocation is enabled for a unit, the name of
the dynamic user/group is implicitly derived from the unit name.
If the unit name without the type suffix qualifies as valid user
name it is used directly, otherwise a name incorporating a hash
of it is used.
但是这个哈希是什么呢?
UMask=0002
(这样文件默认是组可写的),然后将两个服务都设为同一组的成员。也许你也可以尝试这样做? - Lucas Werkmeister