Linux server security audit checklist

A Linux server audit checks that the system is patched, that only expected services and accounts exist, that SSH and the firewall are locked down, and that logs and backups work. Use a benchmark such as a CIS Benchmark as the reference and a scanner such as Lynis to do the first pass.

Start from a published baseline

Pick one written standard and audit against it, so each finding has a reference.

Automated tools save time on the first pass. Lynis audits the host with lynis audit system. OpenSCAP checks a system against SCAP content with its oscap command.

The checklist

The last column shows what server_audit_notify.sh covers. "Lynis" means the script runs Lynis, which reports on the area, and copies its warnings into the email.

The checklist
AreaWhat to checkCommandScript
Security updatesPending updates, automatic security updates onapt list --upgradable or dnf check-updateNo
SSHRoot login, password login, key loginsshd -TLynis
Failed loginsRepeated failures from the same addresslastb -n 20Yes
AccountsOnly root has UID 0, sudo group membersawk -F: '$3 == 0' /etc/passwdLynis
Listening servicesEvery open port has an owner and a reasonss -tulpnYes
FirewallDefault deny for incoming trafficnft list rulesetLynis
SUID filesNo unexpected set-user-ID programsfind / -xdev -perm -4000 -type fLynis
Disk spaceRoom for logs and updatesdf -hYes
LoggingLogs kept, rotated and sent off the hostjournalctl --disk-usageLynis
Audit trailauditd running with rules loadedauditctl -sLynis
TimeClock synchronized, so log times line uptimedatectlNo
BackupsRecent backup exists and a restore was testedDepends on your toolNo

Security updates

Updates close publicly known security bugs, so check them first. List what is pending with apt list --upgradable on Debian and Ubuntu or dnf check-update on Red Hat style systems.

Ubuntu applies security updates on its own through the unattended-upgrades package. The Ubuntu Server documentation says the schedule lives in /etc/apt/apt.conf.d/20auto-upgrades, the behavior in /etc/apt/apt.conf.d/50unattended-upgrades, and the logs in /var/log/unattended-upgrades.

SSH configuration

Run sshd -T as root to print the settings the SSH server uses, after all include files. Compare these lines with your policy. The defaults below come from the OpenSSH sshd_config manual; distributions can change them.

SSH configuration
SettingOpenSSH defaultCommon hardening choice
PermitRootLoginprohibit-passwordno
PasswordAuthenticationyesno, once keys work for every user
PubkeyAuthenticationyesyes
MaxAuthTries6A lower number such as 3

Then look at failed attempts. lastb shows failed logins recorded in /var/log/btmp, and journalctl -u ssh (or -u sshd on Red Hat style systems) shows the SSH server log.

Accounts and privileges

List accounts with UID 0 using awk -F: '$3 == 0' /etc/passwd; only root should appear. Check who can use sudo with getent group sudo wheel. Remove accounts for people who left, and lock service accounts that never log in.

Open ports and firewall

ss -tulpn lists every listening TCP and UDP socket and the process behind it. For each line, you should know which service it is and whether it needs to accept connections from the internet. Then confirm the firewall matches: nft list ruleset, ufw status verbose or firewall-cmd --list-all, depending on the system.

Logs and audit trail

Logs only help if they exist when you need them. Check that the journal or syslog keeps enough history with journalctl --disk-usage, that log rotation works, and that copies go to another host, since an attacker with root can edit local files.

The Linux Audit System records system calls and events from privileged programs. Its project README describes each event as recording when it happened, who did it, what it acted on, and whether it succeeded. Check that it runs with auditctl -s and list the loaded rules with auditctl -l.

Repeat the audit on a schedule

One audit shows the state on one day. Schedule the scan, keep the results, and compare runs so that new warnings stand out. The install guide shows how to run server_audit_notify.sh daily with cron or a systemd timer and keep the reports for a set number of days.