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

Increase the system user id range #65698

Merged
merged 1 commit into from Oct 27, 2019
Merged

Conversation

infinisil
Copy link
Member

@infinisil infinisil commented Jul 31, 2019

This is now a full RFC at NixOS/rfcs#52

This enlarges the system uid/gid range 6-fold, from 100 to 600 ids. This
is a preventative measure against running out of dynamically allocated
ids for NixOS services with isSystemUser, which should become the
preferred way of allocating uids for non-real users if DynamicUser isn't applicable.

Motivation for this change

We're running out of static uid/gid's in the standard range from 0 to 400, only ~85 are left:

zoneminder = 314;
paperless = 315;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!

While it might be possible to assign another range for static id's, that's just an ugly solution, and having to declare static id's has always been a bit of a pain.

A better solution is to not assign static id's for services, but to use NixOS dynamic user allocation (happening by default, when uid/gid = null). Specifically with isSystemUser = true such that ids get allocated in the range SYS_{U,G}ID_MIN (400) - SYS_{U,G}ID_MAX (499 before this change, 999 after), meaning the range above 1000 can be used exclusively by real users.

Why extend it to 999? Because a limit of 100 ids means that over the lifetime of a NixOS system, users can only ever run 100 different services, since id's aren't repurposed after a service is disabled (See a57bcd3), which is a bit on the low side. And 999 (={U,G}ID_MIN-1) is also the default value anyways, see man login.defs.

This means that instead of having a limit of 400 static uids for all NixOS services in nixpkgs, we have a limit of 600 dynamic uids for all NixOS services ever enable on a single system.

But isn't it bad to not use static id's for services?

I don't think so. One reason I can think of for having static id's is for some service that needs to transfer its files across NixOS machines, but this is not the case for most services. Another reason might be that loading data from backups into a new NixOS installation will make services not work due the mismatch of data and service ids. This is however not a problem if /var/lib/{u,g}id-map gets restored as well, and also not a problem if services use StateDirectory or systemd.tmpfiles which fixes permissions on service start.

See #60732 (comment) for a previous discussion

cc @ryantm @arianvp @aanderse @edolstra

@infinisil
Copy link
Member Author

While not directly a problem, this is not beneficial for @jameysharp's move to all-static uid's in #64594

@arcnmx
Copy link
Member

arcnmx commented Jul 31, 2019

Is it possible and/or are there plans to unassign the existing ~300 IDs, moving them to either isSystemUser or DynamicUser? (assuming that the fact they already exist in passwd/uid-map/whatever means they can just remain as-is on existing systems)

@infinisil
Copy link
Member Author

