Tools: Latest: SSH Hardening: How to Secure Your Server Against Brute Force Attacks
SSH Hardening: How to Secure Your Server Against Brute Force Attacks
Check If You're Being Attacked
Step 1: Disable Password Authentication
Step 2: Install and Configure Fail2ban
Step 3: Change the Default SSH Port (Optional but Effective)
Step 4: Use SSH Config File for Easy Access
Step 5: Set Up an SSH Bastion Host (Advanced)
Quick Hardening Checklist 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. You'll probably see hundreds or thousands of failed attempts from random IPs. This is normal. Let's stop them from succeeding. Before doing this, make sure your SSH key is added to ~/.ssh/authorized_keys on the server. This doesn't stop determined attackers but eliminates 95% of automated scans: Connect with: ssh -p 2222 user@your-server Now connect with just: ssh myserver For production infrastructure with multiple servers, use a bastion host — a single hardened entry point: I built ARIA to solve exactly this.
Try it free at step2dev.com — no credit card needed. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse
# See failed SSH login attempts
-weight: 600;">sudo journalctl -u sshd | grep "Failed password" | tail -20 # Or
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | tail -20 # Count failed attempts by IP
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# See failed SSH login attempts
-weight: 600;">sudo journalctl -u sshd | grep "Failed password" | tail -20 # Or
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | tail -20 # Count failed attempts by IP
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# See failed SSH login attempts
-weight: 600;">sudo journalctl -u sshd | grep "Failed password" | tail -20 # Or
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | tail -20 # Count failed attempts by IP
-weight: 600;">sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
-weight: 600;">sudo nano /etc/ssh/sshd_config
-weight: 600;">sudo nano /etc/ssh/sshd_config
-weight: 600;">sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
~/.ssh/authorized_keys
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y
-weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
-weight: 600;">sudo nano /etc/fail2ban/jail.local
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y
-weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
-weight: 600;">sudo nano /etc/fail2ban/jail.local
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y
-weight: 600;">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
-weight: 600;">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
[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
[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
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban # Check banned IPs
-weight: 600;">sudo fail2ban-client -weight: 500;">status sshd
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban # Check banned IPs
-weight: 600;">sudo fail2ban-client -weight: 500;">status sshd
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start fail2ban # Check banned IPs
-weight: 600;">sudo fail2ban-client -weight: 500;">status sshd
-weight: 600;">sudo nano /etc/ssh/sshd_config
-weight: 600;">sudo nano /etc/ssh/sshd_config
-weight: 600;">sudo nano /etc/ssh/sshd_config
Port 2222 # Or any port above 1024
Port 2222 # Or any port above 1024
Port 2222 # Or any port above 1024
# Update firewall before restarting SSH
-weight: 600;">sudo ufw allow 2222/tcp
-weight: 600;">sudo ufw delete allow ssh # Remove default port
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
# Update firewall before restarting SSH
-weight: 600;">sudo ufw allow 2222/tcp
-weight: 600;">sudo ufw delete allow ssh # Remove default port
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
# Update firewall before restarting SSH
-weight: 600;">sudo ufw allow 2222/tcp
-weight: 600;">sudo ufw delete allow ssh # Remove default port
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd
ssh -p 2222 user@your-server
# On your LOCAL machine
nano ~/.ssh/config
# On your LOCAL machine
nano ~/.ssh/config
# On your LOCAL machine
nano ~/.ssh/config
Host myserver HostName your-server-ip User deploy Port 2222 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60
Host myserver HostName your-server-ip User deploy Port 2222 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60
Host myserver HostName your-server-ip User deploy Port 2222 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60
ssh myserver
Internet → Bastion host (public IP) → Internal servers (private IPs only)
Internet → Bastion host (public IP) → Internal servers (private IPs only)
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
# 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
# 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
# 1. Verify key-based auth works (test before disabling password auth!)
ssh -i ~/.ssh/your_key user@server # 2. Disable password auth
-weight: 600;">sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config # 3. Disable root login
-weight: 600;">sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config # 4. Restart SSH
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd # 5. Install fail2ban
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y && -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban # 6. Verify fail2ban is working
-weight: 600;">sudo fail2ban-client -weight: 500;">status
# 1. Verify key-based auth works (test before disabling password auth!)
ssh -i ~/.ssh/your_key user@server # 2. Disable password auth
-weight: 600;">sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config # 3. Disable root login
-weight: 600;">sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config # 4. Restart SSH
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd # 5. Install fail2ban
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y && -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban # 6. Verify fail2ban is working
-weight: 600;">sudo fail2ban-client -weight: 500;">status
# 1. Verify key-based auth works (test before disabling password auth!)
ssh -i ~/.ssh/your_key user@server # 2. Disable password auth
-weight: 600;">sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config # 3. Disable root login
-weight: 600;">sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config # 4. Restart SSH
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">restart sshd # 5. Install fail2ban
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">install fail2ban -y && -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable fail2ban # 6. Verify fail2ban is working
-weight: 600;">sudo fail2ban-client -weight: 500;">status