iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

sudo

sudo runs a single command as another user (root by default), gated by the sudoers policy. Using it well means understanding the password cache, NOPASSWD risks, environment handling, and how to scope grants narrowly with visudo.

sudoers, NOPASSWD, env, audit

EXAMPLE
# 1) Basic usage
sudo apt update                        # run as root
sudo -u deploy ./deploy.sh             # run as another user
sudo -i                                 # interactive root shell ($HOME = /root)
sudo -s                                 # shell as root, keeps current $HOME
sudo -v                                 # extend the password cache without running a command
sudo -k                                 # forget the cached credentials immediately

# 2) What it actually does
# • Reads /etc/sudoers + drop-ins under /etc/sudoers.d/
# • Looks up YOUR user / group permissions
# • Authenticates you (PAM)
# • Runs the command as the target user (root by default), in a sanitised env
# • Logs to syslog / journald / auditd (depending on distro)

# 3) View what YOU're allowed to run
sudo -l
# User mara may run the following commands:
#   (ALL : ALL) ALL
#   (root) NOPASSWD: /usr/bin/systemctl restart nginx

# 4) Edit the sudoers file SAFELY
sudo visudo                              # main file with syntax check on save
sudo visudo -f /etc/sudoers.d/deploy      # drop-in; survives package upgrades

# NEVER edit /etc/sudoers directly. A syntax error can lock you out of root entirely.
# visudo validates before saving.

# 5) Sudoers syntax — granting limited rights
# /etc/sudoers.d/deploy
Defaults:deploy        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# deploy can restart nginx and reload php-fpm without a password
deploy  ALL=(root) NOPASSWD: /bin/systemctl restart nginx
deploy  ALL=(root) NOPASSWD: /bin/systemctl reload php-fpm

# admins group can do everything but must enter their password
%admins ALL=(ALL:ALL) ALL

# alice can run a script as the 'backup' user
alice   ALL=(backup) /usr/local/bin/run-backup.sh

# Wildcards are SHARP — '/bin/systemctl restart *' lets you 'restart ../../arbitrary'
# Prefer exact commands.

# 6) The password timeout
# Default: 5-15 minutes (varies by distro). One sudo lasts for that window.
# Tune in sudoers:
Defaults timestamp_timeout=15            # minutes; 0 = always ask; -1 = never expire (DON'T)
Defaults timestamp_type=tty               # per-tty cache (safer than 'global')

# 7) Environment handling
# Sudo strips MOST environment variables by default (good — stops PATH/LD_PRELOAD attacks).
# To pass a few through:
sudo PATH=/opt/extra/bin:$PATH ./run.sh
sudo --preserve-env=API_KEY,HOME ./run.sh

# In sudoers, allow specific variables for specific commands:
Defaults env_keep += "HTTP_PROXY HTTPS_PROXY NO_PROXY"

# 8) Run a pipeline as root
sudo bash -c 'cat /var/log/secure | grep failed | tail -n 50'
# A naive 'sudo cat ... | grep ...' only runs cat as root; grep runs as you.

# 9) Edit a root-owned file safely
sudoedit /etc/nginx/nginx.conf            # makes an editable temp copy + writes back atomically
sudo -e /etc/nginx/nginx.conf              # same
# Why: this runs YOUR editor as YOU, then root writes the file. 'sudo vim' would expose vim plugins running as root.

# 10) Log + audit
# Every sudo invocation goes to:
#   /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL)
#   journalctl _COMM=sudo
# Track what people are doing:
sudo journalctl --since "-1d" _COMM=sudo
sudo grep "COMMAND=" /var/log/auth.log | tail -50

# 11) NOPASSWD — convenient and dangerous
#   ✓ Good use: one specific automated command in a CI/CD pipeline
#   ✗ Bad use: 'deploy ALL=(ALL) NOPASSWD: ALL' — equivalent to giving the deploy user root
#   ✗ Bad use: NOPASSWD on commands with shell escapes (vim, less, awk, find -exec)
#
# 'less' lets you ':!sh', 'vim' lets you ':!sh', 'find . -exec sh {} \;' opens a shell.
# Wrap dangerous commands in a script you control:
deploy  ALL=(root) NOPASSWD: /usr/local/bin/restart-app.sh

# /usr/local/bin/restart-app.sh
#!/bin/bash
set -euo pipefail
systemctl restart myapp
# Now the only thing NOPASSWD'd is that exact script.

# 12) Auth methods
# Default: PAM. PAM can require:
#   • Password
#   • U2F / FIDO2 token (pam-u2f)
#   • Yubikey OTP
#   • TOTP (libpam-google-authenticator)
#   • Touch ID on macOS
# Configure in /etc/pam.d/sudo. Two-factor sudo for production servers is a strong control.

# 13) Per-host limitations
#   user  host1,host2=(root) ALL
# If your sudoers file is shared across many hosts via config management, this is
# how you scope grants to specific machines.

# 14) Aliases for readability
User_Alias  DEVOPS = mara, sam, alex
Host_Alias  PROD = web1, web2, db1
Cmnd_Alias  RESTART = /bin/systemctl restart *, /bin/systemctl reload *

DEVOPS  PROD = (root) NOPASSWD: RESTART

# 15) doas — minimal alternative
# Some distros / users prefer 'doas' (from OpenBSD) — smaller config surface, no rich features.
# /etc/doas.conf
permit nopass keepenv :wheel as root
doas systemctl restart nginx

# 16) Common bugs
#   • Edited /etc/sudoers directly, broke syntax — boot recovery / pkexec to fix
#   • Granted NOPASSWD on 'tee' or 'dd' — those can overwrite /etc/passwd
#   • Forgot to use sudoedit — vim plugins / .vimrc ran as root
#   • PATH attacks — wrote NOPASSWD: my-script but didn't pin secure_path
#   • Cached creds survived across sudo invocations a user didn't notice — set timestamp_type=tty
#   • 'sudo su -' chain confuses logs — use 'sudo -i' or a single 'sudo -u target cmd'
#   • Trying to read /var/log/auth.log with no sudo — chicken/egg; ensure your user is in adm or similar group
#   • Wildcards in command paths — exploit via path traversal in argument; use absolute paths and exact commands

Why it matters

sudo is a privilege gate, not a convenience. Edit sudoers with visudo (it validates), grant exact commands rather than wildcards, restrict NOPASSWD to wrapper scripts you control, and never edit a file with sudo vim — reach for sudoedit so your editor never runs as root.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
sudo apt update
sudo -i                  # interactive root shell
Try it Yourself »

Discussion

Loading…