Loading...
Home
Explore
Contact
Sign in
Security, Hardening & Backups

Trace SSH Brute-Force Attacks and Cut High Linux CPU Load

Stop SSH brute-force storms draining CPU on Ubuntu/Debian servers. Trace failed logins, harden sshd_config, move off port 22, enforce key-only auth, and know when Fixwebnode should take over remotely in Australia.

Fixwebnode Support
Fixwebnode Support
9 min read 1 views
Trace SSH Brute-Force Attacks and Cut High Linux CPU Load

If your Linux VPS or dedicated box in Australia is pegged at high CPU while auth logs fill with failed passwords, you are almost certainly under an SSH brute-force loop. This guide walks you through tracing the attackers, blocking them, editing /etc/ssh/sshd_config for a non-standard port and key-only authentication, and verifying that CPU usage drops—without locking yourself out.

Fixwebnode provides direct remote Linux server support for homeowners and small businesses across Australia. When DIY stops being safe, book a specialist session via the Ubuntu Linux server support page rather than guessing under pressure.

Why SSH brute-force attacks spike CPU and break login tracking

Automated bots hammer port 22 with thousands of password guesses per hour. Each attempt wakes sshd, PAM, and often fail2ban or journald. On small cloud instances that load becomes sustained high CPU, slow shells, and noisy logs that hide real problems. Moving ingress off the default port, disabling password auth, and rate-limiting sources is the practical fix path.

How do I stop SSH brute-force attacks causing high CPU on a Linux server in Australia?

Identify the flood in auth logs, block repeat offenders at the firewall, then harden SSH: change the listen port, set PasswordAuthentication no and PubkeyAuthentication yes, reload sshd from a second session, and confirm CPU and failed-login rates fall. If you only have one open session or production depends on the box, hand the change window to a remote specialist.

SymptomQuick fixWhen to call Fixwebnode
CPU high; auth.log full of Failed passwordfail2ban or ufw deny + review top offendersBan list grows faster than you can maintain
Legitimate logins slow or time outMove SSH off 22; key-only authRisk of lockout; single session only
sshd restarts fail after config editsshd -t then fix syntax before reloadConsole/out-of-band access unavailable

Common issues unique to SSH brute-force and CPU spikes

1. Continuous failed-password storms on port 22

Symptoms: journalctl -u ssh or /var/log/auth.log shows repeated “Failed password” and “Invalid user” lines; sshd or kswapd appears in top; load average stays elevated even with idle web apps.

2. Password auth still enabled after “hardening”

Symptoms: keys work but bots still try passwords; CPU never fully settles; cloud provider abuse notices mention SSH scanning.

3. fail2ban or firewall rules thrashing under volume

Symptoms: ban/unban churn, iptables/nftables rule counts explode, short CPU spikes every minute, legitimate office IPs occasionally banned.

4. Accidental lockout after port or PermitRootLogin changes

Symptoms: new SSH sessions refuse connection; only the existing session still works; panic reload loops make CPU worse.

Issue 1 — Trace the brute-force source and measure CPU impact

Confirm the attack before changing production SSH.

Step 1 — Snapshot CPU and sshd

top -b -n 1 | head -n 20
ps aux --sort=-%cpu | head -n 15
systemctl status ssh || systemctl status sshd

Note whether sshd, fail2ban, or journald dominate CPU.

Step 2 — Pull failed login patterns

sudo grep -E "Failed password|Invalid user" /var/log/auth.log | tail -n 50
sudo journalctl -u ssh --since "1 hour ago" | grep -E "Failed|Invalid" | tail -n 50
sudo awk '/Failed password/ {print $(NF-3)}' /var/log/auth.log | sort | uniq -c | sort -nr | head -n 20

The last command ranks source IPs by failure count (field position can vary slightly by distro; adjust if needed).

Step 3 — Count connection attempts right now

sudo ss -tn state established '( dport = :22 or sport = :22 )' | wc -l
sudo ss -tn state syn-recv '( dport = :22 )' | head

High SYN-RECV or established counts on 22 support a live scan.

Step 4 — Optional quick block of a top offender (UFW)

sudo ufw deny from 203.0.113.50 to any port 22 proto tcp
sudo ufw status numbered | head

Replace the example IP with a real top offender. Prefer fail2ban for ongoing automation (next section).

When logs rotate too fast to read, disk is full, or you cannot tell scanners from staff VPNs, stop and use Fixwebnode remote Linux support.

Issue 2 — Block repeat offenders and calm the auth loop

Install and tune fail2ban so repeated failures earn temporary bans without manual IP whack-a-mole.

Step 1 — Install fail2ban

sudo apt-get update
sudo apt-get install -y fail2ban
sudo systemctl enable --now fail2ban

Step 2 — Local jail for SSH

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo tee /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
findtime = 10m
bantime = 1h
backend = systemd
EOF
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

On some Ubuntu builds logpath is unused when backend = systemd; keep the stanza anyway for clarity. After you change the SSH port later, update port = to the new number or use a comma list.

Step 3 — Verify bans and CPU

sudo fail2ban-client status sshd
top -b -n 1 | head -n 15
sudo journalctl -u ssh --since "10 min ago" | grep -c "Failed password"

Failed-password rate should fall within minutes if bans stick.

Step 4 — Whitelist your admin IP

