How I Detect and Prevent Brute-Force Attacks (A 6-Month Review)

Security tutorial - IT technology blog
Security tutorial - IT technology blog

The Wake-Up Call: A Midnight Attack

A flood of server alerts at 2 AM is a rude awakening. That was my reality six months ago, when my inbox exploded with over 500 notifications for failed login attempts on a brand-new server. It was a classic, relentless SSH brute-force attack.

Automated scripts were hammering away, trying thousands of password combinations. While they didn’t get in, the incident taught me a critical lesson: default security is no security at all. That night cemented my commitment to prioritizing security from the moment a server goes live.

Over the last six months, I’ve refined a layered defense strategy that has turned my noisy, constantly-probed servers into quiet fortresses. This isn’t about complex, enterprise-grade tools. It’s a practical setup that any IT professional or hobbyist can implement. Here’s the story of that setup, what works, and how you can do it, too.

Understanding the Battlefield: What is a Brute-Force Attack?

Before building our defenses, we need to know the enemy. A brute-force attack is essentially a digital battering ram. Attackers use automated scripts to try an enormous number of combinations to guess your credentials. They primarily come in two flavors:

  • Dictionary Attack: The script cycles through a list of common or previously leaked passwords, like `password`, `123456`, or `qwerty`.
  • Pure Brute-Force: The script methodically tries every possible character combination (aaa, aab, aac…). This is slower but far more exhaustive.

The most common targets are services exposed to the internet, like SSH, RDP, FTP, and web application login pages—especially WordPress. A successful attack means unauthorized access, data theft, and a massive drain on your server’s CPU and memory. Our goal is to make these attacks so ineffective that the attacker gives up and moves on.

My Go-To Strategy: Proactive, Layered Defense

My approach is simple: make the front door incredibly strong, then post an automated guard to kick out anyone who lingers. It’s a highly effective combination that has proven incredibly reliable.

Layer 1: Hardening the Front Door with SSH Keys

The single most important change you can make is to disable password authentication for SSH and use cryptographic keys instead. A password, especially a weak one, can be guessed. A properly generated cryptographic key cannot. An SSH key pair consists of a private key (kept safe on your local machine) and a public key (placed on the server). The server grants access only to someone who can prove they have the correct private key.

1. Generate Your Key Pair

If you don’t have one already, create one on your local computer. Open a terminal and run:

ssh-keygen -t rsa -b 4096

This command creates a strong 4096-bit RSA key. You’ll be prompted to save the file and set an optional passphrase. I highly recommend using a passphrase for an extra layer of security.

2. Copy Your Public Key to the Server

Next, install the public key on your server. The easiest way is with the `ssh-copy-id` utility.

ssh-copy-id user@your_server_ip

It will ask for your password one last time. This command automatically appends your public key to the `~/.ssh/authorized_keys` file on the server.

3. Disable Password Authentication

This is the final, crucial step. Log into your server and open the SSH daemon’s configuration file using a text editor like nano or vim.

sudo nano /etc/ssh/sshd_config

Find the `PasswordAuthentication` line and change its value to `no`. While you’re in this file, it’s also best practice to disable direct root logins by setting `PermitRootLogin` to `no`.

# Change this line
PasswordAuthentication no

# And this one too
PermitRootLogin no

Save the file, then restart the SSH service to apply the changes.

sudo systemctl restart sshd

With this change, password-based login attempts are now impossible. The vast majority of brute-force bots will be blocked instantly.

Layer 2: The Automated Gatekeeper, Fail2ban

With the front door hardened, my next layer is an automated gatekeeper: Fail2ban. This brilliant tool scans log files for malicious activity, such as repeated failed login attempts. When it detects an offender, it automatically updates the firewall to block their IP address for a set amount of time.

1. Installation

On Debian or Ubuntu, installation is a one-line command.

sudo apt update && sudo apt install fail2ban -y

2. Configuration

Fail2ban’s main configuration is `/etc/fail2ban/jail.conf`. Never edit this file directly, as updates can overwrite it. Instead, create a local copy where you can safely make your own changes.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Now, open `jail.local` to customize your rules.

sudo nano /etc/fail2ban/jail.local

To start, I focus on the `[sshd]` section. This configuration is a fantastic baseline:

[sshd]
enabled = true
port    = ssh
maxretry = 3
findtime = 300
bantime = 3600
logpath = /var/log/auth.log
  • enabled: Activates this rule (called a “jail”).
  • maxretry: The number of failed attempts before a ban. Three is a good, strict number.
  • findtime: The time window (in seconds) for the failures. Three failed attempts within 300 seconds (5 minutes) is a clear bot signal.
  • bantime: How long the ban lasts (in seconds). I start with 3600 (1 hour). If I see repeat offenders, I’ll increase this to `86400` (24 hours).

After saving your changes, restart Fail2ban to load the new configuration.

sudo systemctl restart fail2ban

3. Checking the Status

You can watch Fail2ban work. To check the SSH jail and see a list of banned IPs, run:

sudo fail2ban-client status sshd

If you ever accidentally lock yourself out (it happens!), you can unban your IP address from the server’s console:

sudo fail2ban-client set sshd unbanip YOUR_IP_ADDRESS

Layer 3: Don’t Forget Web Applications

Brute-force attacks aren’t just for SSH. Login forms for WordPress, Joomla, and other web apps are huge targets. The defense principle is the same: limit login attempts. For WordPress, the Wordfence Security plugin offers a great login attempt limiter. Whatever your platform, find a similar tool. More importantly, enforce strong passwords and Two-Factor Authentication (2FA). For any critical user account, 2FA is non-negotiable.

Six Months Later: Peace and Quiet

The combination of SSH key authentication and Fail2ban’s automated blocking has been profoundly effective. My server logs tell the story. The daily noise of hundreds of failed logins has vanished, replaced by near silence. My `auth.log` file, which once grew by megabytes each day, now barely registers a few kilobytes. Security isn’t a single product you install; it’s a process of layering smart defenses.

Of course, you still need to review your logs periodically and keep your system updated. But by implementing these practical steps, you can build a resilient defense that provides immense peace of mind. It certainly has for me.

Share: