Brute-Force Protection: Fail2ban, Rate Limits and Login Hardening

Brute-force protection is the set of controls that stop attackers from guessing their way into your server, your website admin area or your mailboxes. Every public server is probed constantly. Within minutes of a new machine appearing online, automated tools start trying common usernames and passwords against SSH, WordPress login pages, mail services and control panels. Most attempts fail, but they cost bandwidth and processing time, fill logs with noise and, when one finally succeeds, hand the attacker everything. The aim is not to make attempts impossible but to make guessing so slow, so limited and so unrewarding that it never works.
This guide explains how brute-force and credential-stuffing attacks work, which layers of defence matter most, how to configure Fail2ban and web server rate limits, how to harden SSH and WordPress logins, and how to monitor the result. It is written for administrators of small business servers and for owners who want to know what to ask their provider. Test every configuration change on a non-critical system first, and always keep a second way into the server so a mistake does not lock you out.
How These Attacks Actually Work
A classic brute-force attack tries many passwords against one account. A password-spraying attack tries one or two common passwords against many accounts, which avoids lockouts on any single user. Credential stuffing takes usernames and passwords leaked from other breaches and tries them on your service, betting that people reuse passwords. All three are automated and distributed: requests arrive from thousands of addresses, often from compromised devices, so blocking one address stops little.
The services most often targeted are:
- SSH, for shell access to the server.
- WordPress and other CMS login pages, including the XML-RPC endpoint that can test many passwords in one request.
- Mail services, where a stolen mailbox is used to send spam or reset other accounts.
- Control panels and database admin tools, which often sit on predictable addresses.
- FTP and other legacy services that nobody remembered to close.
The overview of brute-force attacks gives the general background, and the OWASP guide to blocking brute-force attacks lists the principles used below.
Defence in Layers
No single control is enough. The strongest set-ups stack several, so that an attacker who gets past one still meets the next.
- Remove the target. Close services you do not use and restrict others to known addresses.
- Remove the weak secret. Use keys instead of passwords for SSH, long unique passwords elsewhere and a second factor wherever it is offered.
- Slow the guessing. Apply rate limits and progressive delays at the web server and application.
- Ban the offenders. Use Fail2ban or a similar tool to block addresses after repeated failures.
- Filter upstream. Use a firewall or web application firewall to drop known-bad traffic before it reaches the server.
- Watch and alert. Read the logs, and get notified about unusual patterns and successful logins from new places.
Layers Compared
| Control | What it stops | Effort | Side effects | Where to apply |
|---|---|---|---|---|
| SSH keys, passwords off | All password guessing on SSH | Low | Lose access if key lost; keep a backup key | Every server |
| Two-factor authentication | Stolen or guessed passwords | Low to medium | Extra step at login | Admin areas, mail, panels |
| Fail2ban | Repeated failures from one address | Medium | Possible self-lockout, needs allow-list | SSH, mail, web logins |
| Web server rate limits | Fast guessing against login URLs | Medium | Can slow real users behind shared addresses | Login and XML-RPC endpoints |
| Firewall restrictions by address | Everyone outside allowed ranges | Low | Needs fixed addresses or a VPN | SSH, panels, database tools |
| Web application firewall | Known malicious sources and patterns | Low to medium | Occasional false positives | Public websites |
Harden SSH First
SSH is usually the most valuable door on a server. These settings in the SSH daemon configuration remove most of the risk:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
AllowUsers deploy admin2
Create a normal administrator account with a key pair, test that you can log in with it and elevate privileges, and only then disable root login and password authentication. Keep an existing session open while you test a new one, so a typing mistake does not lock you out. Protect private keys with a passphrase and store a backup in a secure place.
Changing the SSH port reduces log noise from lazy scanners but is not real protection; do it if you like, but never rely on it. A stronger step is to restrict SSH to a VPN or to known office addresses in the firewall. Where that is not possible, Fail2ban becomes more important. Our article on server security hardening basics puts these steps in the context of the rest of the server.
Set Up Fail2ban
Fail2ban reads log files, spots repeated failures and adds temporary firewall rules that block the offending address. It ships with filters for SSH, common mail servers and many web applications. Settings go into a local configuration file so that package updates do not overwrite them. A sensible starting point:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
[sshd]
enabled = true
maxretry = 4
The ignoreip line holds your own fixed addresses so you cannot ban yourself; replace the example address with yours. Findtime is the window in which failures are counted, maxretry is the number of failures allowed within it and bantime is how long the block lasts. The increment option lengthens bans for repeat offenders. After enabling, check the status of each jail, review the banned list and confirm that normal logins still work.
Add jails for the other services you run: mail authentication, web login pages and any control panel. For WordPress, a filter that matches failed login entries in the access log or a plugin-written log can feed a jail. Check the documented filter for your mail server version, since log formats differ.
Fail2ban has limits. Attackers using thousands of addresses with a few tries each will not trip a per-address threshold, and banning by address can catch legitimate users behind a shared office or mobile network address. That is why it belongs in a stack with the other controls and not on its own.
Rate-Limit Login URLs on the Web Server
The web server can slow requests to sensitive paths before PHP or the application is involved. With nginx, a request limit zone applied to the login location looks like this:
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
location = /wp-login.php {
limit_req zone=login burst=5 nodelay;
# normal PHP handling here
}
This allows ten requests per minute per address with a small burst, then answers further requests with an error. Apache can achieve similar effects with modules for evasion and rate control or by combining a web application firewall with custom rules. Choose a rate that real users never reach: a person logging in manually will not exceed it, a script will. Our comparison of Apache and nginx for WordPress explains how each server handles configuration like this.
Harden WordPress Logins
WordPress sites are targeted so often that dedicated steps are worthwhile. The WordPress documentation on brute force attacks lists the main measures; the most useful are:
- Use long, unique passwords and a password manager for every account, and turn on two-factor authentication for administrators and editors.
- Do not use “admin” as a username and do not expose usernames. Disable author archives that reveal login names if you do not need them.
- Limit login attempts with a plugin or with server rules, with delays that grow after each failure.
- Restrict or disable XML-RPC if you do not use it. It allows many password attempts in a single request.
- Restrict the admin area by address or behind an extra layer of protection where practical.
- Give each person the least privilege they need, so a compromised account has limited power.
- Keep core, themes and plugins updated, because stolen sessions and weak plugins bypass login protections altogether.
The guides on multi-factor authentication and password managers and on user roles and permissions cover the human side of these steps.
Protect Mail and Other Services
Mail accounts are attacked because they are valuable: they send spam, receive password resets and hold business conversations. Enforce long passwords, disable legacy protocols that cannot use modern authentication where possible, and set limits on failed authentication in the mail server. Review outgoing mail volume per account so a compromised mailbox is spotted by a sudden spike. Database administration tools and control panels should never be reachable from the whole internet if you can avoid it; restrict them by address or place them behind a VPN. Close FTP in favour of encrypted file transfer, and remove old test accounts and default credentials from every service.
Use Filtering Upstream
A network firewall and a web application firewall can drop traffic before it consumes server resources. Block entire ranges of traffic you never expect, such as countries where you have no customers, with care and with an exception process, since address-based geography is imperfect. A content delivery network with bot management can challenge suspicious requests to login pages. We explain what these services do in our article on CDN and web application firewall options. Filtering reduces noise, but it is not a replacement for strong credentials and a second factor.
Monitor, Alert and Respond
Protection that nobody watches decays. Set up simple monitoring.
- Review authentication failures weekly: top source addresses, targeted usernames and any success after many failures.
- Alert on successful administrator logins from new countries or at unusual hours.
- Alert when Fail2ban bans spike, because a sudden increase suggests a targeted campaign.
- Check that logs rotate properly and are kept long enough to investigate; see our guide to server log analysis for how to read them.
If you find a successful login you did not expect, act quickly: disable the account, rotate credentials, review recent changes and active sessions, check for new users, scheduled tasks and modified files, and restore from a clean backup if needed. Treat it as an incident, not a curiosity. Our server administration service includes this kind of monitoring and response so that small businesses do not need to watch logs themselves.
A Short Checklist
- Close or restrict every service you do not need on the public internet.
- Use SSH keys, disable password and root login, and keep a recovery path.
- Install Fail2ban with your own addresses allow-listed and jails for each exposed service.
- Rate-limit login and XML-RPC paths on the web server.
- Turn on two-factor authentication for admin accounts and mail where available.
- Use a password manager and unique passwords everywhere.
- Keep software updated and permissions minimal.
- Review authentication logs and alerts every week.
- Test your recovery plan so you know how to respond to a compromise.
Frequently Asked Questions
Is Fail2ban enough to stop brute-force attacks?
No. It helps against repeated failures from one address, but distributed attacks use many addresses with few attempts each. Combine it with keys, two-factor authentication, rate limits and strong unique passwords.
Should I change the default SSH port?
It reduces log noise from basic scanners but offers no real security. Use keys, disable password login and restrict access by address or VPN; treat a port change as optional tidiness.
How do I avoid locking myself out with Fail2ban?
Add your own fixed addresses to the ignore list, keep an extra session open while testing, and have a second way into the server, such as a provider console.
Do I need to protect XML-RPC on WordPress?
If you do not use it, disable or restrict it, since it can test many passwords in a single request. If you rely on it, limit access and monitor it closely.
What is the difference between brute force and credential stuffing?
Brute force guesses passwords. Credential stuffing tries real username and password pairs leaked from other sites. Unique passwords and two-factor authentication defend against both.
How often should I review login attempts?
Weekly for a quick look at top sources and any success after many failures, with alerts for unusual successful logins so you do not depend on remembering to check.
The Bottom Line
Brute-force protection works by layering simple controls: close what you do not need, replace guessable secrets with keys, long unique passwords and a second factor, slow guessing with rate limits, ban repeat offenders with Fail2ban and filter known-bad traffic upstream. Then watch the logs and act on the exceptions. None of the steps is difficult on its own, and together they turn a constant stream of automated attempts into background noise. Set them up once, test your recovery path and review the results weekly, and the odds of a guessed password becoming a breach fall dramatically.