[systemd-devel] Starting transient services securely from other service without root

Vašek Šraier vaclav.sraier at nic.cz
Thu Apr 28 15:56:05 UTC 2022


Hi!

On Wed, 2022-04-27 at 17:48 +0200, Michal Koutný wrote:

> (Also I understand the "starter" and "started" are both the same
> user.)

Yes, sorry for not describing it properly. All processes should be
running as the same user.

> > - User sessions
> >   The master process and worker processes can also run in a user 
> >   session. This directly solves problems with privileges. However, 
> >   I am not sure if running a user session with the semantics of a
> >   system service is possible or a good idea. I also don't know if
> >   there is any documentation related to user sessions without
> >   physical users.
> 
> Do you mean having all your stuff as services of user instance of
> systemd?

Yes, exactly this. We actually run the resolvers this way during
development. The control process detects whether it should use session
bus or system bus for communication and the rest works the same. 

> I assume the former. It sounds also a bit strange (unusual use of
> user instance of unusual(?) requirements).
> One consequence that I see directly is that any resource assigned via
> cgroups would be restricted by the single user instance for the whole
> assemply of workers together. (That can be intended or not.)

Yeah, I agree that running user instance of systemd for one type of
service sound pretty unusual. That's why I am unsure whether to pursue
the idea further or whether to abandon it as too hacky.

> > - Use other service managers, not systemd
> 
> Or minimize functions of your main process to just process the config
> and figure out jobs so that it can run as root with anything
> "sensitive"
> (open to external world) moved to unprivileged workers/helpers.

Thanks a lot. This is an approach I haven't really though of. We could
have a small process relaying and validating requests to control
transient service units. It would solve this particular, I just have to
think about it for a while if it does not introduce any more problems.


> In the end, I think it goes along axes like:


> - Is there any benefit of having the workers in individual systemd
>   units? (That suggests just controlling everything by the main
>   process (or 3rd party supervisor.)

Yes. One of the greatest benefits of individual units is the ability to
do transparent restarts and increased reliability. When using multiple
services, we can restart them independently of each other without any
visible impact from the outside. Also failure of any single component
does not really bother us. Workers are replaceable, the control process
is not strictly necessary most of the time. Therefore, there is pretty
much no single point of failure.

To achieve the same in terms of reliability within one systemd unit, we
would have to use some reliable supervisor and run all other processes
under its control. Which is exactly the same thing as using systemd
directly, just one level deeper with more moving parts.

Sure, there are definitely other reliable service managers. Sadly, I am
not aware of any which would support something equivalent to sd_notify.
We rely on it heavily for successfull startup confirmations.

> - Is there any privilege that is actually needed from PID1 or could a
>   given user self-serve themselves? (That suggest the user instance
>   services below.)

Only extra networking privileges are required for general deployments.
We need to open UDP port 53, but that's mostly it. So, non-root user
with extra `cap_net_bind_service` `cap_setpcap` capabilities is enough.



To update the current list of options:

- PolicyKit
  could technically help, but I've discovered that the documentation 
  explicitly prohibits our potential use-case:
  "In particular, applications, [...] must never include any 
   authorization rules."
  ==> THEREFORE, NOT APPLICABLE FOR US

- using our own user instance of systemd
  could technically work, but if even you think it's unusual, I would 
  rather stay away as it would really confuse our users
  ==> THEREFORE, NOT APPLICABLE FOR US

- small privileged daemon
  Potential solution. We should consider this more.

- 3rd party/custom nested supervisor
  Potential solution. Has its downsides, but could be in the end the 
  simplest way forward.


It seems to me then, that nobody really expected/designed transient
units to be used from other unprivileged services as we are attempting.
It seems like quite some effort to prevent general privilege escalation
vulnerability in a system using it.

I am still very much open to reconsider this conclusion, but I am
assuming it's true as nobody pointed to a direct solution.


Thanks a lot, Michal, for your thoughts on this.

Best,
Vašek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4672 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20220428/b22c8db1/attachment.bin>


More information about the systemd-devel mailing list