Add a system user with useradd

I want to add a system user with useradd.

useradd test -r -d /var/lib/test -s /sbin/nologin

The directory /var/lib/test will not be created.

1 Like

Add parameter -m.

[ian@elise ~]$ useradd -h
Usage: useradd [options] LOGIN
       useradd -D
       useradd -D [options]

  -m, --create-home             create the user's home directory

providing -d just means you want to change the home directory location, it won’t actually create it. Even using useradd without -m won’t even create under /home/ unless you provide it. Mine for a basic system with a directory under /home would be:

useradd -m -s /bin/bash iwalker

for example would create /home/iwalker using bash as the shell. Adding -d and the path like you did would just change where it gets created when providing the -m parameter.

man useradd is more verbose on details than useradd -h

The /etc/default/useradd defines SHELL=/bin/bash on typical install. That is the default shell. However, the /bin is a mere symlink to /usr/bin and hence /bit/bash is /usr/bin/bash via symlink dereference. Probably no observable diffirence. Similarly, /sbin is symlink to /usr/sbin.

Note on -r:

-r, --system
Create a system account.

System users will be created with no aging information in /etc/shadow, and their numeric identifiers are chosen 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 useradd can create home without -m – CREATE_HOME is ‘yes’ – but not for system account.

Rather than -d, one could use -b.
-d /var/lib/test and -b /var/lib are equivalent for accout test.

SElinux has ruleset for home directories. Directories under /var/lib get different context than directories under /home. The system account does not depend on SElinux?

I’ve generally found it a good habit/practice to get into to use the -s parameter for setting the shell (just like the OP did to disable the shell), mainly because I use various distributions - Debian for example, defaults to /bin/sh, so if running this command without editing /etc/default/useradd, then I end up with the wrong shell assigned. In such cases, it doesn’t then matter to me what is set in /etc/default/useradd - I always get the system configured how I want without having to rely on defaults applied to the file.

Sure, I could configure this file, if I remember to do it on all the different distros that I use, or have Ansible prepare the system for me. Then I could forget about using it on the command line. If I used just one distro that defaulted to /bin/bash then that would also negate the need for specifying it on the command line - for example as you mentioned with Rocky.


That is a very good point.

I have most accounts on LDAP/Kerberos and there too I do set values explicitly (not using useradd).

On a cluster that does use local accounts, I now use Ansible (that probably calls useradd) and best practices for it do recommend explicit config as well. Everything about user/thing in one place is way better than chasing defaults (especially when they differ in every way in different distros).

I tried useradd -r -d /var/lib test and useradd -r -b /avr/lib/test test.

The passwd file looks like test:x:994:991::/usr/lib/test:/bin/bash
The group file looks like test:x:991:
The directory /var/lib/test will not be created.

Should have a system account a /bin/bash or /sbin/nologin?

You need -m parameter to create home directory, as you didn’t use it, it didn’t get created. An account will need a shell if you wish to login to the system via SSH for example. If you set /sbin/nologin, then it won’t be possible to get a shell and use it for administration. Normally if you were creating users just for sending/receiving files via FTP or SFTP then you would disable the shell so that they cannot do anything via SSH for example.

The -m parameter create a home directory in /home/test and not in /var/lib/test

A Debian Admin type adduser --system test --home /var/lib/test

Here, let me give you an example, if you want a different directory than /home, you need to specify -d /path/to/home as well. So:

root@redmine:~# mkdir /mytestusergroup
root@redmine:~# useradd -m -s /bin/bash -d /mytestusergroup/testuserian testuserian
root@redmine:~# ls /mytestusergroup/
root@redmine:~# ls /home/ | grep testuserian
root@redmine:~# cat /etc/passwd | grep testuser

First I create /mytestusergroup as this is the directory I want the home directory, second I use the -m to create home directory and -d to change from default of /home/username, then I check in mytestusergroup directory and you can see home is created, and last I check under /home to see if it was create here, and no it wasn’t - to prove that the command I gave works. And lastly, I check /etc/passwd to show it created exactly as my command.

1 Like

How does man adduser describe the option --system in Debian?