How to Use sudo on Linux: Complete Guide

Tested on: Ubuntu 26.04 LTS · Debian 12 · Fedora 44 · Arch Linux · AlmaLinux 10 — Last updated: June 2026

sudo is the primary mechanism for privilege escalation on Linux. It lets specific users run commands as root — or as any other user — while keeping a full audit trail and avoiding the security risks of a permanently logged-in root session. Misconfiguring it locks you out; under-configuring it creates security gaps. This guide covers everything from basic usage to locked-down service account configurations.

Contents
  1. Prerequisites
  2. What sudo Actually Does
  3. sudo vs su vs Direct Root Login
  4. Basic sudo Usage
  5. Adding a User to the sudo Group
  6. The sudoers File: Syntax and Configuration
    1. sudoers Syntax Reference
    2. Configuring the sudo Timeout
  7. Running Commands as Another User
  8. sudo and Environment Variables
  9. Auditing sudo Usage
  10. Troubleshooting
    1. "alice is not in the sudoers file. This incident will be reported."
    2. "sudo: command not found" after su or in a restricted shell
    3. sudo keeps asking for a password even within 15 minutes
    4. visudo reports a syntax error
    5. Further Reading

Prerequisites

  • A Linux system running any major distribution (Ubuntu, Debian, Fedora, Arch, RHEL/AlmaLinux/Rocky)
  • An existing user account with sudo or root access (to add other users or modify sudoers)
  • Basic terminal familiarity — you know how to open a shell and run commands

What sudo Actually Does

sudo stands for "superuser do," though it can run commands as any user, not just root. When you prefix a command with sudo, the sudo binary:

  1. Reads /etc/sudoers (and files in /etc/sudoers.d/) to check whether your user or group is permitted to run that command
  2. Prompts for your own password — not root's — to confirm you're the person at the keyboard
  3. Forks a new process owned by the target user (default: root) and executes the command
  4. Logs the event to the system journal or /var/log/auth.log
  5. Caches your authentication for a configurable timeout (default: 15 minutes per terminal)

The practical difference from logging in as root: every privileged action is tied to your username in the logs, not to the anonymous root account.

# Without sudo — permission denied
apt update
# E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)

# With sudo — works
sudo apt update
# [sudo] password for alice:
# Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
# Reading package lists... Done

sudo vs su vs Direct Root Login

These three approaches all grant root access but with very different security and audit implications:

MethodWhat it doesPassword requiredWhen to use
sudo commandRuns one command as rootYour passwordSingle privileged operations
sudo -iOpens a root login shellYour passwordMultiple root tasks in sequence
sudo -sRoot shell, keeps your environmentYour passwordWhen you need root shell but your env vars
su -Switches to root userRoot's passwordSystems with root password set (some Debian installs)
su usernameSwitches to another userThat user's passwordMulti-user systems
Direct root loginFull root sessionRoot's passwordEmergency recovery only — avoid in normal use

Ubuntu disables the root password entirely by default — su - will fail unless you explicitly set one. Debian gives you the choice during installation. Fedora, Arch, and RHEL-based systems use a wheel group rather than sudo for the same purpose.

Basic sudo Usage

# Run a single command as root
sudo apt update

# Edit a protected file
sudo vim /etc/hosts

# Run a command as a specific user (not root)
sudo -u www-data ls /var/www/html

# Open a root shell (full root environment, home dir = /root)
sudo -i

# Open a root shell but keep your current environment
sudo -s

# Check exactly what commands your user is allowed to run
sudo -l

# Re-run the previous command with sudo (bash only)
sudo !!

# Reset the sudo timestamp — forces password re-entry next time
sudo -k

# Extend the sudo session without running a command
sudo -v

sudo -l is particularly useful on systems you didn't configure yourself — it shows you exactly what you're permitted to do:

sudo -l
# Matching Defaults entries for alice on server1:
#     env_reset, mail_badpass, secure_path=...
#
# User alice may run the following commands on server1:
#     (ALL : ALL) ALL

Adding a User to the sudo Group

The simplest way to grant full sudo access is adding a user to the appropriate group. The group name differs by distribution:

# Ubuntu / Debian — group is "sudo"
sudo usermod -aG sudo username

# Fedora / RHEL / AlmaLinux / Rocky Linux / CentOS Stream — group is "wheel"
sudo usermod -aG wheel username

# Arch Linux — group is "wheel"; also requires enabling it in sudoers
sudo usermod -aG wheel username

On Arch (and some minimal Debian/RHEL installs), adding to the wheel group alone isn't enough — the group must be enabled in /etc/sudoers:

sudo visudo
# Find this line and uncomment it:
# %wheel ALL=(ALL:ALL) ALL

Group membership changes don't take effect in the current session. The user must log out and back in, or start a new login shell:

# Verify after the user logs back in
groups username
# username : username sudo

# Or check from the user's own session
id
# uid=1001(username) gid=1001(username) groups=1001(username),27(sudo)

The sudoers File: Syntax and Configuration

All sudo permissions are defined in /etc/sudoers. Never edit this file directly with a standard text editor. A syntax error will lock every user out of sudo — potentially locking you out of the system entirely. Always use visudo, which validates syntax before saving:

sudo visudo

For distribution-specific overrides and application configs, drop files into /etc/sudoers.d/ — they're included automatically and can be managed independently:

sudo visudo -f /etc/sudoers.d/deploy

sudoers Syntax Reference

