Configure Safe Subordinate Group ID Ranges with /etc/subgid
You will finish with a checked subordinate group ID allocation for a Linux user, plus a way to confirm which source supplies that allocation. This is the group-side configuration used by user namespaces and tools such as newgidmap. The examples are based on shadow-utils 4.13, provided here by Ubuntu package passwd version 1:4.13+dfsg1-4ubuntu3.2.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and read access to /etc/subgid. Changing that file needs elevated privileges and can affect containers or other user-namespace workloads. The inspection steps are ordinary commands; the edit is clearly marked as a security-sensitive change.
1. Check the installed contract
Read the local manual page and record the package version before relying on examples. Both commands are read-only:
$ man 5 subgid
$ dpkg-query -W -f='${Package} ${Version}\n' passwd
passwd 1:4.13+dfsg1-4ubuntu3.2
The local manual describes each entry as three colon-separated fields: a login name or numeric UID, the first subordinate group ID, and the number of IDs in the range. For example, alice:200000:65536 grants IDs 200000 through 265535, inclusive. The last number is a count, not the final ID.
Checkpoint
Write down the first ID and count you intend to allocate. Do not copy a range from another host until you have checked that the two systems do not share the same subordinate-ID space.
2. Find the active delegation source
Subordinate-ID delegation is selected by the subid entry in /etc/nsswitch.conf. The value files selects /etc/subgid. Any other value names a plugin as libsubid_VALUE.so; if that value or plugin is unavailable, shadow-utils falls back to files.
$ awk '$1 == "subid:" { print }' /etc/nsswitch.conf
$ if grep -Eq '^subid:[[:space:]]+files([[:space:]]|$)' /etc/nsswitch.conf; then
> printf '%s\n' 'source: /etc/subgid'
> else
> printf '%s\n' 'source: plugin or fallback; inspect the subid setting'
> fi
No output from the first command means there is no explicit subid line. Do not infer a network provider from that absence. Check the installed manual and the file contents, then test the consumer that needs the range. A plugin-backed setup may not keep its authoritative data in /etc/subgid.
3. Inspect existing ranges before choosing one
When files are the source, inspect the file without changing it:
$ sudo sed -n '1,120p' /etc/subgid
alice:200000:65536
build:265536:65536
Each displayed line is an example shape, not a range to reuse. Calculate every occupied interval and choose a new one that does not overlap. A small awk check can show the final ID for each valid-looking line:
$ awk -F: 'NF == 3 && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ {
> printf "%s: %s-%s (%s IDs)\n", $1, $2, $2 + $3 - 1, $3
> }' /etc/subgid
alice: 200000-265535 (65536 IDs)
build: 265536-331071 (65536 IDs)
Keep the arithmetic within the ID range supported by your kernel and deployment. A range grants namespace mapping authority; it is not a pool of ordinary groups to add with groupadd.
4. Choose a non-overlapping entry
Use a real login name or its numeric UID, then choose a first ID and count. The manpage allows multiple ranges for one user, so a second line for the same name is valid. In a large file, numeric UIDs can improve parsing performance. The local manual reports speed-ups of up to 20 times for files with roughly 10,000 to 100,000 or more entries, but that is a performance observation, not a reason to change existing names casually.
For this example, assume alice needs one unused range:
alice:331072:65536
Its IDs run from 331072 through 396607. Re-run the interval check against the complete file, including the proposed line, before installing it. Do not allocate ranges by counting lines: a line may request a different count, and two ranges can overlap even when their starting values differ.
5. Make the file change carefully
Warning
This step changes security-sensitive system configuration. It can change which group IDs a process may map in a child user namespace. Schedule the change if containers or other namespace users are active, and keep a tested rollback copy.
First prepare the new file in a temporary location. The example preserves the existing file and adds the proposed entry; replace the placeholder only after checking the interval:
$ tmp_subgid=$(mktemp)
$ cp /etc/subgid "$tmp_subgid"
$ printf '%s\n' 'alice:331072:65536' >> "$tmp_subgid"
$ awk -F: 'NF != 3 || $1 == "" || $2 !~ /^[0-9]+$/ || $3 !~ /^[0-9]+$/ || $3 == 0 { bad=1 } END { exit bad }' "$tmp_subgid"
$ awk -F: '{ start=$2; finish=$2+$3-1; for (i=1; i<NR; i++) if (start < end[i] && finish >= begin[i]) overlap=1; begin[NR]=start; end[NR]=finish } END { exit overlap }' "$tmp_subgid"
$ sudo cp -a /etc/subgid /etc/subgid.backup
$ sudo install -o root -g root -m 0644 "$tmp_subgid" /etc/subgid
$ rm -f "$tmp_subgid"
A silent return from each awk command means the fields passed those checks. The overlap check is intentionally simple and assumes all lines are numeric entries. If the real file contains comments, blank lines or malformed data, stop and repair or review it instead of forcing the replacement. The temporary file contains a copy of the existing allocation, so remove it after the install.
Recovery
If the change was wrong, restore the backup made before the edit, after stopping or coordinating with affected workloads:
$ sudo cp -a /etc/subgid /etc/subgid.before-rollback
$ sudo cp -a /etc/subgid.backup /etc/subgid
$ sudo chown root:root /etc/subgid
$ sudo chmod 0644 /etc/subgid
The rollback example assumes you created /etc/subgid.backup before changing the file. If no backup exists, do not invent one from memory. Recover the previous file from your host's approved backup system.
6. Verify the result and its consumer
Confirm the installed entry and its calculated end ID:
$ awk -F: '$1 == "alice" { printf "%s: %s-%s (%s IDs)\n", $1, $2, $2 + $3 - 1, $3 }' /etc/subgid
alice: 331072-396607 (65536 IDs)
The file describes permission for mapping; it does not itself create groups, map a process or prove that a container runtime can use the range. On a host with the relevant shadow-utils helper installed, test the actual namespace workflow used by your application. If newgidmap is absent, install or configure the package that owns that helper according to your distribution's change process. Do not replace the check with a guessed command.
Finally, inspect the file after any account-management operation. The subgid manual notes that groupadd writes /etc/subgid only when delegation is managed through subid files. A plugin-backed provider may therefore leave this file unchanged, while a files-backed provider may allocate a new range. Never assume the provider from the result of one command.
Done means
- The installed shadow-utils version and local
subgid(5)behaviour are recorded. - The
subidsource was checked before editing any file. - The entry has exactly three colon-separated fields and a positive count.
- The complete range is non-overlapping with existing allocations.
- The file was backed up before the security-sensitive change.
- The installed entry was re-read and its inclusive end ID calculated.
- The real namespace consumer was tested, or its missing helper was reported as a separate package issue.