systemd with DynamicUser UID unknown

问题描述 投票:0回答:1

problem

systemd有一个DynamicUser功能,请参阅https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser=

我也在使用:PermissionsStartOnly=true来更改权限,因为这需要root。

然而,当ExecStart知道该动态用户的正确UID时,ExecStartPostExecStartPre将不会知道它,因为它们以root身份运行(UID = 0),因此我不知道如何将其打包。

希望:我想使用systemd的动态用户方面,但在不知道UID的情况下,我无法提交文档,因此动态用户可以访问它们。

question

systemd中还有其他东西我可以用来将文件的权限映射到这个临时用户吗?

code with a 'static' user:

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);

code with a '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.

但这个哈希是什么?

systemd
1个回答
1
投票

但是,当ExecStart知道该动态用户的正确UID时,ExecStartPost和ExecStartPre将不会知道它,因为它们以root身份运行(UID = 0),因此我不知道如何将其命名。

我不认为这是真的 - ExecStartPre=ExecStartPost=作为主要可执行文件运行相同的User=Group=(并使用相同的CapabilityBoundingSet=SystemCallFilter=等等),除非配置不同(使用+!!!前缀 - 见man 5 systemd.service)。我测试了它with this test service

希望:我想使用systemd的动态用户方面,但在不知道UID的情况下,我无法提交文档,因此动态用户可以访问它们。

这不应该是必要的。你的服务应该在StateDirectory=中存储状态,在RuntimeDirectory=中存储运行时文件,在CacheDirectory=中存储缓存数据,在LogsDirectory=中记录日志(如果它有自己的任何日志记录 - 但考虑使用日志),并从其ConfigurationDirectory=读取配置(但是这对服务来说是不可写的。 systemd将自动为您管理这些目录的所有权,并且它们遵循标准的UNIX约定(它们是/var/lib/run/var/cache/var/log/etc下的子目录 - 有关详细信息,请参阅man 5 systemd.execthis blog post)。

如果您的守护进程不能限制在这些标准目录中,那么最简单的解决方案可能是不使用DynamicUser= - 使用静态分配的用户进行更复杂的设置并不可耻。但是考虑通过systemd-sysusers创建用户(请参阅man 5 sysusers.d)而不是直接调用adduser / useradd,特别是如果你正在编写一个分发包,那么很明显哪个包安装了用户(通过检查哪个包拥有相应的systemd-sysusers配置文件) 。

© www.soinside.com 2019 - 2024. All rights reserved.