# Format: user  HOST=(run_as_user:run_as_group) commands

# Allow alice to run any command as root on any host
alice  ALL=(ALL:ALL) ALL

# Allow bob to run only apt and systemctl as root
bob    ALL=(root) /usr/bin/apt, /usr/bin/systemctl

# Allow the "sudo" group to run anything (Ubuntu default)
%sudo  ALL=(ALL:ALL) ALL

# Allow the "wheel" group to run anything (Fedora/Arch default)
%wheel ALL=(ALL:ALL) ALL

# Allow the deploy user passwordless sudo for specific commands only
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php8.3-fpm

# Allow a log-monitoring user to read journals only
logwatcher ALL=(root) NOPASSWD: /usr/bin/journalctl

# Allow a user to run commands as the postgres user (not root)
dbadmin ALL=(postgres) /usr/bin/psql, /usr/bin/pg_dump

The ALL=(ALL:ALL) ALL triplet breaks down as: any host = ALL, run as any user = (ALL, run as any group = :ALL), any command = final ALL. For most single-server configurations, the host field is effectively irrelevant and set to ALL.

Configuring the sudo Timeout

The 15-minute authentication cache is a Defaults setting in sudoers. Adjust it based on your security requirements:

# In /etc/sudoers via visudo — or in /etc/sudoers.d/timeout

# Set global timeout to 30 minutes
Defaults  timestamp_timeout=30

# Require password for every single sudo invocation
Defaults  timestamp_timeout=0

# Never expire (not recommended for shared or multi-user systems)
Defaults  timestamp_timeout=-1

# Per-user override — alice gets 60 minutes, everyone else gets default
Defaults:alice  timestamp_timeout=60

# Timestamp per terminal (tty) rather than per user session — more secure
Defaults  timestamp_type=tty

Running Commands as Another User

sudo -u runs a command under a different user account entirely — useful for web server processes, database management, and application deployments without sharing passwords:

# Check permissions as the web server user
sudo -u www-data ls -la /var/www/html

# Open a PostgreSQL shell as the postgres system user
sudo -u postgres psql

# Run a command as another user with their full login environment
sudo -Hu appuser bash

# Run a script as a service account
sudo -u deploy /opt/app/scripts/deploy.sh

sudo and Environment Variables

By default, sudo resets most environment variables before running the command. This is intentional security behavior — a compromised PATH or LD_PRELOAD in the calling environment shouldn't affect the privileged process:

# sudo's clean environment — note PATH is restricted
sudo env | grep PATH
# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Pass a specific variable through
sudo FOO=bar env | grep FOO

# Preserve your entire environment (use cautiously — security implications)
sudo -E command

# Preserve PATH specifically without -E
sudo env PATH="$PATH" command

# Check the full environment sudo provides
sudo env

If you need specific environment variables to pass through reliably, add them to sudoers with env_keep rather than using -E globally:

# In sudoers via visudo:
Defaults  env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY"

Auditing sudo Usage

Every sudo invocation — successful or denied — is logged. This is one of sudo's most important security properties: you know exactly who ran what, and when:

# View sudo events in the systemd journal (most modern distros)
journalctl | grep sudo

# Filter to just the current boot
journalctl -b | grep sudo

# On older systems or those using traditional syslog
grep sudo /var/log/auth.log        # Debian/Ubuntu
grep sudo /var/log/secure          # Fedora/RHEL/AlmaLinux

# Watch sudo activity in real time
journalctl -f | grep sudo

A successful sudo entry looks like this:

Jun 12 14:32:01 server1 sudo[18345]: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update

A failed attempt (wrong password or unauthorized command) is also recorded, making it straightforward to detect privilege escalation attempts in your audit logs.

Troubleshooting

"alice is not in the sudoers file. This incident will be reported."

The user isn't in the sudo group or doesn't have a sudoers entry. If you have another sudo-capable account on the system:

# From another admin account
sudo usermod -aG sudo alice      # Ubuntu/Debian
sudo usermod -aG wheel alice     # Fedora/Arch/RHEL

If no sudo access is available, boot into recovery mode (Ubuntu: hold Shift at boot → Advanced → recovery mode → root shell), or boot from a live USB, mount the filesystem, and use chroot to run usermod.

"sudo: command not found" after su or in a restricted shell

The user's PATH doesn't include /usr/bin. This happens after su username (without the -) or in minimal environments:

# Call sudo by full path
/usr/bin/sudo apt update

# Or switch user with a login shell to get the full PATH
su - username

# Verify where sudo lives
which sudo || type sudo

sudo keeps asking for a password even within 15 minutes

This happens when timestamp_type=tty is set and you switch terminals, or when sudo timestamps are stored per-tty. It can also mean the timestamp directory has wrong permissions:

# Check timestamp type in sudoers
sudo grep timestamp /etc/sudoers /etc/sudoers.d/*

# Fix timestamp directory permissions if corrupted
sudo chmod 700 /run/sudo/ts
sudo chown root:root /run/sudo/ts

# Extend current session explicitly
sudo -v

visudo reports a syntax error

visudo will show you the line number and refuse to save a broken file. When it asks "What now?", type e to go back and fix the error, or x to discard all changes and exit safely. Never force-save a broken sudoers file. Common mistakes: missing spaces around =, a comma instead of a space between commands, or a typo in a keyword like NOPASSWD.

Go up

This site uses cookies for analytics and advertising (Google AdSense). By continuing to browse, you accept our use of cookies. Learn more