Understanding brute-force attacks

2 min read07 November 2026

As soon as a server exposes an authentication service on the Internet, it receives automated attempts. This is not a targeted attack, it is background noise: bots try common credentials on SSH, login forms and APIs. Recognising it prevents confusing that normal pressure with a real intrusion.

What the logs show

Bash
sudo journalctl -u ssh -n 100 --no-pager
sudo grep "Failed password" /var/log/auth.log | tail -n 20
sudo grep -c "Failed password" /var/log/auth.log
sudo lastb | head

Typical lines mention invalid user admin, root or random names, followed by Failed password. On a minimal install without rsyslog, /var/log/auth.log may be absent: journalctl is then the reliable source. Hundreds of attempts per day on a public IPv4 address are ordinary. What matters are Accepted lines: a successful login from an unknown address is the signal to examine first.

Why keys change the game

A password attack only has leverage if password authentication is enabled. A properly protected Ed25519 key cannot be guessed. Order matters:

  1. install your key and test it in a second session;
  2. set PasswordAuthentication no and PermitRootLogin prohibit-password in /etc/ssh/sshd_config.d/;
  3. validate with sudo sshd -t, then reload the service;
  4. keep the first session open until confirmed.

Changing the SSH port reduces log noise but is not a security measure on its own: a scan finds the port within minutes.

Reduce the surface

  • AllowUsers restricts which accounts may log in.
  • MaxAuthTries 3 and LoginGraceTime 20 limit attempts per connection.
  • ufw limit 22/tcp applies simple rate limiting if UFW is in place.
  • Fail2ban temporarily bans an address after several failures.
Bash
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

In jail.local, adjust the duration and threshold, and above all add your admin address to ignoreip before enabling:

JSON
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 YOUR_ADMIN_IP

[sshd]
enabled = true

Then check status with sudo fail2ban-client status sshd. Without an allowlist, a configuration mistake can ban you.

React to a successful attempt

If you find an unknown Accepted line, treat the server as compromised: check ~/.ssh/authorized_keys, users (/etc/passwd), cron jobs, processes and outbound connections. Change passwords and keys, then consider a reinstall if binaries were modified. Restarting the service is not enough: the access persists.

Other targets

Web login forms, wp-login.php, APIs and SMTP face the same pressure. Protect them with strong authentication, rate limiting at the Nginx layer and, where possible, two-factor authentication. If traffic saturates your VPS, contact support: upstream network filtering does not replace a correctly configured application.

Advertisement

Was this article helpful?

Read next