Introduction
This guide explains how to add PureFTPd service to Fail2ban on Ubuntu, so that repeated failed login attempts against your FTP server automatically get blocked instead of left open to brute-force attacks. If you’re running Pure-FTPd on a public-facing Ubuntu server, this is one of the simplest, highest-value hardening steps you can take — and it takes only a few minutes to set up.
Fail2ban works by scanning log files for patterns that indicate malicious activity — like repeated failed login attempts — and automatically banning the offending IP address for a configurable period of time, usually by adding a temporary firewall rule. By default, Fail2ban ships with filters for many common services, but FTP protection via Pure-FTPd isn’t always enabled out of the box, which is exactly what this guide walks through fixing.
By the end of this post, Fail2ban will be actively monitoring your Pure-FTPd logs and automatically banning IPs that repeatedly fail to authenticate.
Implementation
I. Prerequisites
Before you add PureFTPd service to Fail2ban on Ubuntu, make sure you have:
- An Ubuntu host with Pure-FTPd already installed and running
- Fail2ban installed and running
If Fail2ban isn’t installed yet, follow our guide on installing Fail2ban on Ubuntu before continuing with the steps below.
II. Understand How Fail2ban Protects Services
Before making changes, it helps to understand what’s actually happening under the hood. Fail2ban is made up of two main components that work together for each protected service:
- A filter — a regular expression pattern that tells Fail2ban what a “failed login” looks like in a specific service’s log file
- A jail — a configuration block that ties a filter to a specific log file, port, and set of ban rules (like how many failures trigger a ban, and for how long)
Fail2ban ships with a pre-built filter for Pure-FTPd (pure-ftpd.conf), but it isn’t enabled by default. The steps below activate it by creating a matching jail configuration.
III. Copy the Pure-FTPd Filter File
Fail2ban includes a default filter definition for Pure-FTPd, but under a slightly different filename than what we’ll reference in the jail configuration. Copy it to a new filename for clarity and consistency with the jail name we’ll use:
cp /etc/fail2ban/filter.d/pure-ftpd.conf /etc/fail2ban/filter.d/pureftpd.conf
Note: This step is mostly about naming consistency — you could reference
pure-ftpddirectly in your jail configuration instead and skip the copy. Renaming it topureftpdhere just keeps the filter name matching the jail name we’ll define next, which makes the configuration easier to read and maintain later.
IV. Configure the PureFTPd Jail
Open Fail2ban’s local jail configuration file. Using jail.local instead of editing jail.conf directly is important — jail.conf gets overwritten on Fail2ban updates, while jail.local is preserved and takes precedence:
vi /etc/fail2ban/jail.local
Add the following block:
[pureftpd] enabled = true port = ftp filter = pureftpd logpath = /var/log/syslog maxretry = 3
Here’s what each line configures:
| Setting | Purpose |
|---|---|
enabled | Turns this jail on |
port | The service port to apply firewall bans against (ftp maps to port 21) |
filter | The filter file to use for pattern matching (references pureftpd.conf from Step III) |
logpath | The log file Fail2ban monitors for failed login patterns |
maxretry | The number of failed attempts allowed before an IP is banned |
Tip: You can also add a
bantimesetting (in seconds) to control how long an IP stays banned, andfindtimeto control the window of timemaxretryfailures need to occur within. If omitted, Fail2ban uses the defaults defined elsewhere in your configuration (commonly a 10-minute ban with Fail2ban’s out-of-the-box defaults, though this varies by version and prior configuration).
V. Verify the Log Path Matches Your System
The logpath value above assumes Pure-FTPd logs to /var/log/syslog, which is common on Ubuntu when Pure-FTPd is configured to log via syslog. However, this can vary depending on how Pure-FTPd was installed and configured. Confirm the actual log location before restarting Fail2ban:
sudo grep -i pure-ftpd /var/log/syslog | tail -5
If you see recent Pure-FTPd log entries, the path is correct. If not, check your Pure-FTPd configuration for a custom log path — commonly /var/log/pure-ftpd/ — and update the logpath value in your jail configuration to match.
VI. Restart Fail2ban
Apply the new configuration by restarting the Fail2ban service:
sudo systemctl restart fail2ban
VII. Verify the PureFTPd Jail Is Active
Confirm that Fail2ban picked up the new jail:
fail2ban-client status
You should see pureftpd listed among the active jails. For more detail on that specific jail — including how many IPs are currently banned — run:
fail2ban-client status pureftpd
This shows the filter and log file in use, along with any currently banned IP addresses.
VIII. Test the Configuration
It’s worth confirming the jail actually works rather than assuming it does. From a separate machine (not one you rely on for legitimate access, in case something goes wrong), attempt to log in to the FTP server with an incorrect password several times in a row — enough to exceed the maxretry value you configured.
Then check the jail status again:
fail2ban-client status pureftpd
You should see the test IP address listed under “Banned IP list.” If it isn’t showing up, double-check the log path from Step V and confirm Pure-FTPd is actually logging failed attempts in the format Fail2ban’s filter expects.
IX. Unban an IP (If Needed)
If you ever need to manually remove a ban — for example, after confirming a legitimate user was mistakenly blocked — use:
sudo fail2ban-client set pureftpd unbanip <IP_ADDRESS>
Replace <IP_ADDRESS> with the actual banned address.
X. Common Troubleshooting Issues
The pureftpd jail doesn’t appear in fail2ban-client status: Double-check that enabled = true is actually set under the [pureftpd] block, and confirm there are no syntax errors elsewhere in jail.local — a single misplaced line can sometimes prevent the entire file from loading correctly.
Fail2ban restarts successfully but never bans anything: This almost always comes down to the logpath not matching where Pure-FTPd is actually writing its logs, or the filter’s regex pattern not matching your specific Pure-FTPd log format/version. Re-check Step V, and consider testing the filter directly with fail2ban-regex:
fail2ban-regex /var/log/syslog /etc/fail2ban/filter.d/pureftpd.conf
This command shows exactly how many lines matched the filter pattern, which is useful for confirming whether the issue is the log path or the filter itself.
Legitimate users are getting banned too easily: Consider raising maxretry slightly, or increasing findtime so that occasional typos don’t trigger a ban as quickly as a genuine brute-force attempt would.
XI. Customizing Ban Actions
By default, Fail2ban bans IPs using firewall rules (via iptables, nftables, or firewalld, depending on your system configuration), which simply drops traffic from the offending address. But Fail2ban’s “actions” are configurable, and it’s worth knowing what else is available:
Send an email notification on ban:
Fail2ban can notify you whenever a ban occurs, which is useful for keeping an eye on attack patterns without manually checking status output. This requires a working mail setup on your server, then adding an action like:
[pureftpd] enabled = true port = ftp filter = pureftpd logpath = /var/log/syslog maxretry = 3 action = %(action_mw)s
The action_mw action bans the IP and sends an email with a whois report about it — useful context for understanding whether an attack is coming from a known hosting provider, residential ISP, or a known malicious range.
Increase ban time for repeat offenders:
Newer versions of Fail2ban support “recidive” jails, which specifically watch Fail2ban’s own log for IPs that get banned repeatedly across any jail, and apply a much longer ban the second time around. This is a more advanced setup, but worth exploring once your basic PureFTPd jail is confirmed working, since it meaningfully raises the cost of persistent attackers without added maintenance once configured.
XII. Reviewing Fail2ban Logs
Beyond checking jail status, Fail2ban keeps its own log file that records every ban, unban, and filter match — useful for auditing activity over time or diagnosing why a particular IP wasn’t banned when you expected it to be.
sudo tail -f /var/log/fail2ban.log
Watching this file live while intentionally triggering a few failed logins (as in the testing step above) is one of the most reliable ways to confirm the entire pipeline — from log line, to filter match, to ban action — is working end to end.
You can also filter the log for just PureFTPd-related entries:
sudo grep pureftpd /var/log/fail2ban.log
This shows a clean history of every match and ban action taken specifically by this jail, which is helpful when you want to confirm the jail has actually been active over time, not just enabled in configuration.
XIII. Best Practices for FTP and Fail2ban Security
A few additional steps worth considering alongside this Fail2ban configuration:
- Prefer SFTP/FTPS over plain FTP where possible. Plain FTP transmits credentials unencrypted, so even with Fail2ban blocking brute-force attempts, credentials sent over an unencrypted connection remain vulnerable to interception on an untrusted network.
- Set a reasonable
bantime. A longer ban time (hours, rather than minutes) meaningfully raises the cost of a brute-force attempt without much downside for legitimate users, who rarely fail login three times in a row anyway. - Monitor banned IPs periodically. Reviewing
fail2ban-client status pureftpdoccasionally can reveal patterns — like the same IP range attacking repeatedly — that might warrant a broader firewall rule. - Keep Fail2ban and Pure-FTPd updated. Both filter patterns and known vulnerabilities change over time; staying current ensures the filter continues to match actual log formats and that known security issues are patched.
XIV. Conclusion
Adding Pure-FTPd to Fail2ban on Ubuntu is a quick, high-value change: copy the filter, define a jail with a sensible maxretry threshold, confirm the log path matches your actual Pure-FTPd configuration, and restart the service. Once verified with a real test, Fail2ban will automatically block IP addresses that repeatedly fail to authenticate — cutting down on brute-force login attempts without requiring any ongoing manual effort.
For more background on Fail2ban’s configuration options and available filters, see the official Fail2ban documentation.
Frequently Asked Questions
Does Fail2ban work with FTPS or only plain FTP? Fail2ban itself works at the log-monitoring level, so it can protect FTPS the same way, as long as Pure-FTPd’s failed-login log format matches what the filter expects. The port setting in your jail may need adjusting if FTPS uses a different port than standard FTP in your configuration.
How long should I set the ban time for? There’s no universal answer, but many admins use anywhere from 1 hour to 24 hours for a first offense, with some Fail2ban configurations supporting escalating ban times for repeat offenders. Longer bans meaningfully deter automated attacks with minimal impact on real users, who rarely need to retry logins that many times.
Can I protect multiple services with Fail2ban at the same time? Yes — Fail2ban supports running many independent jails simultaneously, each targeting a different service (SSH, FTP, a web application login form, etc.), all defined in the same jail.local file as separate [jail-name] blocks.
What happens if I ban my own IP address by accident during testing? Use the fail2ban-client set <jail-name> unbanip <IP_ADDRESS> command from Step IX to remove the ban immediately, assuming you still have another way to access the server (like a separate SSH session or your hosting provider’s console) while it’s in effect.
Why does my jail show as enabled but never actually bans any IPs, even during a real attack? This is almost always a mismatch between what the filter’s regex expects and what your Pure-FTPd version actually writes to the log. Log formats can differ slightly between Pure-FTPd versions and configurations (for example, whether it logs via syslog, a dedicated log file, or a custom format string). Running fail2ban-regex against your actual log file, as shown in the troubleshooting section, is the fastest way to confirm whether the filter is matching anything at all — if it reports zero matches against lines you know represent failed logins, the filter pattern itself likely needs adjusting for your specific Pure-FTPd version.
Talk to Our Technology Experts
Hardening your server against brute-force attacks? Our team can help with firewall configuration, server hardening, and ongoing security monitoring.
Connect with our technology experts.