๐Ÿ”‘ sudo & Privileges

Users & Groups Series: Part 1 โ€” Basics  |  Part 2 โ€” Advanced Management  |  Part 3 โ€” sudo & Privileges

Privilege Management on Linux

sudo โ€” Superuser Do โ€” is the standard mechanism for granting controlled, audited, elevated privileges on Linux. Rather than sharing the root password or running services as root, sudo lets specific users run specific commands as root (or any other user), with every action logged to syslog and the audit trail.

Properly configured sudo is the difference between "everyone knows the root password" and a system where every privileged action is attributed to a named person and can be reviewed. This page covers sudoers syntax, best practices, and the principle of least privilege in practice.

Anatomy of a sudoers Rule

# WHO WHERE AS WHOM WHAT alice ALL =(ALL) ALL # alice can run any command on any host as any user %wheel ALL =(ALL) ALL # The wheel group can run any command (standard admin group) bob ALL =(root) /usr/bin/systemctl restart httpd # bob can only restart httpd โ€” nothing else %webteam ALL =(root) NOPASSWD: /usr/bin/systemctl reload nginx # webteam can reload nginx without a password prompt

Fields: WHO (user or %group) ยท WHERE (hostname, usually ALL) ยท AS WHOM (runas user) ยท WHAT (command or ALL)

Examples

1
Basic sudo Usage
# Run a single command as root
sudo dnf update
sudo systemctl restart nginx
sudo vi /etc/hosts

# Run as a specific user (not root)
sudo -u postgres psql
sudo -u www-data php artisan migrate

# Get an interactive root shell
sudo -i          # login shell โ€” loads root's environment
sudo -s          # non-login shell โ€” keeps current environment
sudo su -        # equivalent to sudo -i

# Run a command with root's environment
sudo -H vi /etc/nginx/nginx.conf

# List what sudo you are allowed to run
sudo -l
sudo -l -U alice   # check another user's sudo rights (as root)

# Reset sudo timestamp (re-prompt for password next time)
sudo -k

# Extend sudo timeout without running a command
sudo -v
๐Ÿ’ก sudo -l is your friend. Before asking "why can't I run this?", run sudo -l to see exactly what commands you are permitted to run. It shows the full effective policy for your account.
2
Editing sudoers Safely โ€” visudo
# ALWAYS use visudo โ€” never edit /etc/sudoers directly
sudo visudo

# visudo validates syntax before saving
# A syntax error in /etc/sudoers can lock out all sudo access

# Edit a specific drop-in file (preferred method)
sudo visudo -f /etc/sudoers.d/webteam

# Check syntax of a sudoers file without applying
sudo visudo -c -f /etc/sudoers.d/webteam

# List all sudoers files
ls -la /etc/sudoers.d/
โš ๏ธ Never edit /etc/sudoers with a regular editor. A syntax error in sudoers disables ALL sudo access system-wide. If you lock yourself out of sudo, you need physical console access or single-user mode to fix it. visudo validates syntax before saving โ€” use it, always. If you must edit directly, keep a root shell open as a safety net.
๐Ÿ’ก Use /etc/sudoers.d/ drop-ins. Rather than editing the main sudoers file, create separate files in /etc/sudoers.d/ โ€” one per team or role. They are automatically included. Easier to manage, easier to audit, and a syntax error in one drop-in doesn't affect the others.
3
Common sudoers Configurations
# /etc/sudoers.d/admins โ€” full admin access
%wheel  ALL=(ALL)  ALL
%admins ALL=(ALL)  ALL

# /etc/sudoers.d/webteam โ€” web team, specific commands only
%webteam ALL=(root) NOPASSWD: \
    /usr/bin/systemctl restart nginx, \
    /usr/bin/systemctl reload nginx, \
    /usr/bin/systemctl status nginx

# /etc/sudoers.d/dbadmins โ€” database team
%dbadmins ALL=(root) NOPASSWD: \
    /usr/bin/systemctl restart postgresql, \
    /usr/bin/systemctl restart mysqld
%dbadmins ALL=(postgres) NOPASSWD: /usr/bin/psql

