# Sudoers: NOPASSWD Without Holes

LLMS index: [llms.txt](/en/llms.txt)

---

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.

```bash
# 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.

```sudoers
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.

```sudoers
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:

```bash
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:

```sudoers
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: ALL` | Full root without password | List specific commands via `Cmnd_Alias` |
| `user ALL=NOPASSWD: /bin/bash` | Opens root shell | Never give interpreters or `su` |
| `user ALL=(ALL) ALL, NOPASSWD: ALL` | `NOPASSWD` spreads to everything due to order | `NOPASSWD:` before the command list, not after |
| Editing `/etc/sudoers` via `echo` or `cp` | No syntax validation | Only `visudo` or `visudo -f` |
| Absence of `#includedir /etc/sudoers.d` | Manual file overwritten on update | Check include, place custom rules in `/etc/sudoers.d/` |

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

```sudoers
# 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:

```bash
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:**
