SSH Brute-Force Attack Detection
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://ipfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://ipfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://ipfyi.com/entity//)
Use the native HTML custom element.
Your server is receiving thousands of failed SSH login attempts per hour from one or many external IP addresses. Automated bots are systematically trying common usernames and passwords against your SSH daemon. Left unchecked, a successful credential guess gives the attacker full shell access.
Symptoms
- ⚠ Thousands of 'Failed password' or 'Invalid user' entries in /var/log/auth.log
- ⚠ High CPU or I/O load on the authentication subsystem (PAM, sshd)
- ⚠ Slow legitimate SSH logins due to connection queue saturation
- ⚠ Repeated connection attempts from foreign IP ranges in rapid succession
- ⚠ Alert from intrusion detection system (fail2ban, OSSEC) about excessive failures
- ⚠ New unknown user accounts or unexpected sudo entries if an attempt succeeds
Possible Root Causes
- • SSH port 22 exposed directly to the public internet without IP allowlisting
- • Password authentication enabled for SSH instead of key-only authentication
- • No rate-limiting or account lockout mechanism (fail2ban not installed/configured)
- • Default or weak credentials on system accounts (root, admin, ubuntu, ec2-user)
- • Server IP exposed via DNS, email headers, or public-facing application errors
Diagnosis Steps
1. Confirm brute-force activity in auth log
# Count failed attempts per source IP (last 1000 lines)
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# See invalid usernames being tried
grep "Invalid user" /var/log/auth.log | awk '{print $8}' | sort | uniq -c | sort -rn | head -20
# Count total failed attempts in the last hour
grep "$(date +'%b %e %H')" /var/log/auth.log | grep -c "Failed password"
2. Check current active connections to SSH port
# Show established and time-wait SSH connections
ss -tn state established '( dport = :22 or sport = :22 )'
# Count unique source IPs currently connecting
ss -tn '( dport = :22 or sport = :22 )' | awk 'NR>1 {print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn
3. Check fail2ban jail status
# Is fail2ban running?
sudo systemctl status fail2ban
# See current bans for the SSH jail
sudo fail2ban-client status sshd
# See the last 50 fail2ban log entries
sudo tail -50 /var/log/fail2ban.log
4. Identify top attacker IPs and look them up
# Extract top 10 attacker IPs
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# Whois lookup for the worst offender (replace IP)
whois 203.0.113.42
# Check if IP is on known blocklists
curl -s "https://api.abuseipdb.com/api/v2/check?ipAddress=203.0.113.42" \
-H "Key: YOUR_API_KEY" -H "Accept: application/json" | python3 -m json.tool
5. Check for any successful logins from suspicious IPs
# Look for successful logins (Accepted) and compare with known good IPs
grep "Accepted" /var/log/auth.log | awk '{print $9, $11}' | sort | uniq -c | sort -rn
# Check last successful logins
last -a | head -30
Solution
Immediate: Block the top attackers
# Manually block the worst offenders with iptables
sudo iptables -A INPUT -s 203.0.113.42 -j DROP
# Or use fail2ban to ban immediately
sudo fail2ban-client set sshd banip 203.0.113.42
Install and configure fail2ban (if not present)
sudo apt-get install fail2ban -y
# Create a local override
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 3600
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Disable password authentication (use keys only)
Edit /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
sudo sshd -t # Validate config
sudo systemctl restart sshd
Change SSH to a non-standard port (optional defence-in-depth)
Port 2222
Update your firewall rules accordingly and restart sshd.
Prevention
- Keys only: Disable
PasswordAuthenticationinsshd_config— brute force becomes computationally infeasible against Ed25519 keys. - fail2ban: Configure with
maxretry = 3,bantime = 86400(24h ban). Addrecidivejail for repeat offenders. - Firewall allowlist: If connecting from known IPs, whitelist those in your security group or iptables and drop all other port 22 traffic.
- Port obscurity: Move SSH off port 22 to reduce automated scan noise (not a security control by itself).
- Regular log review: Set up a weekly
grep "Accepted" /var/log/auth.logreport to catch unexpected successful logins.