visudo

Safely edit the sudoers policy with syntax checks and file locking to prevent lockouts.

Category: Security sudo sudoers privilege policy

Install

# visudo is shipped with the sudo package.

# RHEL / Alma / Rocky
sudo dnf install sudo

# Debian / Ubuntu
sudo apt install sudo

# openSUSE
sudo zypper install sudo

# Arch
sudo pacman -S sudo

What it does

visudo edits the sudo policy files (the “sudoers” configuration) in a safe way. It:

  • Locks the sudoers file so two admins don’t collide.
  • Runs a syntax check before saving.
  • Refuses to install a broken config that could lock you out of sudo.

Most of the time you use it to edit /etc/sudoers or (better) to manage files under /etc/sudoers.d/.

How it works (mechanical)

  • Opens a temp copy of the target sudoers file in your chosen editor, then validates the result.
  • Validation uses the sudoers parser (same logic sudo uses) and rejects syntax errors.
  • Uses file locking so concurrent edits don’t overwrite each other.
  • Targets a file with -f (default is /etc/sudoers).
  • Editor selection follows $VISUAL, then $EDITOR, then a compiled-in default (often vi).

Quick Start

# Minimal “prove it works” example: open the main sudoers file safely
sudo visudo
# Check sudoers syntax without editing (useful after automation)
sudo visudo -c

10 Practical Examples

# 1) Edit the main sudoers file safely
sudo visudo
# 2) Edit a dedicated drop-in rule file (recommended pattern)
# Create/modify: /etc/sudoers.d/90-admins
sudo visudo -f /etc/sudoers.d/90-admins
# 3) Validate the entire sudo policy now (no editor)
sudo visudo -c
# 4) Validate a specific sudoers.d file (great for CI or a post-edit check)
sudo visudo -c -f /etc/sudoers.d/90-admins
# 5) Use nano (or your preferred editor) for THIS run
sudo EDITOR=nano visudo
# 6) Use vim for THIS run (VISUAL overrides EDITOR)
sudo VISUAL=vim visudo
# 7) Show which editor would be used (quick sanity check)
# (This prints nothing; it just demonstrates the environment precedence)
echo "VISUAL=$VISUAL  EDITOR=$EDITOR"
# 8) Add an “admin group can sudo” rule (common on many distros)
# Inside a sudoers file (edited via visudo), add one of these lines:
#   %wheel ALL=(ALL) ALL
# or
#   %sudo  ALL=(ALL) ALL
# 9) Allow ONE command without a password (be precise!)
# Example: allow 'deploy' to restart nginx with no password prompt:
#   deploy ALL=(root) NOPASSWD: /bin/systemctl restart nginx
# 10) Safe workflow: make a drop-in, validate, then test from another terminal
sudo visudo -f /etc/sudoers.d/90-admins
sudo visudo -c
# In another terminal session:
sudo -l

Notes & Gotchas

  • Don’t edit sudoers with a raw editor. Always use visudo to avoid lockouts.
  • Prefer /etc/sudoers.d/ for local policy. Keep /etc/sudoers close to vendor defaults.
  • File permissions matter: sudo will ignore insecure sudoers files. Keep them root-owned and not writable by others.
  • Order matters: files in /etc/sudoers.d/ are typically read in lexical order. Name files accordingly (e.g., 10-, 90-).
  • Be careful with NOPASSWD: it is convenient but increases risk. Keep it narrow (one command, full path).
  • Always keep a second root session open when changing sudo rules on a remote machine.

Historical Context

Traditional Unix systems used direct root logins or su with shared passwords. sudo and the sudoers policy introduced auditable, per-user privilege elevation. visudo evolved as the “safe editor” to reduce the biggest operational risk: breaking sudoers and locking out administrators.

Modern Equivalent

visudo remains the standard safe interface for sudoers policy. For more structured/managed environments, organizations sometimes move policy management into configuration management (Ansible, Puppet, etc.)—but the final validation step often still uses visudo -c in pipelines.

Related Commands

  • sudo — execute a command with elevated privileges, per sudoers policy.
  • sudoedit — edit a file as root, using your editor, with safer semantics than running the editor as root.
  • su — switch user (often to root) using the target user’s password.
  • getent group — verify group membership (e.g., getent group wheel).
  • id — show user identity and groups (e.g., id deploy).