Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFE] allow to exec units as a uid without passwd entry #19781

Open
frasertweedale opened this issue Jun 2, 2021 · 6 comments
Open

[RFE] allow to exec units as a uid without passwd entry #19781

frasertweedale opened this issue Jun 2, 2021 · 6 comments
Labels
needs-discussion 🤔 pid1 RFE 🎁 Request for Enhancement, i.e. a feature request

Comments

@frasertweedale
Copy link

Is your feature request related to a problem? Please describe.

When creating a unit/scope with User=<uid>, if getpwuid(uid) does not return a passwd struct,
systemd refuses to proceed.

AFAICT, this is because without a passwd struct, reasonable values for the process working directory, shell,
and HOME and LOGNAME are not known.

However, with user namespaces and subuid ranges, it is increasingly common to want to execute processes
and (especially) create cgroup scopes as uids that do not have associated passwd entries.

As a concrete use case: currently, "rootless podman" creates a transient systemd unit. The cgroup is owned by the main user (say, 1000), and the uid_map of the container process is 0 1000 1 \n 1 100000 65536. So, "rootless containers" are not really properly isolated. Enabling systemd to create the transient unit with User=100000 and Delegate=true would enable fully isolated containers.

Describe the solution you'd like

Do not fail when getpwuid(uid) returns nothing. Instead, either leave values unset (where feasible) or synthesise reasonable defaults (e.g. shell = /sbin/nologin). If necessary, synthesise a username (e.g. vu-100000, with collision checks.

If thought appropriate, this behaviour could sit behind a UserCredsFlag, to be triggered by a property (e.g. IgnoreMissingUser=true).

I am happy to implement this, if we can reach agreement that it is the right way to proceed.

Describe alternatives you've considered

  1. systemd-machined registers "machine" subuid offset and range size. nss-systemd consults the machine registry and synthesises passwd entries for uids in the range upon demand. Registering a machine prior to creating the transient unit allows the unit to be executed properly. However this is a more intrusive change for container runtimes.
  2. Create a new NSS passwd module (or enhance nss-systemd) to synthesise entries for UIDs in known subuid ranges. For example, if /etc/subuid contains ftweedal:100000:65536 then a lookup for 101000 could return the passwd entry with name ftweedal-101000 (again subject to collision check) and sensible defaults for other fields.

The systemd version you checked that didn't have the feature you are asking for
tip of main branch (6c498f6)

@frasertweedale frasertweedale changed the title Allow to exec units as a uid without passwd entry [RFE] allow to exec units as a uid without passwd entry Jun 2, 2021
@poettering
Copy link
Member

Why doesn't podman register the user it takes possession of in NSS?

note that it can simply implement this: https://systemd.io/USER_GROUP_API/ and then systemd will do the rest. The outcome of that would be much much nicer, since the relevant UIDs are then officially owned by podman and won#t collide with other users.

@frasertweedale
Copy link
Author

@poettering thanks for your prompt response.

This isn't about podman specifically - every container runtime that wants to do user namespaced containers properly faces this issue. Indeed my particular goal is systemd support on OpenShift (CRI-O + runc).

Instead of adding complexity to every container runtime, instead I would like to understand why systemd currently requires a passwd entry for the uid (User=) of the unit. Or why it is important for the container runtime to "own" (per NSS) the uids it uses**. I am probably being naive, but when there is no passwd entry why can't systemd exec the unit under the specified uid anyway, with conservative defaults for working dir, environment, etc?

** assuming it sticks to its assigned subid range and has its own accounting for assigning chunks of that range to different sandboxes.

@frasertweedale
Copy link
Author

@poettering ping - would you be able to respond to my question about whether/why executing units as "anonymous" UIDs (with conservative defaults for username, cwd, shell) is problematic? Thanks!

@poettering
Copy link
Member

This isn't about podman specifically - every container runtime that wants to do user namespaced containers properly faces this issue. Indeed my particular goal is systemd support on OpenShift (CRI-O + runc).

That's still something to fix in OpenShift/CRIO/runc/podman then. Taking possession of UIDs without registering them in NSS is icky, since it creates all kinds of conflicts, because other code on the system simply doesn't know the UIDs are taken.

@poettering
Copy link
Member

I am probably being naive, but when there is no passwd entry why can't systemd exec the unit under the specified uid anyway, with conservative defaults for working dir, environment, etc?

Of course, it could, but the question is if conceptually it's really a good idea. I mean, ssh doesn't allow you to log into non-existing accounts either.

I am pretty sure it would be a lot nicer for everyone if the container tooling you are using would just do what's right, and register its user in NSS. That would adress the issue you want addressed in a much nicer way, and also fix a multitude of other issues.

Hence: given this can be fixed in openshift/crio/runc/podman or worked around in in systemd, i'd always suggest the former, not the latter.

@poettering poettering added the RFE 🎁 Request for Enhancement, i.e. a feature request label Jun 9, 2021
@frasertweedale
Copy link
Author

Thanks for the response @poettering. I'll pursue a solution within the container runtime(s), but I would like to leave this RFE open until I have at least a working POC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-discussion 🤔 pid1 RFE 🎁 Request for Enhancement, i.e. a feature request
Development

No branches or pull requests

2 participants