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);
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.
但是这个哈希是什么?
答案 0 :(得分:1)
但是,尽管ExecStart知道该动态用户的正确UID,但 ExecStartPost和ExecStartPre 却不知道,因为它们是作为root用户运行(UID = 0)所以我不知道怎么穿。
我认为这不是真的– ExecStartPre=
和ExecStartPost=
以相同的User=
和Group=
(以及相同的CapabilityBoundingSet=
,{{ 1}}等)作为主要可执行文件,除非配置不同(使用SystemCallFilter=
,+
或!
前缀–参见!!
)。我测试了with this test service。
希望:我想使用systemd的动态用户方面,但是在不知道UID的情况下我无法整理文档,因此动态用户可以访问它们。
这不是必需的。您的服务应将状态存储在其man 5 systemd.service
中,将运行时文件存储在其StateDirectory=
中,将数据存储在其RuntimeDirectory=
中,并登录其CacheDirectory=
(如果它具有自己的任何日志记录) –但请考虑使用日志),并从其LogsDirectory=
中读取配置(但无论如何该服务均不可写)。 systemd会自动为您管理这些目录的所有权,并且它们遵循标准的UNIX约定(它们是ConfigurationDirectory=
,/var/lib
,/run
,/var/cache
,{{ 1}} –有关详细信息,请参见/var/log
和this blog post。
如果您的守护程序不能仅限于这些标准目录,那么最简单的解决方案可能是不使用/etc
–使用静态分配的用户进行更复杂的设置不会有什么可耻的。但是考虑使用man 5 systemd.exec
(请参阅DynamicUser=
(而不是直接调用systemd-sysusers
/ man 5 sysusers.d
)来创建用户,尤其是在编写分发程序包时,这很明显软件包安装了用户(通过检查哪个软件包拥有各自的adduser
配置文件)。