michael orlitzky

Gentoo GLEP81 user package guidelines

posted 2019-11-21

Background

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).

Fun summary

Almost every group ebuild should look like,

EAPI=7

inherit acct-group

ACCT_GROUP_ID=8675309

and almost every user ebuild should look like,

EAPI=7

inherit acct-user

ACCT_USER_ID=8675309
ACCT_USER_GROUPS=( "${PN}" )

acct-user_add_deps

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.

Boring details

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:

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.

The shell

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.

The home directory

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:

  1. 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.

  2. 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,

Home directory ownership

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.

Home directory permissions

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.

Wrapping up

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.