What Makes a System User?

QR Code linking to this page

Written by David Evans, first published

When creating a user with useradd on Linux (specifically Debian and Debian-derived distributions like Ubuntu), one of the available flags is --system. This flag is explained as:

Create a system account.

System users will be created with no aging information in /etc/shadow, and their numeric identifiers are choosen in the SYS_UID_MIN-SYS_UID_MAX range, defined in /etc/login.defs, instead of UID_MIN-UID_MAX (and their GID counterparts for the creation of groups).

Note that useradd will not create a home directory for such a user, regardless of the default setting in /etc/login.defs (CREATE_HOME). You have to specify the -m options if you want a home directory for a system account to be created.

Note that this option will not update /etc/subuid and /etc/subgid. You have to specify the -F options if you want to update the files for a system account to be created.

This tells us a few of the differences: system users have no password aging, have no home directory by default (their home directory is still set on the user, but it isn’t created), do not have sub-User-IDs or sub-Group-IDs assigned by default, and have a different User ID and Group ID range (typically UID < 1000 means system user, but this varies depending on the distribution. See SYS_UID_MIN/_MAX and UID_MIN/_MAX in /etc/login.defs).

So, practically speaking, what difference does this make?

Switching a user to / from being a system user

If you have accidentally created a non-system user that should be a system user (or vice-versa), it is possible to apply various changes to switch their effective type. Note that other than the User ID and Group ID ranges, all other distinctions between regular and system users are purely defaults, and can be mixed-and-matched.

From regular user to system user

Note: this guide is specifically written for Debian. It should apply to other distributions too, but some paths and default values may be different.

  1. Change the User ID:

    • check /etc/passwd to see which User IDs are available (third column); find the largest available User ID in the 0–1000 range

    • ensure the user is not running any processes, or the next step will be rejected

    • run the following command:

      sudo usermod --uid <chosen-uid> <user-name>
      
    • if the user owns any files outside their home directory, re-apply their ownership (sudo chown <user-name> <file>)

  2. Change the Group ID:

    • check /etc/group to see which Group IDs are available (third column); find the largest available Group ID in the 0–1000 range

    • run the following command:

      sudo groupmod --gid <chosen-gid> <group-name>
      
    • if the group is assigned to any files (including files in a home directory), re-apply the ownership (sudo chgrp <group-name> <file>)

  3. Clear the password aging configuration:

    sudo chage --mindays -1 --maxdays -1 --warndays -1 <user-name>
    
  4. Optionally delete the home directory for the user, to match the default for system users:

    sudo rm -r /home/<user-name>
    

    To avoid spurious warnings from pwck, you can mark the user as intentionally not having a home directory with:

    usermod --home /nonexistent <user-name>
    

    (/nonexistent is a special name recognised by the tooling to silence warnings about the home directory not existing)

  5. Optionally delete sub-uids and sub-gids for the user, to match the default for system users:

    sudo usermod --del-subuids 0-999999999 --del-subgids 0-999999999 <user-name>
    

From system user to regular user

Note: this guide is specifically written for Debian. It should apply to other distributions too, but some paths and default values may be different.

  1. Change the User ID:

    • check /etc/passwd to see which User IDs are available (third column); find the smallest available User ID above 1000

    • ensure the user is not running any processes, or the next step will be rejected

    • run the following command:

      sudo usermod --uid <chosen-uid> <user-name>
      
    • if the user owns any files outside their home directory, re-apply their ownership (sudo chown <user-name> <file>)

  2. Change the Group ID:

    • check /etc/group to see which Group IDs are available (third column); find the smallest available Group ID above 1000

    • run the following command:

      sudo groupmod --gid <chosen-gid> <group-name>
      
    • if the group is assigned to any files (including files in a home directory), re-apply the ownership (sudo chgrp <group-name> <file>)

  3. Optionally set password aging configuration:

    sudo chage --mindays 0 --maxdays 99999 --warndays 7 <user-name>
    

    These are the default values, but you can set whatever you need.

  4. Optionally create a home directory for the user:

    sudo cp -r /etc/skel /home/<user-name>
    sudo chown -R <user-name>:<group-name> /home/<user-name>
    

    If the user had a home directory set to /nonexistent, you will need to update it:

    usermod --home /home/<user-name> <user-name>
    
  5. Optionally create sub-uids and sub-gids for the user:

    • check /etc/subuid and /etc/subgid to see which IDs are available (if there are no entries in these, check /etc/login.defs to see the SUB_UID_MIN and SUB_GID_MIN values. You may also want to check SUB_UID_COUNT and SUB_GID_COUNT to see the size of the default range allocated to new users)

    • pick a range of UIDs and/or GIDs and run:

      sudo usermod --add-subuids <from>-<to> --del-subgids <from>-<to> <user-name>
      

      Note that ranges are inclusive of both lower and upper bounds.

Other system-user-like options

No SSH login

To prevent logging in via SSH (even if the user is accidentally given a password), it’s possible to set any trivial executable (such as /bin/false) as the user’s shell, but a better choice is to use /usr/sbin/nologin, which was created for this purpose:

usermod --shell /usr/sbin/nologin <user-name>

No home directory

Sometimes it is necessary for a system user to have a home directory, but most of the time it is not needed. The default behaviour of useradd is to mark the user as having a regular home directory (/home/<user-name>), but not create it. This is fine, but will trigger warnings with some linting tools, for example pwck prints:

user '<user-name>': directory '/home/<user-name>' does not exist

To mark the user as intentionally having no home directory, the convention is to set their home directory to /nonexistent. There is nothing special about this path, except that it is unlikely to exist on any system, and is recognised by linting tools as a way to silence these warnings.

To change an existing user’s home directory, run:

usermod --home /nonexistent <user-name>

Note that the user must not be running any processes when this command runs, or it will fail.

More information / further reading