LXD/What are subuids and subgids?
When setting up LXD, one of the things you must do for unprivileged container configuration is to set up two files,
/etc/subgid. These files assign "sub-uids" and "sub-gids" to a specific user. But what are subuids and subgids anyway? This page is here to try to explain what they are and how they work.
There is a little-used feature called "subuids" and "subgids" that is used by LXD. It's best to think about it this way. In Linux, every user has a primary user id and group id. This is easy to understand, so we will build on this concept. When a user creates a file, it is owned by their user id on disk, and when they run a process, it is run under the context of their user id.
/etc/subgid let you assign extra user ids and group ids to a particular user, in bulk -- in other words, you can assign a whole bunch of them to a user with a single line in one of these files. The files have the format of:
Above, "username" would be the literal username, "start" would be a UID or GID starting number, and "count" would be the number of ids to assign.
I'm Still Confused -- What are these things?
When you assign additional user ids or group ids to a user, they become reserved for use exclusively by that user. This
means that the range of ids you assign are no longer available to be assigned to other users, either as their primary user and group ids, or via future assignment via the
It also means that the user to which they are assigned now 'owns' these ids, so that the user can change ownership of files to be owned by these ids, and run processes under these ids.
While we tend to get used to the idea of each user only having one id to work with, the concept itself is actually not that confusing.
/etc/subgid just allow you to assign blocks of ids to users in bulk, and
/etc/subuid is kind of interesting because we aren't used to the idea of a user having more than one user id.
How Does LXD Use Subuids?
Normal Linux systems generally only use the ids between 0 to 65536. However, the actual "uid and gid space" is actually much larger than this and can be useful for use by containers.
When LXD runs an unprivileged container, one of the ways that it isolates this container from your main system (and potentially also from other containers) is to "shift" the user ids and group ids inside the container to very high values, so they are not shared at all with the ids on your main system. This way, even if a user were able to 'escape' their container and has root access, they would not be able to access any files on your main system. This is because if their container were using the UID space starting at 1,000,000, their root UID would actually be 1,000,000 and not 0, so from the perspective of your main system, they would just be a regular user and be denied access by default.
For LXD to shift unprivileged containers to use very high UIDs and GIDs, it needs to have a block of these UIDs and GIDs reserved for its use. This is where
/etc/subgid come in and why creating the reservation of ids is required as part of LXD setup.