Verify Permissions On /etc/sudoers.d Directory
Ensures the /etc/sudoers.d directory is not group/other-writable, not readable or executable by other, and carries no setuid/setgid/sticky bits, so only root controls drop-in sudo rules.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.
Why this rule matters
/etc/sudoers.d holds the drop-in sudo rules that sudo includes in addition to /etc/sudoers. A single file dropped here can grant any user full root via sudo. If the directory is writable by group or other, an unprivileged user could add their own rule and obtain root, a direct privilege escalation; if it is readable by other, the precise privilege layout is disclosed, aiding an attacker. setuid/setgid and a non-standard sticky bit indicate tampering. Only root must be able to write, and read, this directory.
What Pavois checks
Pavois reads the live mode bits of the /etc/sudoers.d directory on the target (group/other write, other read/execute, setuid/setgid/sticky), exactly what the kernel enforces, not a documented baseline. This is precisely the kind of drop-in location a file-based scanner can overlook; Pavois inspects the directory itself. The only_if guard skips the control when the directory is absent.
only_if { file('/etc/sudoers.d').exist? }
describe file('/etc/sudoers.d') do
it { should_not be_setuid }
it { should_not be_writable.by('group') }
it { should_not be_setgid }
it { should_not be_executable.by('other') }
it { should_not be_writable.by('other') }
it { should_not be_readable.by('other') }
it { should_not be_sticky }
endHow to verify it is applied
Run stat -c '%A %U %G' /etc/sudoers.d. Expected: mode drwxr-x--- (0750), or 0755 per some baselines, but 0750 root:root is preferred, owned by root root, with no write bit for group/other and no read/exec for other when set to 0750. Quick check: find /etc/sudoers.d -maxdepth 0 -perm /7027 must return nothing. Confirm sudo still parses cleanly with visudo -c.
Inspect & investigate
Permission changes are not logged by default. Watch the directory with auditd: auditctl -w /etc/sudoers.d/ -p wa -k scope, then review with grep 'key="scope"' /var/log/audit/audit.log. Actual sudo invocations are logged to /var/log/auth.log (Debian/Ubuntu) or /var/log/secure / journalctl _COMM=sudo (RHEL). Current mode and ownership: stat /etc/sudoers.d.
Remediation
No automated harden plan ships for this rule yet, so it must be applied manually: chown root:root /etc/sudoers.d && chmod 0750 /etc/sudoers.d. This removes any group/other write, strips other read/execute and clears any setuid/setgid/sticky bits. Note that individual rule files inside must themselves be 0440 root:root, or sudo ignores them.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| mode | 0750 |
|---|---|
| path | /etc/sudoers.d |
| resource | file |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Risk if left mis-set: a writable /etc/sudoers.d is a direct route to root, a non-root user drops a file granting themselves sudo. Applying the fix is safe: 0750 root:root lets sudo (running as root) read the drop-ins while denying access to everyone else. Precaution: keep ownership root:root and do not chmod individual rule files to anything but 0440, sudo/visudo refuses world-writable or wrong-mode includes and will report a parse error. Run visudo -c after any change to avoid locking yourself out of sudo.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| ANSSI BP-028 | R50 | direct | 2.0 | high |
Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.