← All rules
SOCLE-CLD-FSP-157// File permissionsmediumpersistent config

Verify Permissions on SSH Server config file

Ensures /etc/ssh/sshd_config is owned by root with no read/write/execute for group or other, protecting the SSH daemon's master policy from tampering and disclosure.

Checked against the content of a persistent configuration file, the source of truth that survives reboots.

A pass proves? running now✓ on disk✓ survives rebootthe qualified verdict →
Debian 12CIS 1.1.0Debian 13CIS 1.0.0FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0Ubuntu 22.04CIS 3.0.0Ubuntu 24.04CIS 1.0.0Ubuntu 26.04
One check, maps to 4 standards

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/ssh/sshd_config is the master configuration of the SSH daemon and enables or disables security-critical features (root login, password vs. key auth, ciphers, allowed users). If it is writable by group or other, a non-privileged user could alter it to weaken remote access or plant a backdoor that takes effect on the next reload; if readable by group/other, the access policy is disclosed to anyone on the host. The file must be owned by root with no read/write/execute for group or other and no special bits, so only the administrator controls the SSH server policy.

What Pavois checks

Pavois reads the effective inode mode of /etc/ssh/sshd_config and asserts no read/write/execute for group or other and no setuid/setgid/sticky bits. Guarded by only_if { file('/etc/ssh/sshd_config').exist? }. Note: this control covers the permissions of the file; the effective SSH policy itself (which can be overridden by Included drop-ins) is what sshd -T reports, Pavois's service controls audit that resolved state, while this rule locks down the file that seeds it.

only_if { file('/etc/ssh/sshd_config').exist? }
describe file('/etc/ssh/sshd_config') do
  it { should_not be_executable.by('owner') }
  it { should_not be_setuid }
  it { should_not be_executable.by('group') }
  it { should_not be_writable.by('group') }
  it { should_not be_readable.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 }
end

How to verify it is applied

Run stat -c '%a %U %G' /etc/ssh/sshd_config. The expected output is 600 root root (or stricter): no read, write or execute for group or other.

Inspect & investigate

stat /etc/ssh/sshd_config shows the current mode; sshd -T shows the effective policy it produces. SSH service and auth events are in journalctl -u ssh / /var/log/auth.log (Debian/Ubuntu) or journalctl -u sshd / /var/log/secure (RHEL family). File modifications appear in /var/log/audit/audit.log if watched.

Remediation

No automated harden plan is defined for this rule yet, so apply it manually: chown root:root /etc/ssh/sshd_config then chmod 0600 /etc/ssh/sshd_config.

Pavois applies this with its own harden engine, the plan below, not a shell script:

grouproot
mode0600
ownerroot
path/etc/ssh/sshd_config
resourcefile
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

A group- or world-writable sshd_config lets an unprivileged user re-enable root login, switch on password auth, or whitelist a backdoor account on the next reload, a critical remote-access compromise; a readable one leaks the access policy. Precautions: tightening to 0600 root:root does not interrupt active SSH sessions and matches the distro default, so it is low-risk. Run sshd -t to validate syntax before any reload to avoid bringing the daemon down and locking yourself out, and keep at least one authenticated session open during changes.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R50direct2.0high
CIS2.2.6, 5.1.1, 5.1.2directper OS, see the benchmark tablehigh
NISTAC-17(a), AC-6(1), CM-6(a)supporting800-53 Rev 5 · 800-171 Rev 2 (pinned)medium
PCI DSS2.2.6supporting4.0.1medium

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.

Sources & references