Sudo Explained

Sudo Explained

sudo is the standard way to run commands with elevated privileges on Linux. It sits between your regular user account and root access, providing a logged, controlled gateway. Understanding how it works and how to configure it correctly is a fundamental Linux administration skill.

How sudo works

When you run sudo somecommand:

  1. sudo checks /etc/sudoers (and files in /etc/sudoers.d/) to see if you are allowed to run that command
  2. If allowed, sudo prompts for your password (not root’s)
  3. sudo logs the command to the system journal and optionally /var/log/auth.log
  4. sudo executes the command with the requested privileges
  5. A short grace period (default: 15 minutes) lets you run further sudo commands without re-entering your password
# Run a single command as root
sudo apt update
sudo systemctl restart nginx
sudo cat /etc/shadow

# Run a command as a specific user
sudo -u postgres psql
sudo -u www-data ls /var/www/html

# Open a root shell (login shell, sets environment to root's)
sudo -i

# Open a root shell (non-login, keeps your environment)
sudo -s

# Run a command as root with root's environment
sudo -i ls /root

# Check what you are allowed to do
sudo -l

# Check what another user is allowed to do
sudo -l -U colton

# Re-authenticate (reset the timeout grace period)
sudo -v

# Invalidate the cached credentials immediately
sudo -k

The sudoers file

The main configuration is in /etc/sudoers. Never edit it directly with a text editor. Always use visudo, which validates syntax before saving.

# Open sudoers with the default editor
sudo visudo

# Open with a specific editor
sudo EDITOR=nano visudo

# Edit a file in /etc/sudoers.d/ (preferred for custom rules)
sudo visudo -f /etc/sudoers.d/colton

Sudoers syntax

# Basic syntax:
# user  host=(runas_user:runas_group)  commands

# Aliases (define reusable groups)
User_Alias    ADMINS = colton, alice, bob
Cmnd_Alias    WEBOPS = /bin/systemctl restart nginx, /bin/systemctl reload nginx
Host_Alias    SERVERS = web1, web2, db1

# Full root access for a user
colton ALL=(ALL:ALL) ALL

# Full root access for a group (% prefix = group)
%sudo  ALL=(ALL:ALL) ALL        # Debian/Ubuntu convention
%wheel ALL=(ALL) ALL            # Fedora/RHEL/Arch convention

# Specific commands only
colton ALL=(ALL) /usr/bin/systemctl, /usr/bin/journalctl

# No password prompt for specific commands
colton ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

# No password for everything (not recommended)
colton ALL=(ALL) NOPASSWD: ALL

# Run as a specific user only
colton ALL=(postgres) /usr/bin/psql

# Using aliases
ADMINS SERVERS=(ALL) WEBOPS

The /etc/sudoers.d/ directory

Custom rules belong in /etc/sudoers.d/ rather than in the main /etc/sudoers file. This prevents your custom rules from being overwritten when the sudo package updates:

# Create a file for a specific user or team
sudo visudo -f /etc/sudoers.d/colton

# File content:
# colton ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, \
#                             /usr/bin/systemctl reload nginx, \
#                             /usr/bin/systemctl status nginx

# Files in /etc/sudoers.d/ must not be world-writable and should not end in ~
# or contain a . (dot) -- these are silently ignored
ls -la /etc/sudoers.d/

Reading sudo -l output

sudo -l shows what your current user is permitted to do:

sudo -l
Matching Defaults entries for colton on server1:
    env_reset, mail_badpass, secure_path=/usr/local/sbin:...

User colton may run the following commands on server1:
    (ALL : ALL) ALL

A more restricted user might see:

User deploy may run the following commands on server1:
    (root) NOPASSWD: /bin/systemctl restart nginx
    (root) NOPASSWD: /bin/systemctl restart php8.2-fpm
    (root) /usr/bin/certbot renew

This means deploy can restart nginx and php-fpm without a password, but needs to enter their password to run certbot.

Common sudo patterns

Service management without full root

# /etc/sudoers.d/webops
deploy ALL=(root) NOPASSWD: /bin/systemctl restart nginx
deploy ALL=(root) NOPASSWD: /bin/systemctl reload nginx
deploy ALL=(root) NOPASSWD: /bin/systemctl restart php8.2-fpm
deploy ALL=(root) NOPASSWD: /bin/certbot renew

Database administration

# /etc/sudoers.d/dbadmin
# Allow running psql as the postgres user
dbadmin ALL=(postgres) /usr/bin/psql
dbadmin ALL=(postgres) /usr/bin/pg_dump
# Usage:
sudo -u postgres psql
sudo -u postgres pg_dump mydb > backup.sql

Monitoring and log access