sudo tee -a /etc/fail2ban/jail.d/sshd.local > /dev/null <<'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 198.51.100.20
EOF
sudo systemctl restart fail2ban

Use your real static office or home IP. Dynamic consumer IPs need care or you ban yourself.

Call Fixwebnode if ban lists grow into thousands of entries, nftables/iptables latency appears, or you run a custom SSH port behind Cloudflare Spectrum or a bastion and jail matching breaks.

Issue 3 — Edit sshd_config: non-standard port and key-only auth

This is the core hardening path from the brief. Do it from a second session and never close the working session until a new login succeeds.

Prerequisites

  • Your public key already in ~/.ssh/authorized_keys for the admin user.
  • Console, VNC, or provider serial access available if possible.
  • UFW/security group will allow the new port before you reload sshd.

Step 1 — Confirm key login works on the current port

ssh -i ~/.ssh/id_ed25519 -p 22 admin@YOUR_SERVER_IP
grep -E '^(PasswordAuthentication|PubkeyAuthentication|PermitRootLogin|Port)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null

Step 2 — Open the new port on the firewall first

sudo ufw allow 2222/tcp comment 'SSH alternate'
sudo ufw allow OpenSSH
sudo ufw status

Pick any high unused port you will remember; 2222 is an example only. Cloud security groups must allow it too.

Step 3 — Write a drop-in config (safer than editing the whole file blind)

sudo mkdir -p /etc/ssh/sshd_config.d
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null <<'EOF'
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
LoginGraceTime 30
AllowUsers admin
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 120
ClientAliveCountMax 2
EOF

Replace admin with your real sudo user. If root keys are mandatory in your environment, set PermitRootLogin prohibit-password instead of no and understand the risk.

Step 4 — Syntax check before reload

sudo sshd -t
echo $?

Exit code 0 means the config parses. Fix any reported line before continuing.

Step 5 — Reload sshd (keep the old session open)

sudo systemctl reload ssh || sudo systemctl reload sshd
sudo systemctl status ssh --no-pager || sudo systemctl status sshd --no-pager
sudo ss -tlnp | grep sshd

You should see sshd listening on 2222 (and possibly still on 22 until a full restart if an old directive remains—remove duplicate Port 22 lines from the main file if needed, then sshd -t and restart).

Step 6 — Test a brand-new session on the new port

ssh -i ~/.ssh/id_ed25519 -p 2222 admin@YOUR_SERVER_IP

Only after this works, close extra sessions and tighten the firewall:

sudo ufw delete allow OpenSSH
sudo ufw allow 2222/tcp
sudo ufw status numbered

Step 7 — Point fail2ban at the new port

sudo sed -i 's/^port = ssh/port = 2222/' /etc/fail2ban/jail.d/sshd.local
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Step 8 — Confirm password auth is dead

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no -p 2222 admin@YOUR_SERVER_IP

This must fail. CPU and auth noise should drop sharply within an hour as bots still hit closed port 22.

Book Fixwebnode when you have only one live session, use nested bastions, or manage fleets where a bad reload means downtime for staff across Australia.

Issue 4 — Reduce leftover CPU load after the attack quiets

Brute-force aftermath can leave journal growth, stuck processes, or misconfigured monitoring.

Step 1 — Re-check resource hogs

top -b -n 1 | head -n 25
sudo journalctl --disk-usage
sudo du -sh /var/log/* | sort -h | tail

Step 2 — Vacuum old journals if safe

sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=200M

Step 3 — Confirm sshd workers are idle

ps -C sshd -o pid,user,%cpu,%mem,args
sudo ss -tn | grep ':2222' | wc -l

Step 4 — Optional unattended-upgrades sanity

sudo apt-get install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

Keep kernel and openssh packages patched so tomorrow’s exploit is not today’s CPU incident.

If load remains high with quiet SSH logs, the bottleneck may be PHP-FPM, MySQL, or a compromised process—not SSH. That is a broader performance pass, not more firewall rules.

When DIY is enough vs when to book Fixwebnode

DIY is enough when you already have working key auth, provider console access, a second laptop session, and a non-production or low-traffic window. Follow the numbered steps above, keep the original session open, and verify every reload.

Book Fixwebnode when any of these apply: sole SSH session on a live store; unclear which IP ranges belong to staff; custom SELinux/AppArmor policies; Docker-published SSH; repeated lockouts; or CPU still high after auth storms stop. Fixwebnode works as a direct remote specialist for Linux servers—not a freelance marketplace—covering remote diagnostics for clients across Australia. See where support is offered on the service areas page.

Related build work such as headless WordPress with React/Next.js frontends still depends on a quiet, hardened SSH edge; fix the brute-force CPU loop before chasing application performance.

Book remote help and close the loop

You now have a full path: trace failures, ban repeaters, shift SSH off port 22, enforce key-only passwordless authentication in sshd_config, and re-check CPU. If you want a guided change window or a second pair of eyes before reload, start a conversation with Fixwebnode through the Linux server support landing page. Bring your distro version, current SSH port, and whether console access exists—we will take it from the terminal under pressure with you.

Share this article
Fixwebnode Support
Fixwebnode Support

Hey there!
I am your assistant for Fixwebnode. Ask about our services, quotes, packages, orders, or how to get support.
While you wait
What’s your name and best email? We’ll reply even if you leave.