sudoers shell

the file that decides who gets to be god.

The sudoers file is the most powerful configuration file on your system and you’ve never read it. You’ve been told “add the user to the sudo group” and you did that and it worked and you never thought about it again.

But the sudoers file can do a lot more than “allow everything.” It can restrict specific users to specific commands. It can let the deploy user restart nginx without a password but nothing else. It can let the DBA run pg_dump as root but not rm. It can log every escalated command to syslog. It’s an entire access control system hiding in a single file, and you’ve been using it as an on/off switch.

The scariest part? One syntax error in this file and sudo stops working. For everyone. Including you. Including root. You can lock yourself out of your own machine by putting a typo in the wrong file. That’s why visudo exists — and why you should never, ever edit this file with vim or nano directly.

Unless you’re running Windows then wtf none of this applies to you. But hey, come to the dark side, go install WSL2 and you can follow along. We’ll wait. Impatiently.

This page has distro-specific commands. Pick your poison:
Set it and forget it. Like your firewall rules. Wait—

If you’re lazy like me (all sysadmins are!) then click here for the sudoers cheat sheet.


Always use visudo

sudo visudo

Opens /etc/sudoers in a safe editor that checks your syntax before saving. If you made a mistake, it warns you and gives you the option to re-edit, quit without saving, or save anyway (don’t pick that last one).

Never do sudo vim /etc/sudoers. Never. If you save a syntax error, sudo breaks and you can’t use sudo to fix it. You’ll be booting into recovery mode or single-user mode to fix a typo. visudo prevents this entirely.

Edit a drop-in file instead

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

Modern systems use drop-in files in /etc/sudoers.d/ instead of editing the main sudoers file. Each file contains rules for a specific user or role. Easier to manage, easier to audit, harder to break everything at once.

The main /etc/sudoers file has an @includedir /etc/sudoers.d directive at the bottom that loads these automatically.


The sudoers file format

Every rule follows this pattern:

WHO  WHERE = (AS_WHOM) WHAT
  • WHO — user or group (groups start with %)
  • WHERE — which hosts (usually ALL unless you’re managing a fleet)
  • AS_WHOM — which user to run as (usually ALL or root)
  • WHAT — which commands (full paths, or ALL)

The rule you’ve seen a hundred times

%sudo   ALL=(ALL:ALL) ALL

Translation: anyone in the sudo group, on any host, can run any command as any user or group. This is the default rule on Debian/Ubuntu systems. It’s the “allow everything” switch.

On Debian and Ubuntu, the default admin group is sudo:

sudo usermod -aG sudo username

On Fedora and RHEL, the default admin group is wheel:

sudo usermod -aG wheel username

After adding the user, they need to log out and back in for the group membership to take effect. Or they can run newgrp sudo (or newgrp wheel) to pick it up in the current session.


Give a user full sudo access

The group method above is preferred, but you can also add a direct user rule:

sudo visudo -f /etc/sudoers.d/alice
alice   ALL=(ALL:ALL) ALL

Alice can now run anything as root. Same as being in the sudo/wheel group, but explicit per-user.


Allow specific commands only

This is where sudoers gets actually useful instead of being a blunt instrument.

deploy  ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx

The deploy user can restart or reload nginx. Nothing else. Can’t stop it. Can’t start other services. Can’t read files. Can’t delete anything. Exactly the permissions needed, nothing more.

backup  ALL=(root) /usr/bin/rsync, /usr/bin/tar

The backup user can run rsync and tar as root. Enough to do backups. Not enough to do damage.

Important: always use full paths

# WRONG — user could create their own "systemctl" in PATH
deploy  ALL=(root) systemctl restart nginx

# RIGHT — explicit binary path
deploy  ALL=(root) /usr/bin/systemctl restart nginx

Without the full path, a user could create a malicious script called systemctl in their own directory and run it as root. Always use absolute paths in sudoers rules.


NOPASSWD: skip the password prompt

deploy  ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx

The deploy user can restart nginx without typing a password. Essential for automated deployments, CI/CD pipelines, and service accounts that can’t type interactively.

NOPASSWD for everything (use with caution)

deploy  ALL=(ALL) NOPASSWD: ALL

