Skip to content

Sudoers: NOPASSWD Without Holes

Unrestricted NOPASSWD in sudoers is a misconfiguration that grants root access without a password, turning any user script or library vulnerability into a full system compromise. The correct approach limits NOPASSWD to specific commands only.

Why NOPASSWD + ALL Is a Hole, Not a Solution

%admin ALL=(ALL) NOPASSWD: ALL — the most common sudoers error. The user receives unlimited root access without a password. Any script, any utility, any vulnerability in the user’s environment becomes a direct path to full machine control. NOPASSWD without command restrictions is not convenience; it is a backdoor in plain sight.

The proper method: allow specific commands via Cmnd_Alias and attach NOPASSWD only to them. Then the user can restart a service but cannot read /etc/shadow or run su.

visudo: The Only Safe Way to Edit sudoers

Editing /etc/sudoers directly via vi or nano is a path to locking yourself and the entire team out. visudo locks the file, validates syntax before saving, and rejects invalid entries.

# Correct path:
sudo visudo

# If the default editor is inconvenient:
sudo EDITOR=nano visudo

# For separate files in /etc/sudoers.d/:
sudo visudo -f /etc/sudoers.d/deployer
Warning

A syntax error in sudoers = loss of sudo capabilities for all. visudo prevents this, but only when used.

Cmnd_Alias: Grouping Commands Instead of Allowing Everything

Cmnd_Alias lets you create a named group of commands. You then reference the name — readable and easy to change.

Cmnd_Alias RESTART_WEB = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
Cmnd_Alias RESTART_DB = /usr/bin/systemctl restart postgresql
Cmnd_Alias PACKAGE_MGMT = /usr/bin/apt, /usr/bin/yum, /usr/bin/dnf
Cmnd_Alias LOG_VIEW = /usr/bin/tail, /usr/bin/journalctl

Alias syntax: name in uppercase, comma-separated absolute paths. The path is mandatory — systemctl without /usr/bin/ will not work.

Example: Limited NOPASSWD for Specific Tasks

Real scenario: a deployer user needs to restart nginx and view logs, nothing more.

Cmnd_Alias RESTART_WEB = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
Cmnd_Alias LOG_VIEW = /usr/bin/journalctl, /usr/bin/tail

deployer ALL=(ALL) NOPASSWD: RESTART_WEB, LOG_VIEW

Now deployer can:

sudo systemctl restart nginx    # without password
sudo journalctl -u nginx        # without password
sudo apt update                 # denied
sudo su                         # denied

To allow a single user one binary:

monitor ALL=(ALL) NOPASSWD: /usr/bin/tail /var/log/syslog
Tip

For multiple users performing the same task — use a group. %deployers ALL=(ALL) NOPASSWD: RESTART_WEB is more maintainable than duplicating lines.

What to Avoid: Common sudoers Mistakes

ОшибкаПочему плохоКак правильно
ALL ALL=(ALL) NOPASSWD: ALLFull root without passwordList specific commands via Cmnd_Alias
user ALL=NOPASSWD: /bin/bashOpens root shellNever give interpreters or su
user ALL=(ALL) ALL, NOPASSWD: ALLNOPASSWD spreads to everything due to orderNOPASSWD: before the command list, not after
Editing /etc/sudoers via echo or cpNo syntax validationOnly visudo or visudo -f
Absence of #includedir /etc/sudoers.dManual file overwritten on updateCheck include, place custom rules in /etc/sudoers.d/

Another frequent trap — spaces in Cmnd_Alias. A comma and space after it are mandatory:

# Correct:
Cmnd_Alias WEB = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx

# Incorrect (space replaces comma, parsing breaks):
Cmnd_Alias WEB = /usr/bin/systemctl restart nginx /usr/bin/systemctl reload nginx

Verify a rule without root privileges:

sudo -l -U deployer

The output lists permitted commands and their flags. An empty list means the rules did not apply — check syntax and paths. Here’s a thinking process:

  1. Analyze User Input:
  • Role: Practicing Lead DevOps writing IT notes for a Hugo blog (Mana theme).
  • Style: Short paragraphs, specific commands, tables of flags, code with language fences.
  • Constraints: No water, no “in this article we’ll explore”, no marketing, no emojis, no author signature at the end.
  • Allowed: GitHub admonitions: > [!NOTE], > [!TIP], > [!WARNING].
  • Fact Constraint: Don’t make up non-existent flags, URLs, or versions. If fact is unclear, write cautiously as in operations.
  • Task: Write the English article as a parallel original, not a word-for-word translation.
  • Structure & Facts: Must match the Russian draft exactly.
  • Format: