SSH is the main way to remotely manage a Linux server. Through SSH, an administrator connects to a VPS or dedicated server, performs configuration, updates the system, checks logs, and manages services.
Because of this, SSH almost always becomes one of the first targets for automated attacks. Bots scan the internet, find an open port 22, and start trying different usernames and passwords. This type of attack is called brute force — password guessing.
Even if the password is strong, constant login attempts create unnecessary load, fill up logs, and increase the risk of server compromise. If a weak password, the standard root login, and an open SSH port are used, the server can be hacked automatically.
Usually, such an attack looks like this:
Failed password for root from 185.XX.XX.XX port 54321 ssh2
Failed password for admin from 185.XX.XX.XX port 54322 ssh2
Failed password for test from 185.XX.XX.XX port 54323 ssh2
In this article, we will look at 5 main solutions that help protect SSH from brute force attacks.
1. Use SSH Keys and Disable Password Login
The most important step is to stop using password login and switch to SSH keys. A password can be guessed, especially if it is simple or has already been compromised. An SSH key is almost impossible to brute force if the private key is stored securely.
Create an SSH key on your local computer:
ssh-keygen -t ed25519 -C “admin@example.com”
Add the public key to the server:
ssh-copy-id user@SERVER_IP
Or manually add the public key content to the file:
~/.ssh/authorized_keys
Important
Before disabling password login, make sure that SSH key login already works.
Then open the SSH configuration file:
sudo nano /etc/ssh/sshd_config
Specify:
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
Check the configuration:
sudo sshd -t
If there are no errors, reload SSH:
sudo systemctl reload ssh
or:
sudo systemctl reload sshd
The service name depends on the distribution.
Do not close your current SSH session until you test login in a new terminal tab.
2. Disable root Login
Many brute force attacks first try the root login because it exists on almost every Linux server. Therefore, it is better to disable SSH login as root and use a separate user with sudo privileges for administration.
Create a separate user:
sudo adduser adminuser
sudo usermod -aG sudo adminuser
Check login as this user:
ssh adminuser@SERVER_IP
Check sudo privileges:
sudo whoami
Expected response:
root
After that, specify the following in the SSH configuration:
PermitRootLogin no
Apply the changes:
sudo sshd -t
sudo systemctl reload ssh
This approach reduces the risk of automated access attempts because the attacker needs to know not only the key, but also the separate username.
3. Limit the Number of Login Attempts
Even if password login is disabled, it is useful to limit the number of authentication attempts. This helps terminate suspicious connections faster and reduce the load from automated attacks.
Open the SSH configuration file:
sudo nano /etc/ssh/sshd_config
Add or change the parameters:
MaxAuthTries 3
LoginGraceTime 30
What this means:
MaxAuthTries 3 — no more than 3 authentication attempts per connection
LoginGraceTime 30 — 30 seconds for a successful login
After making changes, check the configuration:
sudo sshd -t
Reload SSH:
sudo systemctl reload ssh
Recommendation
Do not set the values too low if several administrators connect to the server or automated SSH connections are used.
4. Allow SSH Only from Trusted IPs or Through a VPN
If SSH is open to the entire internet, it will be constantly scanned by bots. A safer option is to allow connections only from trusted IP addresses.
Example for UFW:
sudo ufw allow from YOUR_TRUSTED_IP to any port 22 proto tcp
sudo ufw deny 22/tcp
sudo ufw enable
Check the rules:
sudo ufw status numbered
Example logic:
Allow SSH from trusted IP
Deny SSH from all other IPs
If administrators do not have fixed IP addresses, it is better to use a VPN. In this case, SSH is not published directly to the internet and is available only from the internal VPN network.
This option is especially suitable for production servers, Proxmox infrastructure, OPNsense, internal services, databases, and corporate systems.
5. Install Fail2Ban for Automatic Blocking of Attacking IPs
Fail2Ban is one of the most popular tools for protecting SSH from brute force attacks. It analyzes logs, detects repeated failed login attempts, and temporarily blocks the attacker’s IP address through the firewall.
Install it on Debian/Ubuntu:
sudo apt update
sudo apt install fail2ban -y
Create a configuration file for SSH:
sudo nano /etc/fail2ban/jail.d/sshd.local
Example configuration:
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
What the parameters mean:
maxretry = 5 — block after 5 failed attempts
findtime = 10m — count attempts within the last 10 minutes
bantime = 1h — block the IP for 1 hour
Start Fail2Ban:
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban
Check the status:
sudo fail2ban-client status
sudo fail2ban-client status sshd
If everything works correctly, the status will show the number of blocked IP addresses.
You can also consider CrowdSec instead of Fail2Ban.
With a standard installation, CrowdSec usually adds basic Linux/SSH collections, and after installing a firewall bouncer, it can block IP addresses that trigger SSH brute force scenarios.
In other words, the CrowdSec + bouncer setup not only detects suspicious SSH attempts in logs, but also applies blocking through the firewall.
CrowdSec can also be extended to protect other services: Nginx, Apache, Traefik, Docker, or control panels.
Important: the CrowdSec engine is responsible for detection, while the bouncer is responsible for actually blocking IP addresses.
Conclusion
SSH protection against brute force attacks should not be limited to a single setting. The best result comes from combining several measures:
- SSH keys
- No password login
- No root login
- Limited login attempts
- Firewall allowlist or VPN
- Fail2Ban
For a test VPS, SSH keys, disabled password login, and Fail2Ban are often enough. For a production server, it is better to use a stricter approach: close SSH from the entire internet, allow access only from trusted IPs or through a VPN, and regularly check the protection status.
This approach significantly reduces the risk of hacking and makes the server more resistant to automated attacks.