Skip to content
elephantoo

Users, groups & sudo

Lesson 9 of 31 15 min read

/etc/passwd and /etc/group, useradd, usermod, passwd, groups and using sudo safely.


Linux was built as a multi-user system from day one. Every file has an owner, every process runs as some user, and permissions decide who can do what. Even on your personal laptop there are dozens of users: most belong to system services, so that a hacked web server can't read your SSH keys. Understanding users and groups is essential for permissions, servers, Docker and security.

Who am I?#

Terminal
whoami
id
Output
ada
uid=1000(ada) gid=1000(ada) groups=1000(ada),4(adm),27(sudo),100(users)

(Output from a typical Ubuntu desktop; your groups will differ.)

  • UID (user ID): the number the kernel actually uses. Names are just labels for humans.
  • GID: your primary group, used as the group owner of files you create. On Debian/Ubuntu/Fedora each user gets a private group with the same name.
  • groups: supplementary groups that grant extra rights. Being in sudo (Debian/Ubuntu) or wheel (Fedora/RHEL) lets you use sudo.

groups prints just the group names, and id ben shows another user.

Kinds of users#

TypeUID rangeExamplesCan log in?
root0rootYes (but often locked)
System users1–999www-data, mysql, sshd, systemd-networkNo: shell is /usr/sbin/nologin
Regular users1000+ada, benYes
nobody65534nobodyNo: an owner of last resort

root can read any file, kill any process and change anything. That's why you work as a normal user and borrow root power only when needed.

The user database: /etc/passwd, /etc/shadow, /etc/group#

Terminal
head -3 /etc/passwd
Output
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

Each line has seven colon-separated fields:

Output
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
   │     │  │  │     │        │           └─ login shell
   │     │  │  │     │        └─ home directory
   │     │  │  │     └─ comment / full name (GECOS)
   │     │  │  └─ primary GID
   │     │  └─ UID
   │     └─ password placeholder (real hash is in /etc/shadow)
   └─ username
Terminal
ls -l /etc/passwd /etc/shadow /etc/group
Output
-rw-r--r-- 1 root root    673 Sep 30 16:35 /etc/group
-rw-r--r-- 1 root root   1426 Sep 30 16:35 /etc/passwd
-rw-r----- 1 root shadow  718 Sep 30 16:35 /etc/shadow

Everyone can read /etc/passwd (programs need to map UIDs to names), but only root can read /etc/shadow, where password hashes live. /etc/group lists groups and their members (sudo:x:27:ada,ben).

Don't edit these files by hand. Use the tools below, or getent, which also covers users from LDAP or Active Directory:

Terminal
getent passwd root
getent group sudo
Output
root:x:0:0:root:/root:/bin/bash
sudo:x:27:

List the regular (human) accounts with a little awk, which you'll learn properly later:

Terminal
awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwd

sudo: borrowing root's power#

Terminal
sudo apt update           # run one command as root
sudo -u postgres psql     # run a command as ANOTHER user
sudo -i                   # an interactive root shell (use sparingly; exit with `exit`)
sudo -l                   # what am I allowed to run?
sudo !!                   # re-run the previous command with sudo

sudo asks for your own password (then remembers it for about 15 minutes), checks the rules in /etc/sudoers, and logs every use (see them with journalctl _COMM=sudo or in /var/log/auth.log). Grant sudo by adding a user to the right group rather than editing the rules:

Terminal
sudo usermod -aG sudo ben       # Debian/Ubuntu
sudo usermod -aG wheel ben      # Fedora/RHEL

If you must change the rules, always use sudo visudo: it checks the syntax before saving, so a typo can't lock everyone out of sudo. Drop extra rules in /etc/sudoers.d/ files, e.g. deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp lets the deploy user restart one service without a password.

su - ben switches to another user's full login environment, but needs their password (or use sudo su - ben / sudo -iu ben).

Managing users#

The commands in the rest of this lesson change system accounts, so they were not run on our test machine. They are the standard tools on Debian, Ubuntu and Fedora; try them in a virtual machine or a throwaway cloud server.

Terminal
sudo adduser ben                 # Debian/Ubuntu: friendly, interactive; creates home, asks for password
sudo useradd -m -s /bin/bash ben # Low-level, works everywhere (Fedora's adduser is an alias for it)
sudo passwd ben                  # set or reset ben's password
passwd                           # change your own password
sudo usermod -aG docker ben      # add to a supplementary group (-a = append!)
sudo usermod -s /bin/zsh ben     # change login shell (or `chsh -s /bin/zsh` for yourself)
sudo usermod -L ben              # lock the account (-U unlocks)
sudo chage -l ben                # password expiry information
sudo deluser --remove-home ben   # Debian/Ubuntu: delete user and home
sudo userdel -r ben              # everywhere: same thing

useradd without -m creates no home directory, a classic gotcha. On Debian/Ubuntu prefer adduser for humans.

A system user for a service, with no login and no home:

Terminal
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp

You'll use exactly this in the systemd and deployment lessons, so your app doesn't run as root.

Managing groups#

Terminal
sudo groupadd developers               # create
sudo usermod -aG developers ada        # add a member (or: sudo gpasswd -a ada developers)
sudo gpasswd -d ada developers         # remove a member
sudo groupdel developers               # delete
getent group developers                # who's in it?

Group membership is read at login. After adding yourself to a group, log out and back in (or run newgrp developers in the current shell) before it takes effect. This is why docker commands still say "permission denied" right after usermod -aG docker $USER.

A shared project folder for a group (the setgid bit 2 was covered in the permissions lesson):

Terminal
sudo mkdir /srv/project
sudo chgrp developers /srv/project
sudo chmod 2775 /srv/project     # group can write; new files inherit the group

Common mistakes#

  • usermod -G without -a, wiping a user's other groups.
  • Expecting new group membership to apply without logging in again.
  • Editing /etc/sudoers with a normal editor instead of visudo.
  • Running services, scripts or pip install as root out of habit.
  • Sharing one login (or the root password) between people. Give everyone their own account and sudo access so actions are traceable.

What's next#

Next you'll learn about hard links and symbolic links: how one file can have several names, and how shortcuts to files and directories work.

Check your understanding

Quick quiz

0/3 answered
  1. 1.You added user ben to the docker group with sudo usermod -aG docker ben. Why must you be careful with the -a flag?

  2. 2.Where are users' hashed passwords stored on a modern Linux system?

  3. 3.What is the safest way to run a single admin command as a normal user?

Finished reading?

Mark this lesson complete to track your progress.