Enable nss-systemd and Verify User Lookups
Dynamic service users, systemd-homed accounts and machine users all need nss-systemd switched on before getent can see them at all. This guide enables the module, checks that ordinary name lookups still work, and shows where records from systemd services or JSON drop-ins appear. The installed machine uses systemd 255 and Debian package version 255.4-1ubuntu8.17 for libnss-systemd:amd64. Allow about fifteen minutes. You need a shell and root access only for the configuration change.
The route
Jump straight to the step you need, or tick off Done means at the end.
The module matters when user or group identities come from systemd components rather than only /etc/passwd and /etc/group. It resolves identities exposed through the User/Group Record Lookup API, including dynamic service users, systemd-homed users and machine users, and it provides fallback handling for the root and nobody identities when the traditional files do not supply them.
1. Record the current configuration
Start with read-only checks. They show which NSS module is installed and which databases already ask for the systemd source:
$ dpkg-query -W -f='${Package} ${Version}\n' libnss-systemd:amd64
libnss-systemd 255.4-1ubuntu8.17
$ ldconfig -p | grep libnss_systemd
libnss_systemd.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libnss_systemd.so.2
$ sed -n '/^passwd:/p;/^group:/p;/^shadow:/p;/^gshadow:/p' /etc/nsswitch.conf
Your library path and package revision may differ. The important check is that libnss_systemd.so.2 is available. If the four NSS lines already contain systemd, do not add a second copy.
Checkpoint
Save a copy of the four relevant lines in your terminal or change review. It gives you an easy rollback reference if a later edit is not what you intended.
2. Add systemd after the file databases
Open /etc/nsswitch.conf with your normal administrative editor. This changes the host's identity resolution order, so treat it as a privileged configuration change:
$ sudoedit /etc/nsswitch.conf
Ensure the relevant lines contain systemd after files:
passwd: files systemd
group: files systemd
shadow: files systemd
gshadow: files systemd
The manual's fuller group example uses [SUCCESS=merge] before systemd, which asks NSS to merge a successful group result with later sources. Keep an existing site-specific control action if your machine relies on it; do not replace an entire nsswitch.conf file with a copied example. The practical rule: files stays first, so local passwd, group, shadow and gshadow mappings take precedence.
Warning
Do not remove files as a shortcut. A typo in this file can make users, groups or authentication databases appear to vanish. If the edit is wrong, restore the four recorded lines with sudoedit and test again. The edit itself does not create users, alter passwords or restart services.
3. Verify ordinary lookups
Use getent, which asks the configured NSS stack rather than reading one file directly:
$ getent passwd root nobody
root:x:0:0:root:/root:/bin/bash
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
$ getent passwd 0 65534
root:x:0:0:root:/root:/bin/bash
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
Exact fields vary with the local account database. Check that the names and numeric IDs are plausible, not that the home directory or shell matches this example. Querying a name or numeric ID returns a non-zero status when no source can resolve it:
$ getent passwd ACCOUNT_THAT_DOES_NOT_EXIST
$ printf 'lookup status: %s\n' "$?"
lookup status: 2
That empty result is normal for a deliberately unknown account. Do not diagnose the module from a single application that caches identities; repeat the check with getent and inspect the NSS lines.
4. Check identities supplied by systemd
nss-systemd prefers systemd-userdbd.service when it is available, but it can work without that service running. Dynamic users are normally exposed while the service that owns them is active. To test a real identity, replace the placeholder with a name supplied by your own service or machine:
$ getent passwd DYNAMIC_USER_NAME
$ getent group DYNAMIC_GROUP_NAME
A blank result means this host currently has no matching record, not that the module has failed. For a machine managed by systemd-machined, names may be generated from the machine and user namespace. The manpage's example uses names such as vu-rawhide-0 and vg-rawhide-0; those names only exist while the corresponding container and mapping exist, so do not paste them as universal expected output.
When a service uses DynamicUser=, test during its active lifetime. Stop the service and the temporary identity may disappear by design. That is not a reason to copy the name into /etc/passwd: dynamic allocation and persistence have different ownership and cleanup rules.
5. Add a static JSON record only when you need one
Static records are an advanced alternative to traditional account files. nss-systemd searches /etc/userdb/, /run/userdb/, /run/host/userdb/ and /usr/lib/userdb/. A user record uses a world-readable NAME.user file and a UID symlink such as 4711.user pointing to it. Group records use .group and the corresponding numeric GID symlink. The JSON structure is defined by the systemd User and Group Record specifications, not by an arbitrary passwd-like format.
Security boundary
Keep privileged data separate. A .user-privileged or .group-privileged companion is for sensitive fields and must be readable only by root. The ordinary record must not contain the privileged section; this matters if the record can be returned to an untrusted lookup client.
Before installing a record, check for collisions:
$ getent passwd ACCOUNT_NAME
$ getent passwd 4711
$ getent group GROUP_NAME
$ getent group 4711
Do not continue if an existing account already owns the name or numeric ID. Static records generally do not override conflicting entries from /etc/passwd, /etc/group or other databases, so a conflict produces confusing results rather than a clean replacement. Installing files in /etc/userdb/ is a privileged, persistent change: keep the original files and symlinks so you can remove exactly what you added if the lookup test fails.
Common traps
- A file-backed user works but a systemd identity does not. Check the spelling, the identity's lifetime and the relevant provider. A stopped dynamic-user service cannot supply its transient record. A machine user requires the machine and its user namespace to exist. A static record requires both its name-based file and its numeric symlink for both lookup forms.
- Every lookup fails after the edit. Inspect
/etc/nsswitch.conffirst and restore the recorded lines if necessary. Usegetentinstead of testing only one application, because applications can cache results or use a different lookup path. Do not restart authentication services or reboot while the basic NSS configuration is still uncertain. - Expecting nss-systemd to manage users. It is a lookup provider, not a user-management command. It does not create a home directory, assign a password, start
systemd-userdbd.serviceon demand in every situation, or make a dynamic identity permanent.
Done means
- Module installed:
libnss_systemd.so.2is present and its package version is recorded. - Lines updated:
passwd,group,shadowandgshadowincludesystemdafterfiles, where appropriate. - Ordinary lookups pass:
getentresolves known local accounts by name and numeric ID. - Dynamic identities tested live: only while their provider exists.
- No collisions: any JSON record avoids existing name and UID or GID collisions.
- Rollback ready: you have a copy of the previous NSS lines and can undo a bad edit without guessing.