VPS & Server audit fixes

SSH & Access: fixing all 11 checks

The SSH and access audit reads sshd_config, the sudoers files and every account home to establish who can open a session on this box and how much privilege they hold once they are in.

Three conditions skip a check here: /etc/ssh/sshd_config being unreadable, which takes out six of the config checks at once, /etc/login.defs being unreadable, which takes out Password Ageing, and no root, which stops the sudoers scan behind Passwordless Sudo Rules. SSH Authorized Keys never skips, it quietly narrows to the account homes the audit user can read and appends "readable homes only" to the result, so a low key count under an unprivileged run is not the whole picture.

11
checks in this audit
4
rated high severity
2
need root or sudo
~14s
automated run time

Transcribed from the vps-security-ssh-access audit script. For what the audit covers rather than how to fix it, see the SSH & Access checklist.

Every check

Find your finding

Listed in the order the audit runs them. Take the check name from the third field of the result line and open its page.

  • SSH Root Login

    Soon

    Checks the effective sshd PermitRootLogin setting for direct root access over SSH

    HighNo root4 results
  • SSH Password Auth

    Soon

    Checks whether sshd still accepts password authentication instead of keys only

    MediumNo root3 results
  • SSH Port

    Soon

    Checks whether sshd listens on the default port 22, which attracts constant brute-force noise

    LowNo root3 results
  • SSH Idle Timeout

    Soon

    Checks the ClientAliveInterval and ClientAliveCountMax pair that drops idle SSH sessions

    LowNo root3 results
  • SSH Authorized Keys

    Soon

    Checks every account home for authorized_keys files, counting keys and flagging group- or world-writable ones

    HighNeeds root3 results
  • Extra Root Accounts

    Soon

    Checks for accounts other than root holding UID 0, using getent so LDAP-backed accounts are covered

    HighNo root2 results
  • Sudo Group Members

    Soon

    Checks who belongs to the sudo, wheel and admin groups, including primary-group membership

    MediumNo root2 results
  • Passwordless Sudo Rules

    Soon

    Checks sudoers for NOPASSWD rules, separating blanket ALL grants from command-scoped ones

    MediumNeeds root4 results
  • SSH Login Restrictions

    Soon

    Empty passwords, retry ceiling and the SSH account allow-list

    HighNo root4 results
  • SSH Crypto Algorithms

    Soon

    Key exchange, cipher and MAC algorithms offered by sshd

    MediumNo root4 results
  • Password Ageing

    Soon

    Password expiry policy in /etc/login.defs

    LowNo root3 results
Shared script behaviour

How the SSH & Access audit reads your server

Every check in this audit runs after the same preamble, and several of its results only make sense once you know what that preamble could and could not see.

How sshd settings are read. The script does not run sshd -T. It parses /etc/ssh/sshd_config and, if the file contains an Include directive, the included files first (the same first-match-wins order sshd uses). sshval <keyword> returns the first value found, case-insensitive. Every message carries the qualifier "(read from sshd_config - Include drop-ins are followed, Match blocks are not evaluated)". Consequences:

  • A setting inside a Match User/Group/Address block is ignored. Use sshd -T -C user=bob,host=x,addr=1.2.3.4 to see effective values.
  • Ubuntu's /etc/ssh/sshd_config.d/50-cloud-init.conf (PasswordAuthentication yes) is an Include and is followed, so it correctly overrides the main file.
  • Defaults assumed when nothing is set: PermitRootLogin prohibit-password, PasswordAuthentication yes, Port 22, ClientAliveInterval 0, ClientAliveCountMax 3, PermitEmptyPasswords no, MaxAuthTries 6.
Why checks skip

A SKIP is never a pass

A skipped check verified nothing at all. The most common cause is privilege: 2 of the 11 checks in this audit need root for a complete result. Before every run, each script works out which of four privilege modes it is in.

The four privilege modes an audit script can run in, and what each one means for checks that need root
ModeHow it is reachedWhat it means for your results
rootThe audit runs as UID 0.Every privileged branch runs directly. No check skips for lack of permission.
nopasssudo -n true succeeds, so the account has passwordless sudo.Privileged commands run through sudo -n.
passA sudo password was supplied in the CtrlOps audit settings and accepted.Privileged commands run through sudo -S.
noneNone of the above worked.CAN_ROOT=0. Every privileged branch returns SKIP with a "Need root" message rather than guessing.

If many checks skip with a “need root” message, run the audit as root, grant the audit account sudo (with or without NOPASSWD), or supply the sudo password in the CtrlOps audit settings.

FAQ

SSH & Access questions

Almost always an Include drop-in winning the first-match race. The audit reads the Include directory before the main sshd_config, in the same first-match-wins order sshd uses, so on Ubuntu the cloud-init drop-in at /etc/ssh/sshd_config.d/50-cloud-init.conf that sets PasswordAuthentication yes beats a line you appended to the bottom of the main file. Run sudo grep -rn passwordauthentication /etc/ssh/ to find every copy, then put your setting in a drop-in that sorts earlier, such as 10-hardening.conf.
Because the audit parses the configuration files rather than running sshd -T. That keeps the checks working without root, and Include drop-ins are followed correctly, but a setting inside a Match User, Match Group or Match Address block is invisible to it. A host that passes SSH Root Login while a Match Address block re-enables root is the classic case, so confirm the effective value with sudo sshd -T -C user=root,addr=203.0.113.1 before you trust a pass.
Keep your current session open the entire time and never close it until a new one works. Write the change to a drop-in under /etc/ssh/sshd_config.d rather than editing the main file, validate with sudo sshd -t, reload with sudo systemctl reload ssh, then open a second terminal and log in before you touch anything else. The two fixes that lock people out most often are PasswordAuthentication no on a host where no key is installed yet, and an AllowUsers or AllowGroups line that omits your own account.
Audit your fleet

Run all 11 SSH & Access checks, in one click

CtrlOps runs this audit over your existing SSH connection - no agents, no scripts to manage. $7/user/month after a 1 month free trial - no credit card required.

Start instantly· No credit card· No sneaky autorenewals