Skip to main content
Bots start brute-forcing a server with password login within the first few minutes. Go through the checklist in order, the commands are for Ubuntu/Debian as root.

Keys and firewall

  • Key-based SSH login – set up a key and disable password login, then brute-forcing becomes pointless: SSH keys.
  • Firewall – close all incoming ports except the ones you need: Firewall.

Updates

  1. Fresh packages – they fix known vulnerabilities:
  2. Auto-updates – security updates install themselves:

fail2ban

fail2ban watches the logs and temporarily bans an IP that brute-forces the SSH password.
  1. Install:
  2. Settings – in jail.local, updates don’t overwrite it:
    Add:
    • maxretry – how many failed attempts are allowed.
    • findtime – the window in seconds over which attempts are counted: 600 = 10 minutes.
    • bantime – how many seconds to ban for: 3600 = 1 hour.
    • Debian 12 – fail2ban does not start without /var/log/auth.log: add the line backend = systemd to the section.
  3. Start and check – the second command shows how many addresses are banned right now:

User with sudo

Under root, any mistake or breach gives full control of the server at once. Create a regular user with the right to use sudo:
From now on log in as that user, and run commands that need privileges through sudo. Password login already off – copy the root key to the new user:
Don’t close the root session until you check in a separate window that you can log in as the new user and run sudo. Otherwise you risk losing administrative access.

SSH port

Optional. Moving SSH off port 22 cuts out the bulk of blind brute-forcing: it’s not protection, but there is less noise in the logs. Before experimenting with access, make a backup.
  1. Firewall – if ufw is enabled, open the new port first, otherwise you lock yourself out: ufw allow 2222/tcp.
  2. SSH – in /etc/ssh/sshd_config set, for example, Port 2222 and restart: systemctl restart ssh. On Ubuntu 24.04 and newer SSH listens through ssh.socket, run systemctl daemon-reload and systemctl restart ssh.socket there instead.
  3. fail2ban – add the new port, otherwise it quietly stops protecting SSH. In /etc/fail2ban/jail.local, in the [sshd] section, add or replace the port line:
    Restart fail2ban:
Next: Backups, Firewall.