Users and Groups Overview

Every process runs as a user (UID). Users belong to one primary group (GID) and optional supplementary groups. Linux stores account data in plain-text databases protected by permissions:

File Purpose Permissions
/etc/passwd Account names, UIDs, homes, shells world-readable
/etc/shadow Hashed passwords, expiry root-only
/etc/group Group definitions and members world-readable
/etc/gshadow Group passwords (rare) root-only
  id alice
id                           # current user
groups bob
getent passwd alice
getent group sudo
awk -F: '$3 == 0 { print }' /etc/passwd   # UID 0 accounts
  

UID 0 is always root. System accounts typically use UIDs below 1000 (Debian) or below 500 (RHEL).

Creating Users

Debian/Ubuntu

  sudo adduser alice             # interactive; creates home, sets password
sudo adduser --disabled-password --gecos "" deploy   # automation user
sudo usermod -aG sudo alice    # grant sudo (Ubuntu)
sudo usermod -aG docker alice  # supplementary group
sudo chage -d 0 alice          # force password change on next login
  

RHEL/Fedora

  sudo useradd -m -s /bin/bash alice
sudo passwd alice
sudo usermod -aG wheel alice   # sudo group on RHEL family
sudo useradd -r -s /sbin/nologin nginx   # system account
  

Remove users:

  sudo deluser alice             # Debian; keep home
sudo deluser --remove-home alice
sudo userdel -r alice          # RHEL; -r removes home
  

Groups

  sudo groupadd developers
sudo groupadd -g 1500 appgroup   # explicit GID for NFS consistency
sudo usermod -aG developers alice
sudo gpasswd -d alice developers   # remove from group
sudo groupdel developers           # only if empty

getent group developers
  

Primary group is set at user creation; supplementary groups control access to shared resources (docker, www-data, disk groups).

sudo Configuration

Edit /etc/sudoers only with visudo — syntax errors lock out all sudo access.

  sudo visudo
sudo visudo -f /etc/sudoers.d/deploy   # drop-in file (preferred)
  

Examples:

  # Full sudo for alice
alice ALL=(ALL:ALL) ALL

# Passwordless restart only
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp

# Run as specific user
backup ALL=(postgres) NOPASSWD: /usr/bin/pg_dump *
  

Test before closing session:

  sudo -l -U alice
sudo -u postgres whoami
  

Password and Account Policies

  sudo passwd alice              # set password
sudo passwd -l alice             # lock account (prefix ! on hash)
sudo passwd -u alice             # unlock
sudo chage -l alice              # view expiry policy
sudo chage -M 90 -W 14 alice     # max 90 days, warn 14 days before
sudo chage -E 2026-12-31 alice   # account expires on date
  

Configure defaults in /etc/login.defs (PASS_MAX_DAYS, PASS_MIN_DAYS, UMASK).

Service Accounts

Applications run as dedicated users to limit blast radius:

  sudo useradd -r -s /usr/sbin/nologin -d /opt/myapp myapp
sudo chown -R myapp:myapp /opt/myapp
sudo chmod 750 /opt/myapp
  

Use -r for system UID, /usr/sbin/nologin to block interactive login, and no password (locked account).

PAM and Authentication

Pluggable Authentication Modules control login behavior via /etc/pam.d/:

  ls /etc/pam.d/
cat /etc/pam.d/common-auth      # Debian
cat /etc/pam.d/system-auth      # RHEL
  

LDAP/SSO integration, MFA, and password quality checks (pam_pwquality) hook in here — avoid editing PAM unless you understand lockout risk.

Best Practices

Practice Reason
One human user per person Audit trails and accountability
Least privilege via groups and sudo Avoid shared passwords
Disable unused accounts promptly Offboarded employees retain access otherwise
Use /etc/sudoers.d/ drop-ins Easier to manage than monolithic sudoers
Never edit /etc/shadow by hand Use passwd, useradd, usermod

Common Mistakes

Mistake Consequence
Shared deploy SSH key across team Cannot revoke one person
Adding users to docker group Equivalent to root (socket access)
usermod -G instead of -aG Removes all other supplementary groups
Broken sudoers syntax Total sudo lockout; requires recovery console
  # WRONG — replaces groups
sudo usermod -G docker alice

# CORRECT — append group
sudo usermod -aG docker alice
  

Troubleshooting

User cannot sudo: Check group membership (groups user), sudoers entry, and /var/log/auth.log for “not in sudoers”.

Account locked after failed logins: Check faillock --user alice (RHEL) or PAM pam_tally2 settings.

Home directory missing: sudo mkhomedir_helper alice or recreate with useradd -m.

Production Scenario

A SaaS platform provisions per-tenant Linux users on shared app servers:

  1. Terraform creates tenant_1234 system user with /usr/sbin/nologin
  2. Ansible sets ACLs so tenant can only write /data/tenant_1234
  3. sudoers.d allows ops team passwordless systemctl restart tenant-1234.service
  4. Offboarding runs userdel -r tenant_1234 and removes sudoers drop-in

Quarterly audit: awk -F: '$3 == 0 || $3 >= 1000 { print }' /etc/passwd cross-checked against HR roster.

Proper user hygiene is the foundation of multi-tenant servers, compliance audits, and incident response — know who can become root and how.