# /etc/sudoers.d/monitoring โ€” read-only monitoring
monitoring ALL=(root) NOPASSWD: \
    /usr/bin/journalctl, \
    /usr/bin/ss, \
    /usr/bin/df, \
    /usr/bin/top, \
    /usr/bin/ps

# Allow a user to edit specific files with sudoedit
alice ALL=(root) sudoedit /etc/nginx/conf.d/*.conf

# Command alias โ€” group commands under a name
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, \
                      /usr/bin/systemctl stop *, \
                      /usr/bin/systemctl restart *
%sysadmin ALL=(root) SERVICES
NOPASSWD โ€” use carefully. NOPASSWD removes the password prompt for that command. Good for service accounts and automation scripts. Avoid it for interactive admin commands โ€” the password prompt is a speed bump that makes accidental misuse less likely.
4
Add Users to wheel / sudo Group
### RHEL / Rocky / AlmaLinux โ€” uses wheel group ###

# Add user to wheel group
sudo usermod -aG wheel alice

# Verify wheel is enabled in sudoers (should be uncommented)
grep wheel /etc/sudoers
# Should show: %wheel  ALL=(ALL)  ALL

# Remove from wheel group
sudo gpasswd -d alice wheel


### Debian / Ubuntu โ€” uses sudo group ###

# Add user to sudo group
sudo usermod -aG sudo alice

# Verify
grep sudo /etc/sudoers
# Should show: %sudo  ALL=(ALL:ALL)  ALL

# On either system โ€” verify user's sudo access
sudo -l -U alice
su - alice -c "sudo -l"
wheel vs sudo group: RHEL-family distros use wheel as the admin group. Debian/Ubuntu use sudo. Both are configured in sudoers to allow full root access. The group name is the only difference โ€” the concept is identical.
5
sudo Logging and Auditing
# Every sudo command is logged โ€” view with journalctl
sudo journalctl -t sudo
sudo journalctl -t sudo --since today
sudo journalctl -t sudo -n 50

# On systems with /var/log/secure or /var/log/auth.log
sudo grep sudo /var/log/secure | tail -20         # RHEL
sudo grep sudo /var/log/auth.log | tail -20       # Debian/Ubuntu

# See who ran what sudo commands
sudo journalctl -t sudo | grep "COMMAND" | tail -20

# Enhanced logging โ€” add to sudoers for detailed logs
sudo visudo
# Add these lines:
# Defaults  logfile=/var/log/sudo.log
# Defaults  log_input, log_output
# Defaults  iolog_dir=/var/log/sudo-io/%{user}
journalctl sudo output example:
Apr 25 10:22:15 server sudo[12345]: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/systemctl restart nginx Apr 25 10:25:33 server sudo[12350]: bob : TTY=pts/1 ; PWD=/home/bob ; USER=root ; COMMAND=/usr/bin/dnf update Apr 25 10:31:07 server sudo[12401]: mallory : TTY=pts/2 ; PWD=/home/mallory ; USER=root ; COMMAND=/usr/bin/bash Apr 25 10:31:07 server sudo[12401]: pam_unix(sudo:auth): authentication failure
๐Ÿ’ก sudo logs are your audit trail. Every privileged action is logged with username, working directory, and the exact command. When something breaks or a security incident occurs, the sudo log tells you who did what and when. Review it regularly โ€” failed sudo attempts are worth investigating.
6
sudoedit โ€” Safe File Editing

sudoedit (or sudo -e) lets a user edit a privileged file safely โ€” it copies the file to a temp location, opens it in the user's own editor, then copies it back. No root shell involved:

# User edits /etc/nginx/nginx.conf without getting a root shell
sudoedit /etc/nginx/nginx.conf
sudo -e /etc/nginx/nginx.conf    # same thing

# Grant sudoedit permission in sudoers (safer than NOPASSWD: /usr/bin/vi)
# In /etc/sudoers.d/webteam:
# alice ALL=(root) sudoedit /etc/nginx/conf.d/*.conf

# sudoedit respects the user's EDITOR/VISUAL environment variable
export EDITOR=vim
sudoedit /etc/hosts
sudoedit vs sudo vi. Never grant NOPASSWD: /usr/bin/vi in sudoers โ€” a user with root vi access can run :!/bin/bash from inside vi and get a root shell. sudoedit avoids this entirely โ€” the editor runs as the user, not as root. This is the correct way to grant file editing privileges.
7
Sudo Security Best Practices
# Useful Defaults settings to add to sudoers
sudo visudo
# Require password re-entry after 5 minutes (default is 15)
Defaults  timestamp_timeout=5

# Require password even for NOPASSWD commands when session is new
Defaults  timestamp_type=tty

# Log all sudo commands to a dedicated file
Defaults  logfile=/var/log/sudo.log

# Send mail on sudo failures (bad password etc.)
Defaults  mailto=sysadmin@example.com
Defaults  mail_badpass

# Prevent environment variable injection attacks
Defaults  env_reset
Defaults  env_keep += "LANG LC_ALL LC_MESSAGES LC_CTYPE LC_COLLATE LC_TIME"

# Secure PATH โ€” use only known-good directories
Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Show a lecture to new sudo users
Defaults  lecture=always
Defaults  lecture_file=/etc/sudo_lecture
โš ๏ธ Principle of least privilege. Grant only the specific commands a user needs โ€” not ALL unless they are a full sysadmin. A developer who needs to restart their application service should get exactly that: NOPASSWD: /usr/bin/systemctl restart myapp โ€” not full root.
8
Switching Users โ€” su vs sudo
# su โ€” switch user (requires target user's password)
su alice               # switch to alice, keep environment
su - alice             # switch to alice, load her full environment
su -                   # switch to root (requires root password)

# sudo su โ€” use sudo to become another user without their password
sudo su - alice        # become alice (requires YOUR sudo password)
sudo -u alice -i       # equivalent โ€” open alice's login shell
sudo -u postgres psql  # run a command as postgres user

# runuser โ€” run a command as another user (root only, no PAM)
sudo runuser -l postgres -c "pg_dump mydb > /backup/mydb.sql"
sudo runuser -u www-data -- php artisan queue:work

# Check who you are after switching
id
whoami

# Exit back to original user
exit    # or Ctrl-D
CommandPassword neededEnvironmentLogged?
su - aliceAlice's passwordAlice's full envPartially
sudo -u alice -iYour sudo passwordAlice's full envYes โ€” fully
sudo -iYour sudo passwordRoot's full envYes โ€” fully
sudo -sYour sudo passwordCurrent envYes โ€” fully
runuser -l userNone (root only)User's full envYes
๐Ÿ’ก Prefer sudo over su. sudo logs every action with your username attached. su - to root logs the switch but not what you did afterward โ€” the audit trail stops. On a well-managed system, the root password should be unknown to everyone and all privileged work done via sudo.

Quick Reference

CommandWhat it does
sudo COMMANDRun command as root
sudo -u USER COMMANDRun command as specific user
sudo -iInteractive root login shell
sudo -lList your sudo permissions
sudo -l -U userList another user's sudo permissions
sudo -kInvalidate sudo timestamp (force re-auth)
sudo -vExtend sudo timeout
sudo visudoEdit sudoers safely with syntax check
sudo visudo -f /etc/sudoers.d/fileEdit a drop-in sudoers file
sudo visudo -c -f fileCheck sudoers file syntax only
sudoedit FILEEdit privileged file safely (no root shell)
sudo usermod -aG wheel userAdd user to wheel (RHEL admin group)
sudo usermod -aG sudo userAdd user to sudo (Debian admin group)
journalctl -t sudoView all sudo log entries
sudo runuser -l user -c CMDRun command as user (no PAM)

sudoers Quick Syntax Reference

RuleEffect
alice ALL=(ALL) ALLalice has full root access everywhere
%wheel ALL=(ALL) ALLwheel group has full root access
alice ALL=(root) /usr/bin/systemctlalice can only run systemctl as root
alice ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginxNo password needed for this specific command
alice ALL=(postgres) /usr/bin/psqlalice can run psql as postgres user
alice ALL=(root) sudoedit /etc/nginx/conf.d/*.confSafe file editing with wildcards
Defaults timestamp_timeout=5Re-prompt after 5 minutes
Defaults logfile=/var/log/sudo.logLog all sudo to dedicated file

← Back to Users-Groups Index ↑ Back to EXPANDED