LFCS 42 ๐ง Sudo Configuration โ visudo and sudoers
The previous chapter established that sudo delegates privilege escalation through rules in /etc/sudoers. This chapter goes deeper into the two tools that make that configuration safe and maintainable: visudo and the sudoers grammar itself. The LFCS exam expects you to configure sudo access and command aliases, and to restrict privilege escalation via sudo . Both objectives converge on the same file and the same editor.
The /etc/sudoers file is parsed by a strict grammar. A misplaced character can cause sudo to refuse every request, locking you out of administrative access entirely. This is not hypotheticalโit is the single most common way administrators brick a system. visudo exists to prevent this: it locks the file, opens it in an editor, parses the syntax on save, and refuses to write invalid configuration. It also checks file permissions and ownership, which sudo itself enforces at runtime.
The sudoers grammar has four components per rule: who, where, as whom, and what. Beyond the basic rule, the file supports aliases for users, hosts, runas users, and commands. Aliases reduce repetition and make policies readable. The drop-in directory /etc/sudoers.d/ lets you keep custom rules separate from the main file, so OS upgrades do not overwrite them. This chapter covers all of it: visudo usage, the grammar, aliases, and the drop-in directory.
Key point: visudo is the only safe way to edit /etc/sudoers and its drop-in files because it validates syntax before saving; the grammar follows WHO WHERE=(AS_WHOM) WHAT, and aliases (User_Alias, Cmnd_Alias, Host_Alias, Runas_Alias) reduce repetition.
Why visudo and sudoers grammar matter
The lockout problem. /etc/sudoers is parsed at every sudo invocation. If the file contains a syntax error, sudo refuses to run any command for any user. If you edited the file without visudo and introduced an error, you cannot fix it with sudo because sudo is broken. Recovery requires booting into single-user mode or using pkexec. visudo prevents this by parsing the file before saving and offering to re-edit on error .
The permission enforcement problem. sudo checks that /etc/sudoers is owned by root:root and mode 0440. If the permissions are wrong, sudo refuses to use the file, regardless of its contents. A common cause is editing with a tool that changes ownership or permissions. visudo sets the correct permissions automatically. Drop-in files in /etc/sudoers.d/ must also be 0440 and owned by root; if they are not, they are silently ignored .
The filename restriction. Files in /etc/sudoers.d/ must not contain dots (.) or end with a tilde (~). A file named admin.conf is ignored; admin works. Backup files created by editors (admin~) are also ignored, which is intentionalโit prevents a broken backup from breaking sudo. The filename should use only alphanumeric characters and hyphens .
The alias problem. Without aliases, a policy that grants a group access to ten commands repeats the group name ten times. A typo in one repetition creates an inconsistent policy that is hard to audit. Aliases (Cmnd_Alias, User_Alias) define the set once and reference it by name . They also make the policy self-documenting: %webadmins ALL=(root) SERVICES is clearer than a list of five systemctl paths.
The drop-in maintenance problem. The main /etc/sudoers file is owned by the package manager. If you add custom rules there, an OS upgrade may overwrite them. The drop-in directory exists so that custom rules survive upgrades. The main file includes the directory via @includedir /etc/sudoers.d (or #includedir on some distributions) . Each drop-in file is independent: you can add or remove a role by adding or removing a file.
a. Using visudo correctly
visudo opens /etc/sudoers in the editor specified by the EDITOR environment variable (or vi if unset). It locks the file to prevent concurrent edits, parses the syntax on save, and writes only if the syntax is valid .
sudo visudo
To edit a drop-in file, use the -f flag:
sudo visudo -f /etc/sudoers.d/webadmins
This opens the specified file with the same syntax validation. If the file does not exist, visudo creates it. It also sets the correct permissions (0440) on save .
To check a file without editing it, use -c:
sudo visudo -c -f /etc/sudoers.d/webadmins
This parses the file and reports syntax errors without opening an editor. It is useful for validating files in scripts or CI pipelines .
The -q flag suppresses the “parsed OK” message, which is useful in scripts where you only care about the exit code. The exit code is 0 on success, 1 on syntax error.
If visudo detects an error, it prints the line number and the error, then asks whether to re-edit, discard changes, or quit. Choosing re-edit returns to the editor with the file unchanged. Choosing discard exits without writing. This is the safety net: an invalid file is never written to disk.
b. The sudoers grammar and aliases
Every sudoers rule has four parts:
WHO WHERE=(AS_WHOM) WHAT
- WHO: a username, a
%group, a#uid, or aUser_Alias. - WHERE: a hostname, an IP address, or
ALL. In practice,ALLis almost always used. - AS_WHOM: a parenthesized list of users the command can run as.
(ALL)or(root). If omitted, it defaults toroot. - WHAT: an absolute command path, a directory ending in
/, or aCmnd_Alias.
A complete rule for a single user:
alice ALL=(ALL:ALL) ALL
The :ALL after the user list specifies the group the command can run as. (ALL:ALL) means any user and any group. (root) is shorthand for (root:root).
Aliases are defined before the rules that use them. User_Alias groups users:
User_Alias WEBADMINS = alice, bob, %webteam
Cmnd_Alias groups commands. Commands must be absolute paths:
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl restart *, /usr/bin/systemctl status *
Host_Alias groups hosts (rarely used in practice):
Host_Alias WEBSERVERS = web1, web2, 192.168.1.10
Runas_Alias groups target users:
Runas_Alias DBUSERS = postgres, mysql
Once defined, aliases are used in rules:
WEBADMINS ALL=(root) SERVICES
Aliases must begin with an uppercase letter and contain only uppercase letters, digits, and underscores . They are evaluated in order; if a command matches multiple aliases with different permissions, the last matching rule wins.
The NOPASSWD: tag disables the password prompt for the commands that follow it:
deploy ALL=(root) NOPASSWD: /opt/deploy/run.sh
This is common for automation but reduces auditability. The PASSWD: tag restores the prompt for specific commands within a broader NOPASSWD rule .
c. The /etc/sudoers.d/ drop-in directory
The main /etc/sudoers file includes the drop-in directory with a line like:
@includedir /etc/sudoers.d
On some distributions it is #includedir. The @ form is the modern syntax; the # form is historical and still works . If this line is missing or commented out, drop-in files are ignored. Some minimal container images ship without it, which is why a drop-in rule can silently fail .
Files in /etc/sudoers.d/ follow the same grammar as the main file. A file for a web administration group:
%webadmins ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
The permissions must be 0440 and ownership root:root. visudo -f sets these automatically. If you create the file with a normal editor, you must set them manually:
sudo chown root:root /etc/sudoers.d/webadmins
sudo chmod 0440 /etc/sudoers.d/webadmins
The filename must not contain a dot or end with a tilde . A file named webadmins.conf is ignored; webadmins is used. This is a common source of confusion: the file exists, the syntax is correct, but sudo does not see it because of the filename.
Files are parsed in lexicographical order. Numeric prefixes (10-admins, 20-developers) control precedence. If two files define rules for the same user, the later file’s rules are applied in addition to the earlier ones; they do not override. To revoke a permission, you must remove it from the file that granted it or use a negation rule in a later file.
Complete Example Session
The following session creates a command alias, grants a group access to specific services, and validates the configuration with visudo.
# ============================================
# PART 1: OPEN A NEW DROP-IN FILE
# ============================================
sudo visudo -f /etc/sudoers.d/10-webadmins
# ============================================
# PART 2: DEFINE ALIASES AND RULES
# ============================================
# Add the following content:
# Cmnd_Alias WEB_SERVICES = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx
# %webadmins ALL=(root) WEB_SERVICES
# ============================================
# PART 3: SAVE AND VERIFY PERMISSIONS
# ============================================
ls -l /etc/sudoers.d/10-webadmins
# Expected: -r--r----- root root
# ============================================
# PART 4: VALIDATE SYNTAX
# ============================================
sudo visudo -c -f /etc/sudoers.d/10-webadmins
# Output: parsed OK
# ============================================
# PART 5: CREATE GROUP AND ADD USER
# ============================================
sudo groupadd webadmins
sudo usermod -aG webadmins bob
# ============================================
# PART 6: TEST AS BOB (after re-login)
# ============================================
su - bob
sudo systemctl status nginx
# Allowed: matches WEB_SERVICES
sudo systemctl stop nginx
# Denied: command not in alias
# Output: Sorry, user bob is not allowed to execute '/usr/bin/systemctl stop nginx' as root
# ============================================
# PART 7: ADD NOPASSWD FOR A DEPLOY SCRIPT
# ============================================
sudo visudo -f /etc/sudoers.d/20-deploy
# Content:
# deploy ALL=(root) NOPASSWD: /opt/deploy/run.sh
# ============================================
# PART 8: VERIFY THE DROP-IN IS INCLUDED
# ============================================
grep -E '^[@#]includedir' /etc/sudoers
# Expected: @includedir /etc/sudoers.d
# ============================================
# PART 9: LIST BOB'S PRIVILEGES
# ============================================
sudo -l -U bob
# Shows the WEB_SERVICES rule and any group-based rules
# ============================================
# PART 10: CLEAN UP
# ============================================
sudo rm /etc/sudoers.d/10-webadmins
sudo rm /etc/sudoers.d/20-deploy
sudo groupdel webadmins
The ten parts cover opening a drop-in file with visudo, defining an alias and a rule, verifying permissions, validating syntax, creating the group and adding a user, testing allowed and denied commands, adding a NOPASSWD rule, verifying the includedir directive, listing privileges, and cleanup. What the session demonstrates is that the drop-in directory and aliases make sudo policy modular and readable, and that visudo is the gatekeeper that prevents lockout.
Quick Reference
visudo Options
| Option | Purpose |
|---|---|
visudo | Edit main /etc/sudoers |
visudo -f file | Edit a drop-in file |
visudo -c | Check syntax only |
visudo -c -f file | Check a specific file |
visudo -q | Quiet mode (suppress “parsed OK”) |
Sudoers Grammar
| Component | Meaning | Example |
|---|---|---|
| WHO | User, %group, #uid, alias | alice, %wheel |
| WHERE | Host or ALL | ALL |
| AS_WHOM | Run-as user/group | (ALL:ALL), (root) |
| WHAT | Command path or alias | /bin/ls, SERVICES |
Alias Types
| Alias | Purpose |
|---|---|
User_Alias | Group users |
Cmnd_Alias | Group commands |
Host_Alias | Group hosts |
Runas_Alias | Group target users |
Drop-in File Rules
| Requirement | Value |
|---|---|
| Directory | /etc/sudoers.d/ |
| Ownership | root:root |
| Permissions | 0440 |
| Filename | No dots, no trailing tilde |
| Included by | @includedir /etc/sudoers.d |
Best Practices
โ Do This:
sudo visudo -f /etc/sudoers.d/10-webadmins # โ
syntax-checked edit
sudo visudo -c -f /etc/sudoers.d/10-webadmins # โ
validate before relying
Cmnd_Alias SERVICES = /usr/bin/systemctl restart * # โ
aliases for readability
chmod 0440 /etc/sudoers.d/rule # โ
correct permissions
โ Don’t Do This:
nano /etc/sudoers # โ no syntax check
chmod 0644 /etc/sudoers.d/rule # โ sudo ignores it
# file named webadmins.conf # โ dot causes ignore
# %webadmins ALL=(root) /usr/bin/systemctl # โ wildcard without * is literal
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Drop-in silently ignored | Wrong permissions (0644) | chmod 0440 |
| Drop-in ignored | Filename contains a dot | Rename without dot |
| Drop-in ignored | includedir line missing | Add @includedir /etc/sudoers.d |
| Syntax error locks out sudo | Edited without visudo | Use single-user mode or pkexec |
| Command denied despite rule | Path mismatch | Use absolute path in rule |
| Alias not recognized | Lowercase or contains invalid char | Uppercase, digits, underscores only |
Real-World Examples
1. Edit main sudoers safely
sudo visudo
2. Create a drop-in file
sudo visudo -f /etc/sudoers.d/10-admins
3. Command alias for services
Cmnd_Alias SERVICES = /usr/bin/systemctl restart *, /usr/bin/systemctl status *
4. Group rule using alias
%ops ALL=(root) SERVICES
5. User alias
User_Alias ADMINS = alice, bob
ADMINS ALL=(ALL) ALL
6. NOPASSWD for a script
deploy ALL=(root) NOPASSWD: /opt/deploy/run.sh
7. Validate syntax
sudo visudo -c -f /etc/sudoers.d/10-admins
8. Check includedir
grep includedir /etc/sudoers
9. List user privileges
sudo -l -U username
10. Remove a drop-in rule
sudo rm /etc/sudoers.d/10-admins
Visual
visudo Safety Net
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ sudo visudo โ
โ โ โ
โ โผ โ
โ Lock file, open editor โ
โ โ โ
โ โผ โ
โ User edits /etc/sudoers โ
โ โ โ
โ โผ โ
โ Save โ
โ โ โ
โ โผ โ
โ Parse syntax โ
โ โ โ
โ โโโโโโดโโโโโ โ
โ โ โ โ
โ valid invalid โ
โ โ โ โ
โ โผ โผ โ
โ Write Report error, โ
โ file offer re-edit โ
โ or discard โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Sudoers Grammar
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ %webadmins ALL=(root) /usr/bin/systemctl โ
โ โโโโโโโโโโ โโโ โโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ WHO WHERE AS_WHOM WHAT โ
โ โ
โ WHO: %webadmins (group) โ
โ WHERE: ALL (any host) โ
โ AS_WHOM: (root) (run as root) โ
โ WHAT: /usr/bin/systemctl (exact path) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Alias Expansion
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Cmnd_Alias SERVICES = /usr/bin/systemctl โ
โ restart *, status * โ
โ โ โ
โ โผ โ
โ %ops ALL=(root) SERVICES โ
โ โ โ
โ โผ โ
โ Equivalent to: โ
โ %ops ALL=(root) /usr/bin/systemctl restart *โ
โ %ops ALL=(root) /usr/bin/systemctl status * โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Drop-in Directory
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ /etc/sudoers โ
โ @includedir /etc/sudoers.d โ
โ โ โ
โ โผ โ
โ /etc/sudoers.d/ โ
โ โโโ 10-admins root:root 0440 โ
โ โโโ 20-webadmins root:root 0440 โ
โ โโโ 30-deploy root:root 0440 โ
โ โ
โ Ignored: files with dots, wrong perms โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Safe editor | visudo |
| Edit drop-in | visudo -f /etc/sudoers.d/file |
| Syntax check | visudo -c -f file |
| Grammar | WHO WHERE=(AS_WHOM) WHAT |
| Full access | user ALL=(ALL:ALL) ALL |
| Alias types | User_Alias, Cmnd_Alias, Host_Alias, Runas_Alias |
| Drop-in dir | /etc/sudoers.d/ |
| Permissions | root:root, 0440 |
| Filename restriction | No dots, no trailing tilde |
| Inclusion directive | @includedir /etc/sudoers.d |
Key takeaways:
visudois not optional. It validates syntax before saving and prevents the lockout that a malformed sudoers file causes .visudo -fedits drop-in files. It sets the correct permissions and performs the same syntax check .- The grammar is
WHO WHERE=(AS_WHOM) WHAT. TheAS_WHOMpart is parenthesized and defaults torootif omitted . - Aliases reduce repetition.
Cmnd_Aliasgroups commands,User_Aliasgroups users, and rules reference them by name . - Drop-in files must be
0440,root:root, and dot-free. A file with a dot in its name is silently ignored . - The
includedirdirective must be present. Without it, the drop-in directory is never read . NOPASSWD:disables the prompt. Use it sparingly, and scope it to specific commands rather thanALL.
Remember: The sudoers configuration is powerful and fragile. visudo exists because the file’s grammar is unforgiving and the consequences of a mistake are total: no sudo access at all. Use visudo for every edit, visudo -c for validation, and the drop-in directory for all custom rules. Define aliases for readability, restrict commands to absolute paths, and set NOPASSWD only where automation requires it. For the LFCS exam, know how to create a drop-in file, define a Cmnd_Alias, and grant a group access to a specific set of commandsโand know why visudo is the first and last tool you should reach for.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!