Server security checklist

3 min read07 November 2026

Securing a server means applying a series of simple measures in the right order, then verifying each one. This checklist targets a Debian 13 VPS with root access. Before any SSH or firewall change, keep a session open and a backup: a mistake can cut your access.

Before you start

  • Back up data and note the current state of services.
  • Open a second SSH session and keep it active during changes.
  • Know how to get back in: the VPS panel's noVNC console, resettable root password.
  • Make small changes, one service at a time.

Priority 1: access and updates

Bash
sudo apt update && sudo apt full-upgrade
sudo systemctl reboot

Reboot if the kernel or C library was updated. Create an unprivileged user and grant sudo:

Bash
sudo adduser user
sudo usermod -aG sudo user

Test that login in a new session before disabling root. Then install your public key, confirm it works, and set PasswordAuthentication no and PermitRootLogin no in /etc/ssh/sshd_config. Validate with sudo sshd -t before reloading the service.

Priority 2: network exposure

List what is listening:

Bash
sudo ss -tulpn

Close unused services. Enable a default-deny firewall, allowing SSH before turning it on:

Bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbose

If Docker is installed, it publishes ports around UFW: bind containers to 127.0.0.1 when they are not public, and check with docker ps.

Install Fail2ban for SSH and check the jail:

Bash
sudo apt install fail2ban
sudo fail2ban-client status sshd

Priority 3: data and accounts

  • Databases listen on 127.0.0.1; each application has its own user with minimal rights on its database.
  • No chmod 777: 755 for directories, 644 for files, 600 for a .env file.
  • No secrets in Git. Tokens go in environment variables or a secrets file readable by the service only.
  • The TLS certificate is valid and renewal is tested: sudo certbot renew --dry-run.
  • A backup exists off the server and a restore has been tried.

Priority 4: monitoring and documentation

  • journalctl -p err -b for errors since boot.
  • HTTP or TCP monitoring with alerts, to catch outages before users do.
  • unattended-upgrades for security fixes, with checks for required reboots.
  • timedatectl for reliable log timestamps.
Item Check Expected
SSH sudo sshd -T | grep -E "permitrootlogin|passwordauthentication" no / no
Firewall ufw status verbose active, only useful ports
Listening ss -tulpn no unexpected port
Updates apt list --upgradable no pending security update
Backup tested restore documented and recent

Record changes, where secrets live and how to roll back. A checklist applied once is not enough: rerun it after every new service and regularly.

Advertisement

Was this article helpful?

Read next