SSH Hardening: How to Secure Your Server Against Brute Force Attacks
If your server is publicly accessible, it's being attacked right now. SSH brute force is constant and automated.
Here's how to lock it down.
Check If You're Being Attacked
# See failed SSH login attempts
sudo journalctl -u sshd | grep "Failed password" | tail -20
# Or
sudo grep "Failed password" /var/log/auth.log | tail -20
# Count failed attempts by IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
You'll probably see hundreds or thousands of failed attempts from random IPs. This is normal. Let's stop them from succeeding.
Step 1: Disable Password Authentication
sudo nano /etc/ssh/sshd_config
Set these:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
sudo systemctl restart sshd
Before doing this, make sure your SSH key is added to ~/.ssh/authorized_keys on the server.
Step 2: Install and Configure Fail2ban
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 86400 # Ban for 24 hours
findtime = 3600 # In 1 hour window
maxretry = 3 # After 3 failures
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 604800 # Ban SSH attackers for 7 days
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check banned IPs
sudo fail2ban-client status sshd
Step 3: Change the Default SSH Port (Optional but Effective)
This doesn't stop determined attackers but eliminates 95% of automated scans:
sudo nano /etc/ssh/sshd_config
Port 2222 # Or any port above 1024
# Update firewall before restarting SSH
sudo ufw allow 2222/tcp
sudo ufw delete allow ssh # Remove default port
sudo systemctl restart sshd
Connect with: ssh -p 2222 user@your-server
Step 4: Use SSH Config File for Easy Access
# On your LOCAL machine
nano ~/.ssh/config
Host myserver
HostName your-server-ip
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
Now connect with just: ssh myserver
Step 5: Set Up an SSH Bastion Host (Advanced)
For production infrastructure with multiple servers, use a bastion host — a single hardened entry point:
Internet → Bastion host (public IP) → Internal servers (private IPs only)
# SSH through bastion to internal server
ssh -J user@bastion-ip user@internal-server-ip
# Or in ~/.ssh/config
Host internal-server
HostName 10.0.0.5
User deploy
ProxyJump bastion-host
Quick Hardening Checklist
# 1. Verify key-based auth works (test before disabling password auth!)
ssh -i ~/.ssh/your_key user@server
# 2. Disable password auth
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 3. Disable root login
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 4. Restart SSH
sudo systemctl restart sshd
# 5. Install fail2ban
sudo apt install fail2ban -y && sudo systemctl enable fail2ban
# 6. Verify fail2ban is working
sudo fail2ban-client status
I built ARIA to solve exactly this.
Try it free at step2dev.com — no credit card needed.
Top comments (0)