Merge pull request #22526 from poettering/homed-container-uid-range
homed: map container UID range for homed home directories
This commit is contained in:
@@ -12,18 +12,39 @@ CHANGES WITH 251:
|
||||
* Services with Restart=always and a failing ExecCondition= will no longer
|
||||
be restarted, to bring ExecCondition= in line with Condition*= settings.
|
||||
|
||||
* In v250 systemd-homed started making use of UID mapped mounts for the
|
||||
home areas if the kernel and used file system support it. Files are
|
||||
now internally owned by the "nobody" user (i.e. the user typically
|
||||
used for indicating "this ownership is not mapped"), and dynamically
|
||||
mapped to the UID used locally on the system via the UID mapping
|
||||
mount logic of recent kernels.
|
||||
In the current implementation systemd-homed only maps a limited
|
||||
number of UIDs and GIDs making it impossible to run unprivileged
|
||||
containers that want to map a full POSIX compliant UID and GID range
|
||||
with their rootfs located within the systemd-homed managed home area.
|
||||
This will be fixed in subsequent releases. See
|
||||
https://github.com/systemd/systemd/pull/22239 for a proposal.
|
||||
* Starting with v250 systemd-homed uses UID/GID mapping on the mounts
|
||||
of activated home directories it manages (if the kernel and selected
|
||||
file systems support it). So far it mapped three UID ranges: the
|
||||
range from 0…60000, the user's own UID, and the range 60514…65534,
|
||||
leaving everything else unmapped (in other words, the 16bit UID range
|
||||
is mapped almost fully, with the exception of the UID subrange used
|
||||
for systemd-homed users, with one exception from that: the user's own
|
||||
UID). Unmapped UIDs may not be used for file ownership in the home
|
||||
dirctory — any chown() attempts with them will fail. With this
|
||||
release a fourth range is added to these mappings:
|
||||
524288…1879048191. This range is the UID range intended for container
|
||||
uses, see:
|
||||
|
||||
https://systemd.io/UIDS-GIDS
|
||||
|
||||
This range may be used for container managers that place container OS
|
||||
trees in the home directory (which is a questionable approach, for
|
||||
quota, permission, SUID handling and network file system
|
||||
compatibility reasons, but nonetheless apparently commonplace). Note
|
||||
that this mapping is mapped 1:1 in a pass-through fashion, i.e. the
|
||||
UID assignments from the range are not managed or mapped by
|
||||
`systemd-homed`, and must be managed with other mechanisms, in the
|
||||
context of the local system.
|
||||
|
||||
Typically, a better approach to user namespacing in relevant
|
||||
container managers would be to leave container OS trees on disk at
|
||||
UID offset 0, but then map them to a dynamically allocated runtime
|
||||
UID range via another UID mount map at container invocation
|
||||
time. That way user namespace UID ranges become strictly a runtime
|
||||
concept, and do not leak into persistent file systems, persistent
|
||||
user databases or persistent configuration, thus greatly simplifying
|
||||
handling, and improving compatibility with home directories intended
|
||||
to be portable like the ones managed by systemd-homed.
|
||||
|
||||
CHANGES WITH 250:
|
||||
|
||||
|
||||
@@ -233,6 +233,27 @@ safely use the NSS user database as allocation check, too. Note that if you
|
||||
follow this scheme no changes to `/etc/passwd` need to be made, thus minimizing
|
||||
the artifacts the container manager persistently leaves in the system.
|
||||
|
||||
5. `systemd-homed` by default mounts the home directories it manages with UID
|
||||
mapping applied. It will map four UID ranges into that uidmap, and leave
|
||||
everything else unmapped: the range from 0…60000, the user's own UID, the range
|
||||
60514…65534, and the container range 524288…1879048191. This means
|
||||
files/directories in home directories managed by `systemd-homed` cannot be
|
||||
owned by UIDs/GIDs outside of these four ranges (attempts to `chown()` files to
|
||||
UIDs outside of these ranges will fail). Thus, if container trees are to be
|
||||
placed within a home directory managed by `systemd-homed` they should take
|
||||
these ranges into consideration and either place the trees at base UID 0 (and
|
||||
then map them to a higher UID range for use in user namespacing via another
|
||||
level of UID mapped mounts, at *runtime*) or at a base UID from the container
|
||||
UID range. That said, placing container trees (and in fact any
|
||||
files/directories not owned by the home directory's user) in home directories
|
||||
is generally a questionable idea (regardless of whether `systemd-homed` is used
|
||||
or not), given this typically breaks quota assumptions, makes it impossible for
|
||||
users to properly manage all files in their own home directory due to
|
||||
permission problems, introduces security issues around SETUID and severely
|
||||
restricts compatibility with networked home directories. Typically, it's a much
|
||||
better idea to place container images outside of the home directory,
|
||||
i.e. somewhere below `/var/` or similar.
|
||||
|
||||
## Summary
|
||||
|
||||
| UID/GID | Purpose | Defined By | Listed in |
|
||||
|
||||
@@ -209,6 +209,13 @@ static int make_userns(uid_t stored_uid, uid_t exposed_uid) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Also map the container range. People can use that to place containers owned by high UIDs in their
|
||||
* home directories if they really want. We won't manage this UID range for them but pass it through
|
||||
* 1:1, and it will lose its meaning once migrated between hosts. */
|
||||
r = append_identity_range(&text, CONTAINER_UID_BASE_MIN, CONTAINER_UID_BASE_MAX+1, stored_uid);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* Leave everything else unmapped, starting from UID_NOBODY itself. Specifically, this means the
|
||||
* whole space outside of 16bit remains unmapped */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user