Tools: Latest: SSH Hardening: How to Secure Your Server Against Brute Force Attacks

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

Command

Copy

# 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