Use this as a baseline review for a new server, and repeat it every few months on existing ones.
Access
- SSH logins use keys; password login is disabled.
- Direct root login over SSH is disabled.
- Each administrator has a personal account; no shared logins.
- Accounts of people who left have been removed, along with their SSH keys.
- Brute-force protection (such as fail2ban) is running.
Updates
- The operating system is a supported release that still receives security updates.
- Security updates are applied automatically or on a fixed schedule.
- Applications installed outside the package manager (CMS, frameworks) are updated too.
Network
- A firewall allows only the ports in use, by default deny.
- Databases, caches and admin panels are not reachable from the internet; they listen on localhost or a private network.
- Management ports are limited to known IP addresses where possible.
Services
- Unused services and packages have been removed.
- Web and database services run as unprivileged users.
- File permissions do not allow the web server to write to code directories unless needed.
- TLS is enabled for every public service, with old protocols (TLS 1.0 and 1.1) turned off.
Logging and monitoring
- System and application logs are kept and rotated.
- Someone is alerted when disk, memory or CPU run high, or when the server stops responding.
- Login attempts and sudo use are logged.
Backups and recovery
- Backups run automatically and a copy is stored off the server.
- A restore has been tested recently.
- There is a written note of how the server is built, so it can be rebuilt.
Hardening is not a one-time task. Most compromises use a known weakness that was fixed months earlier in an update nobody installed.