No password for anything. This is what people do when they’re tired of typing their password. It’s also what attackers love to find. Use this only for service accounts on locked-down systems, never for human users on shared machines.


Deny specific commands

intern  ALL=(root) ALL, !/usr/bin/su, !/usr/bin/bash, !/usr/bin/sh

The intern can run anything as root except shells and su. This prevents them from getting a permanent root shell. They can still run individual commands but can’t drop into an unrestricted session.

Note: this is defense in depth, not a security guarantee. A determined user with broad sudo access can find ways around command blacklists. Whitelisting specific commands is always safer than blacklisting.


Cmnd_Alias WEB = /usr/bin/systemctl restart nginx, \
                  /usr/bin/systemctl reload nginx, \
                  /usr/bin/systemctl status nginx

Cmnd_Alias BACKUP = /usr/bin/rsync, /usr/bin/tar, /usr/bin/gzip

deploy  ALL=(root) NOPASSWD: WEB
backup  ALL=(root) NOPASSWD: BACKUP

Aliases make complex policies readable. Group related commands, assign them to roles, and the intent of each rule is obvious at a glance.


Set a custom password timeout

The default timeout (how long your password is cached) is 15 minutes. Change it:

Defaults    timestamp_timeout=5

Cache for 5 minutes instead. Set to 0 to always prompt. Set to -1 to cache forever (don’t do this).

Per-user override:

Defaults:alice    timestamp_timeout=0

Alice always gets prompted. Everyone else keeps the global default.


Log everything

Defaults    logfile="/var/log/sudo.log"

Every sudo command gets logged to this file. Who ran what, when, from where. This is your audit trail. When something goes wrong at 3 AM and nobody remembers what they did, this file remembers.

Most systems also log sudo to syslog by default (/var/log/auth.log on Debian, /var/log/secure on RHEL). The logfile directive gives you a dedicated file that’s easier to grep through.


Validate your sudoers file

sudo visudo -c

Checks the syntax of /etc/sudoers and all files in /etc/sudoers.d/ without opening the editor. Returns either “parsed OK” or tells you exactly what’s wrong and on which line. Run this after any change to drop-in files.

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

Check a specific file.


“But just—”

Go on.

“I just give everyone root.” And when someone runs rm -rf / by accident? Or when a compromised user account gets full system access? Or when the auditor asks who has root privileges and you say “everyone”? The sudoers file exists so that “give them root” isn’t the only option. Specific permissions for specific tasks.

“The syntax is too complicated.” It’s WHO WHERE = (AS_WHOM) WHAT. Four fields. The main sudoers file even has comments explaining every line. And visudo catches your mistakes before they lock you out. It’s simpler than most config files you deal with daily.

“I just use su.” su requires knowing the root password. sudo uses your own password. su doesn’t log what the user did after switching. sudo logs every command. su is all-or-nothing. sudo is granular. There’s a reason every modern Linux distro defaults to sudo and many disable root login entirely.

“Drop-in files are overkill.” Drop-in files mean you can add and remove policies without touching the main sudoers file. You can manage them with configuration management tools. You can audit them individually. You can delete /etc/sudoers.d/intern when the intern leaves without editing a monolithic config. It’s not overkill — it’s basic operations.


sudoers cheat sheet

You made it. Or you skipped straight here. Either way, no judgment. Copy and paste these. Pin them. Tattoo them on your forearm. Whatever works.

Commands:

What you’re doing Command
Edit sudoers safely sudo visudo
Edit a drop-in file sudo visudo -f /etc/sudoers.d/name
Check syntax sudo visudo -c
See your permissions sudo -l

Common rules:

What you’re configuring Rule
Full access for a group %sudo ALL=(ALL:ALL) ALL
Full access for a user alice ALL=(ALL:ALL) ALL
Specific commands only deploy ALL=(root) /usr/bin/systemctl restart nginx
No password required deploy ALL=(root) NOPASSWD: /path/to/command
Deny a command user ALL=(root) ALL, !/usr/bin/su
Set password cache timeout Defaults timestamp_timeout=5

The one rule: WHO WHERE = (AS_WHOM) WHAT — every sudoers rule follows this pattern. Learn it once and the whole file makes sense.

Back to the top, you overachiever.