posted 2019-11-21
Users and groups in Gentoo are now governed by GLEP81. According to that GLEP, users and groups are created on the system by installing packages in the acct-user and acct-group categories. Those user and group packages should be relatively simple, but there are some pitfalls to watch out for, and the advice in the devmanual is wrong.
Below I give an example of the easiest and safest thing to do (use the defaults), explain the rationale for doing so (why you should believe me), and point out the exceptions to the rules (when you should ignore them).
Almost every group ebuild should look like,
and almost every user ebuild should look like,
That's pretty much it. If it's possible for your user and group ebuilds look like that, you should go make them look like that.
Chances are, if you're migrating away from user.eclass
,
then this will involve some changes to your package and the
user/group that it installs. That's OK. User management in Gentoo
was a disaster, and now is when we fix that. You should embark upon
a GLEP81 migration like an EAPI update. Rather than simply copy your
user's settings into an acct-user package, you should
take the opportunity to re-evaluate your user's name, shell, home
directory, and its permissions. GLEP81 sheds light upon many user
management issues that were allowed to fester in the past. Use
the defaults.
Software sucks, so you will occasionally hit problems while trying to not suck. In that case, you may need to set one or more of the following variables in your acct-user ebuilds:
ACCT_USER_SHELL
ACCT_USER_HOME
ACCT_USER_HOME_OWNER
ACCT_USER_HOME_PERMS
However, I'm going to repeat this a few times… do not set any of those variables unless it's absolutely necessary. Setting them can cause unforeseen problems down the road.
In most cases, the default shell (that is, no shell) should be used.
Services can still be started as a user who has no shell, cron
jobs can specify a shell, and daemons are able to drop privileges to
a user who has no shell. If necessary, the administrator can
override a user's default shell with su -s <shell>
<username>
. This is sufficient for testing, management
of SSH credentials, and for initial configuration in an ebuild's
pkg_config
phase.
An obvious exception to this rule is if a human being will need to log into the account interactively, as is the case with the root user. Other exceptions certainly exist, but should be evaluated case-by-case. To be clear: if you haven't checked, don't set your user's shell to /bin/bash just because you think he might need it.
The goal here is twofold. First, the principle of least privilege says that if a user doesn't need a real shell, then he shouldn't have one. And along those same lines, not having a shell gives the system administrator some peace of mind: he doesn't have to be as concerned with whether or not that user has a password (and how strong it is), or whether or not its filesystem permissions are all set correctly, or whether or not it can log in via SSH, et cetera.
In most cases, the default home directory (that is, no home directory) should be used.
GLEP81 changed two aspects of user management with respect to home directories:
Creating a user can now modify the permissions on an existing directory. Should the need arise, this is necessary for a new version of an acct-user package to be able to fix the ownership and permissions of its home directory.
All user data aside from the username became non-local to ebuilds that depend on that user. This is merely a side-effect of moving the user creation out of the client package, and into a separate acct-user package.
The first item means that you should be conservative when choosing a home directory. If at all possible, avoid choosing a home directory that is used by another package. In particular, no two acct-user packages should use the same home directory. At best, the ownership and permissions on a shared home directory would need to be kept synchronized between all packages that share it. At worst, one package goes out-of-sync and introduces a security hole for the others who no longer have the expected permissions.
The second item means that if your package requires a user, you can no longer be sure of that user's home directory or its ownership and permissions. If your package requires a directory to be owned and writable by some user, then your package's ebuild should create that directory and ensure that it is writable by the user. In other words, you should not rely on the directory being created “transitively” by a dependency, even if that dependency is an acct-user package.
In summary,
ACCT_USER_HOME
that belongs to another
package.
ACCT_USER_HOME
.
ACCT_USER_HOME
at its default (empty) value; setting
ACCT_USER_HOME=/var/lib/<username>
creates
unnecessary duplication and risks desynchronizing the permissions.
In most cases, the default home directory ownership is correct.
If a non-default home directory is needed at all, then it should be
writable by its user and giving ownership of it to someone else
would prevent that. Being unwritable indicates that a shared and
potentially sensitive location was chosen. Moreover, the fact that
the home directory is not writable suggests that the default home
directory (which is also not writable) would suffice instead; the home directory guidelines explain why
the default is preferable in that case. For example, setting
ACCT_USER_HOME_OWNER="root:root"
is
suspicious because it appears intended to “undo” the
ownership changed by your user package, and that would only be
necessary if the path in question is used by some other package.
Strict permissions are good permissions.
In many cases, the default home directory permissions (0755) will suffice. But, if your package will work with mode 0700 or 0750, then those are preferable. This is the principle of least privilege again. If your package works with a non-writable home directory, then you should probably be using the default of no home directory!
The world-writable bit should never be set in
ACCT_USER_HOME_PERMS
. This should never be necessary,
and is usually exploitable.
These guidelines are not written in stone, except perhaps for the
world-writable warning. There are packages in the tree that
chroot()
to $HOME
, and require that
directory to be owned by root:root
for security
reasons. In cases like that, it's impossible to avoid implicitly
tying the user to the package that needs it via the home directory,
and the best you can do is attempt to ensure that the users and
paths are unique so that no conflicts arise.
Unless your package is exceptional, though, following these guidelines will minimize the potential for problems down the road.