Day 5 - Users, Groups, and Sudo

2025-09-256 min read

linuxusersgroupssudosecuritypasswdshadow

Day5 Dots

Accounts and privileges form the base of system security. This lesson explains user and group records, how to create and modify accounts, how to grant controlled administrative rights with sudo, and how to keep account data safe.

Account data at a glance

Core files: /etc/passwd user list, /etc/group group list, /etc/shadow password hashes and aging, /etc/sudoers and /etc/sudoers.d/ sudo policy. Read them with getent instead of parsing them directly.

Prerequisites

  • Day 1 through Day 4 completed
  • A terminal and a user account with sudo

Inspect current identity and records

bash
whoami                    # current username
id                        # uid, gid, and group memberships
getent passwd "$USER"     # full user record
getent group sudo 2>/dev/null || getent group wheel

Record formats:

  • /etc/passwd fields: name:x:uid:gid:gecos:home:shell
  • /etc/group fields: name:x:gid:members
  • /etc/shadow fields are readable only by root and hold password hashes and aging data
Do not edit system files directly

Avoid editing /etc/passwd, /etc/group, or /etc/shadow by hand. Use account tools that validate entries. Use vipw and vigr only when necessary and with care.

Create users and groups

Debian and Ubuntu provide adduser with friendly prompts. Low level tools are useradd, groupadd, and passwd on all distributions.

bash
# create a group
sudo groupadd developers || true

# create a user with a home directory and default shell
sudo useradd -m -s /bin/bash alice
sudo passwd alice

# add existing user to a group
sudo usermod -aG developers alice

# Fedora family often uses wheel group for sudo
getent group wheel || sudo groupadd wheel || true

Check results.

bash
getent passwd alice
id alice
getent group developers

Remove accounts safely.

bash
sudo userdel -r alice    # remove user and home directory
sudo groupdel developers || true
System users

Service accounts use low uid ranges and usually have /usr/sbin/nologin or /bin/false as shell. They exist to run daemons and should not be used for interactive login.

Passwords, locking, and aging

bash
# set or change a password
sudo passwd bob

# lock or unlock an account without changing the password hash
sudo passwd -l bob
sudo passwd -u bob

# view and set password aging
sudo chage -l bob
sudo chage -M 90 -W 14 bob   # max age 90 days, warn 14 days before expiry

For public key only users on servers, consider locking the password and requiring SSH keys.

Never store plain text passwords

Use password hashes in /etc/shadow only. Prefer SSH keys for remote admin and use a password manager for secrets.

sudo basics and least privilege

Sudo lets trusted users run specific commands as root or as another user. Always grant the minimum required access.

Check sudo version and policy path.

bash
sudo -V | grep -E "Sudoers|visudo|Plugins" -n

Grant access by adding users to a sudo group that is already enabled by the distribution.

bash
# Ubuntu and Debian family
grep -nE "%sudo|%admin" /etc/sudoers
sudo usermod -aG sudo "$USER"    # or admin on older releases

# Fedora and many RHEL based systems
grep -n "%wheel" /etc/sudoers
sudo usermod -aG wheel "$USER"

Test sudo and record a log entry.

bash
sudo -l           # list allowed commands
sudo whoami       # should print root if policy allows
Use visudo

Edit policy with visudo to validate syntax and prevent broken sudo. Prefer drop in files under /etc/sudoers.d/ with descriptive names.

Example minimal policy in a drop in file.

bash
# create a drop in
printf '%s\n' '%sudo ALL=(ALL:ALL) ALL' | sudo tee /etc/sudoers.d/00-sudo-group >/dev/null
sudo visudo -c   # validate

Limit access to one command with a command alias.

bash
# allow the deploy group to restart a service only
printf '%s\n' \
'Cmnd_Alias RESTART = /usr/bin/systemctl restart myapp.service' \
'%deploy ALL=(root) NOPASSWD: RESTART' | sudo tee /etc/sudoers.d/deploy-restart >/dev/null
sudo visudo -c
Avoid ALL with NOPASSWD

Granting unlimited root access without a password removes accountability. Use NOPASSWD only for narrow, low risk commands.

Use sudoedit for safe file edits with elevated rights.

bash
sudoedit /etc/ssh/sshd_config

Audit sudo use.

bash
sudo journalctl -t sudo -r 2>/dev/null || sudo grep -i sudo /var/log/auth.log 2>/dev/null

su versus sudo

  • su starts a shell as another user and requires that user's password. su - simulates a full login shell.
  • sudo runs a single command as root or another user and authenticates the invoking user. It supports detailed policy and logging.

Prefer sudo for admin tasks on most systems. Use su - only when a full root shell is necessary and allowed by policy.

Fixing ownership and group access

bash
# take ownership of a home subdirectory
sudo chown -R "$USER":"$USER" "$HOME/projects"

# set a shared directory with team write access
sudo mkdir -p /srv/shared
sudo chgrp developers /srv/shared
sudo chmod 2775 /srv/shared     # setgid so new files inherit the group
Name service and getent

On systems with LDAP, SSSD, or Active Directory, getent returns users and groups from remote sources as well. This keeps scripts compatible across environments.

Practical lab

Create a limited operator role for restarting one service and confirm logging and prompts.

  1. Create a deploy group and add a test user.
bash
sudo groupadd deploy || true
sudo useradd -m -s /bin/bash operator || true
sudo usermod -aG deploy operator
sudo passwd operator
  1. Add a narrow sudo policy.
bash
sudo bash -c 'cat > /etc/sudoers.d/deploy-restart <<"EOF"\nCmnd_Alias RESTART = /usr/bin/systemctl restart nginx.service\n%deploy ALL=(root) NOPASSWD: RESTART\nEOF'

sudo visudo -c
  1. Verify.
bash
sudo -u operator -H bash -lc 'id; sudo -l; sudo systemctl restart nginx.service; sudo -l'
  1. Check logs.
bash
sudo journalctl -t sudo -r 2>/dev/null || sudo tail -n 50 /var/log/auth.log 2>/dev/null

Troubleshooting

  • user is not in the sudoers file Add the user to the correct group or create a drop in under /etc/sudoers.d/. Validate with visudo -c.
  • Group membership changes do not apply in the current shell. Log out and in again or run newgrp <group>.
  • permission denied on a shared directory. Ensure the group owns the directory and that the setgid bit is set. Example chmod 2775 /srv/shared.
  • Sudo prompt does not accept the password. Confirm the keyboard layout and that Caps Lock is off. Check account lock status with passwd -S <user> and unlock if needed.
  • Remote accounts from LDAP or AD are missing. Confirm that getent returns them and that sssd or the name service is running.

Next steps

Day 6 covers permissions and ownership in depth. It explains the rwx model, directory execution rules, special bits like setgid and sticky, default permissions with umask, and introduces ACLs for fine grained control.