Protect SSH with Fail2ban
A VPS exposed to the Internet receives automated SSH login attempts within minutes. Fail2ban reads authentication logs and temporarily bans addresses that fail too often. It is not a replacement for SSH keys or for disabling root login, but it cuts noise sharply and slows password guessing.
Install the service
On Debian 13 the package is in the official repositories:
sudo apt update
sudo apt install fail2ban
sudo systemctl status fail2banThe service starts and is enabled at boot. Debian ships /etc/fail2ban/jail.conf, but that file is replaced when the package is upgraded. Do not edit it: create a local file that is merged on top.
Configure the sshd jail
Create /etc/fail2ban/jail.local:
[sshd]
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 ::1backend = systemdreads the systemd journal, which matches Debian 13 whereauth.logis not guaranteed.maxretryandfindtimeset the threshold: five failures within ten minutes.bantimeis the ban duration. One hour discourages an attacker without locking out a legitimate user who mistyped a password.ignoreiplists addresses that are never banned. Add your admin address if it is static, never an overly broad prefix.
Reload and check:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshdThe output shows how many failures are tracked and which addresses are banned.
Manage bans
sudo fail2ban-client set sshd unbanip ADDRESS_IP
sudo journalctl -u fail2ban -n 50 --no-pagerTo test safely, generate a few failures from a machine you control, then unban that address. Do not use a third-party service: testing stays on your own infrastructure.
Persistent bans can be enabled with bantime.increment = true in the [DEFAULT] section, but start simple. A long ban on a shared address can affect legitimate users.
Avoid locking yourself out
- Keep an SSH session open during any change, and know how to open the noVNC console from
https://dash.neoheberg.fr. - Prefer key authentication: Fail2ban only blocks visible failures, not a stolen key.
- Make sure
ignoreipcontains127.0.0.1/8and::1, otherwise a local script can ban itself. - After changing the SSH configuration, run
sudo sshd -tbefore reloading.
Verify
sudo fail2ban-client status
sudo fail2ban-client get sshd bantime
sudo systemctl is-enabled fail2banstatus must list the active sshd jail. After a day, journalctl -u fail2ban shows real bans: that is the proof filtering works. If nothing appears, check that the jail name matches the service actually in use and that the journal contains failures.
Advertisement
Was this article helpful?
Read next
- Configure the UFW firewallDefault policy, allowing SSH, HTTP and HTTPS, IPv6 and the Docker caveat.
- Change the SSH port safelyMove SSH to another port by opening the firewall first and testing from a second session.
- Set up SSH keysssh-keygen ed25519, ssh-copy-id, permissions and disabling passwords without locking yourself out.