# /etc/sudoers.d/monitoring
nagios ALL=(root) NOPASSWD: /usr/lib/nagios/plugins/*
monitor ALL=(root) NOPASSWD: /usr/bin/journalctl
monitor ALL=(root) NOPASSWD: /bin/cat /var/log/nginx/error.log

Restricting by command path

Sudoers matches commands by their full path. This matters: if you allow /usr/bin/vim, users could use vim to run shell commands and escape to root. Be specific about what you allow:

# Dangerous: vim can be used to escape to a shell
colton ALL=(ALL) /usr/bin/vim

# Better: allow editing only a specific file
colton ALL=(ALL) /usr/bin/vim /etc/nginx/nginx.conf

# Best: use a restricted editor or a purpose-built tool

Also be careful with commands that can spawn shells: less, man, find -exec, awk, python, and many other programs can be used to break out to a shell if granted via sudo.

sudo vs su

# su: switch to another user for the whole session
su -          # become root (needs root password)
su - postgres # become postgres user
exit          # return to your user

# sudo -i: become root via sudo (needs your password, is logged)
sudo -i       # root login shell
exit          # return to your user

# sudo -s: root shell, keep your environment
sudo -s
exit

# Check who you are
whoami
id

Audit logging

Every sudo command is logged. This is one of the main reasons to use sudo instead of direct root:

# View sudo usage on systemd systems
sudo journalctl | grep sudo
sudo journalctl _COMM=sudo

# View on Debian/Ubuntu
sudo grep sudo /var/log/auth.log

# Typical log entry:
# Jun 28 10:23:11 server1 sudo: colton : TTY=pts/0 ; PWD=/home/colton ;
#                                USER=root ; COMMAND=/usr/bin/apt upgrade

Troubleshooting

# "colton is not in the sudoers file"
# -- Add user to the sudo/wheel group, or add a sudoers entry
groups colton          # check group membership
id colton

# Group membership does not take effect until next login
# Test immediately with:
su - colton            # open a new session as colton
sudo whoami            # should now work

# "sudo: command not found" after sudo -i
# -- sudo -i resets PATH to root's PATH
# Run the full path, or add to /etc/sudoers Defaults secure_path

# Syntax error in sudoers (locked out of sudo)
# -- Boot to recovery mode or use pkexec (PolicyKit) as an alternative
pkexec visudo          # fix the sudoers file without sudo

# Check sudoers syntax without saving
sudo visudo -c -f /etc/sudoers.d/myfile

Frequently Asked Questions

What is sudo and why is it used instead of logging in as root?

sudo (superuser do) allows a permitted user to run a command as root (or another user) without logging in as root. It is preferred over direct root login for several reasons: it requires authentication (your own password, not root), it logs every command run with elevated privileges to the system audit log, it lets you grant users only the specific commands they need rather than full root access, and it means you work as your normal user by default, reducing the chance of accidentally running destructive commands with root power. The principle is that you should only have elevated privileges for the moments you need them.

What is the difference between sudo and su?

sudo runs a single command with elevated privileges and then returns you to your normal session. su (switch user) opens a new shell as another user, typically root, for the duration of your session. sudo is preferred because each invocation is logged, you authenticate with your own password rather than the root password, and access can be restricted to specific commands. su -l (or su -) opens a full login shell as root, inheriting root’s environment. sudo -i and sudo -s open an interactive root shell via sudo, which is logged.

What is /etc/sudoers and how do I edit it safely?

/etc/sudoers is the configuration file that controls who can run what with sudo. You must edit it with visudo (not a regular text editor) because visudo validates the syntax before saving, preventing a malformed sudoers file that could lock everyone out of sudo. The file uses a specific syntax: user host=(runas) command. Entries in /etc/sudoers.d/ (a directory of included files) follow the same syntax and are the preferred place to put custom rules so they are not overwritten by package updates.

How do I add a user to the sudo group?

On Debian and Ubuntu, add the user to the sudo group: usermod -aG sudo username. On Fedora, RHEL, and Arch, add the user to the wheel group: usermod -aG wheel username. The group membership grants access because /etc/sudoers contains a line like %sudo ALL=(ALL:ALL) ALL (Debian) or %wheel ALL=(ALL) ALL (RHEL). The change takes effect the next time the user logs in. Verify with su - username followed by sudo whoami, which should print “root”.

What does ALL=(ALL:ALL) ALL mean in sudoers?

The sudoers syntax is: who host=(runas_user:runas_group) commands. ALL=(ALL:ALL) ALL means: this rule applies on all hosts (ALL), the user can run commands as any user (ALL) and any group (ALL), and the allowed commands are all commands (ALL). The line %sudo ALL=(ALL:ALL) ALL means every member of the sudo group gets full root access on all hosts for all commands. More restrictive examples: colton ALL=(ALL) /usr/bin/systemctl means colton can only run systemctl. colton ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx means colton can restart nginx without a password prompt.

What is sudo -i vs sudo -s vs sudo su?

sudo -i starts a login shell as root, sourcing root’s profile files (~/.profile, ~/.bashrc etc.) and setting the working directory to /root. It is the cleanest way to work as root for an extended period via sudo. sudo -s starts a non-login shell as root, keeping your current environment variables but running as root. sudo su opens a root shell by running su through sudo, which is redundant but common in documentation. In all three cases, the session is initiated through sudo and logged. When finished with the elevated session, type exit to return to your normal user shell.