I believe it would be safe to switch services that don't need static uid's to isSystemUser (because existing systems will get the same id's from /var/lib/nixos/{u,g}id-map). DynamicUser might also be safe if systemd can handle this transition, this should be tested first.

@arcnmx
Copy link
Member

arcnmx commented Aug 1, 2019

Last I recall reading about DynamicUser it was explicitly stated as a goal that it be able to handle seamless transitions for existing systems (I believe their particular approach is just to treat it as if DynamicUser weren't set if the user already exists on the system?). Certainly yeah stuff to test, just wondering since it seems like it may be unnecessary to keep many of them reserved for the future, which could widen the range of usable system IDs further.

(though systemd is meant to handle the transition, if nixos removes deleted users from passwd that may or may not cause problems; really depends on whether StateDirectory= is the whole story or not for a given service I guess? but even then if it's fine and then you tried rolling back... poof?)

@aanderse
Copy link
Member

aanderse commented Aug 1, 2019

Unfortunately moving to DynamicUser for many of the existing nixos modules will be difficult because the dataDir pattern (or maybe in this case anti-pattern).

@reanimus
Copy link
Contributor

reanimus commented Aug 7, 2019

So, after some discussion in the IRC channel, it looks line roon-server doesn't work with DynamicUser enabled, as the backup mechanism needs to be able to write to a persistent location and DynamicUser would make managing permissions for this directory impossible.

@infinisil
Copy link
Member Author

Yeah so it might be the case that we can't use DynamicUser as much as we'd like to

@edolstra
Copy link
Member

edolstra commented Aug 9, 2019

My understanding is that DynamicUser is only intended for services that don't have persistent state.

@aanderse
Copy link
Member

aanderse commented Aug 9, 2019

@edolstra there is some allowance for persistent data. See 'Persistent Data' section of http://0pointer.net/blog/dynamic-users-with-systemd.html

@arianvp
Copy link
Member

arianvp commented Aug 9, 2019

My understanding is that DynamicUser is only intended for services that don't have persistent state.

Incorrect. It's only meant for services that don't share state between services. Persistent state is definitely possible, as long as it's defined through StateDirectory=,CacheDirectory=,LogDirectory= etc

@infinisil
Copy link
Member Author

@volth StateDirectory and co. won't chown recursively when the top-most directory already has the correct perms (source: man systemd.exec), so this can be used for such cases.

systemd.tmpfiles doesn't have such a mechanism unfortunately. It can either chown recursively with Z or it doesn't chown at all if that's not used (the d directive only does anything if the directory doesn't exist yet) (see man tmpfiles.d)

@infinisil infinisil mentioned this pull request Aug 9, 2019
10 tasks
@infinisil infinisil mentioned this pull request Aug 18, 2019
10 tasks
@globin
Copy link
Member

globin commented Aug 19, 2019

I'd prefer this being a proper RFC :)

@infinisil
Copy link
Member Author

I made this a full RFC, see above

@asymmetric
Copy link
Contributor

asymmetric commented Sep 18, 2019

AFAIK, systemd ignores /etc/login.defs and instead relies on compilation flags to decide the uid pool size.

So it seems you'd have to change this.

@infinisil
Copy link
Member Author

@asymmetric Yeah, but I think this is only relevant for users created through useradd, because the dynamic ids allocated by NixOS use the limits in update-users-groups.pl to write /etc/passwd directly

Will do that change too

@globin
Copy link
Member

globin commented Oct 8, 2019

FYI NixOS/rfcs#52 is in Final Comment Period

@infinisil infinisil mentioned this pull request Oct 12, 2019
10 tasks
@infinisil infinisil changed the title [RFC] Away from static id's for services Increase the system user id range Oct 12, 2019
@infinisil
Copy link
Member Author

@asymmetric Now applied the change to the systemd build flags too. Will probably have to switch to staging because of this.

@GrahamcOfBorg eval

pkgs/os-specific/linux/systemd/default.nix Outdated Show resolved Hide resolved
nixos/modules/programs/shadow.nix Outdated Show resolved Hide resolved
@infinisil infinisil changed the base branch from master to staging October 13, 2019 23:20
@ofborg ofborg bot requested a review from Mic92 October 13, 2019 23:34
This enlarges the system uid/gid range 6-fold, from 100 to 600 ids. This
is a preventative measure against running out of dynamically allocated
ids for NixOS services with isSystemUser, which should become the
preferred way of allocating uids for non-real users.
@infinisil
Copy link
Member Author

Turns out that the ranges defined in the systemd compile time options really don't matter that much, they're only used by systemd features like ConditionUser=@system and systemd-sysusers (which is apparently another way to allocate ids, maybe we could even use that for NixOS at some point).

The ranges in login.defs are only used for mutable users/groups added with useradd/groupadd/newusers.

And the ones in update-users-groups.pl are used by NixOS to allocate its declaratively defined users.

I added this info to a comment.

Also added links to the issues regarding runtime configuration of systemd ranges.

@infinisil
Copy link
Member Author

NixOS/rfcs#52 is now accepted and I think this is ready to be merged.

@c0bw3b
Copy link
Contributor

c0bw3b commented Oct 24, 2019

@GrahamcOfBorg test systemd

@infinisil
Copy link
Member Author

Hehe, the error on aarch64 is deceivingly related-looking:

error: all build users are currently in use; consider creating additional users and adding them to the 'nixbld' group

But really that only seems to occur as a result of heavy aarch64 builder usage, nothing with this PR.

@infinisil infinisil merged commit de357d5 into NixOS:staging Oct 27, 2019
@infinisil infinisil deleted the system-users branch November 1, 2019 12:19
@infinisil infinisil added the significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet