Deploying WordPress websites often involves a set of automated scripts. These scripts can connect through SSH, copy files, run setup commands, and even use FTP when needed. All this magic makes going live smooth and predictable.
But recently, some developers noticed something odd. Their deployments kept failing—right at the SSH-to-FTP hook step. The culprit? WP fail2ban, doing its job a little too well.
TL;DR
The WP fail2ban plugin blocked valid SSH-to-FTP deployment hooks, mistaking them for brute force attacks. Automated deployment scripts were getting flagged and banned. After investigating, developers found the issue was in the regex pattern used to detect threats. Updating the regex fixed it and made sure real attacks are still blocked, but valid connections are safe.
What is WP fail2ban?
WP fail2ban is a security plugin for WordPress. It works with fail2ban, a system tool that watches your logs. When it sees something suspicious—like too many failed logins—it can block the IP.
This is great for stopping attackers who try to guess passwords or exploit known vulnerabilities. It’s part of a layered defense system for websites. But as with all automated defense tools, things can go sideways.
The Problem with Deployments
Let’s say you use an awesome deployment script. It connects to your server using SSH. Then it switches to FTP to upload some assets. It might even call a custom WordPress hook to finish the job.
In a perfect world, this goes smoothly. But what started happening was that these deployments were being auto-blocked by the server. Yikes.
fail2ban Cries Wolf
The fail2ban system uses regex patterns to scan log files. It looks for certain phrases that signal an attack. For example, 5 failed logins from the same IP? Blocked. An FTP login that doesn’t quite look right? Suspicious.
The problem was that certain automated, legitimate FTP connections looked like brute force attempts to the regex that WP fail2ban was using.
This was especially true when the FTP command was called right after an SSH connection. The logs just looked sketchy to the regex—even though a human would see it’s a normal deployment.
Identifying the Misfire
Several dev teams began seeing strange bans on their IP addresses. After checking their deployment logs and server logs, the pattern became clear:
- Connect via SSH ✅
- Run deploy script ✅
- Switch to FTP to send media files ✅
- Connection drops mid-deploy ❌
- Check server → BLOCKED IP ❗️
The FTP activity, seen out of context, matched WP fail2ban’s pattern for brute-force FTP login attempts. It wasn’t malicious, but it looked close enough to trigger a block.
Diving into the Regex
Regex (short for Regular Expression) is powerful. It’s used to match patterns in text. In the case of fail2ban, the regex reads log entries and looks for “bad behavior.”
Here’s a simplified example of a regex pattern gone rogue:
Failed password.*for.*from (.*) port
This matches a standard failed SSH login. But if a deployed FTP user logs in quickly and fails once (or appears to), the log might look similar. The pattern sees “failed,” “password,” and “from IP”—and boom, banished!
The real regex that WP fail2ban used was more complex, but the idea was the same: legit behavior closely mimics malicious patterns sometimes.
Enter the Fix: A Better Regex
The root fix was to update the regex so it would still catch real threats but ignore safe deployment steps.
Developers rewrote the regex to be more precise. It now checks for patterns that only occur in truly failed login attempts. It ignores legit system behaviors like:
- Successful, quick FTP logins
- Automated logins that follow a specific deploy tag
- IP addresses already whitelisted by the user
Additionally, the new regex includes timing checks and log context. This way, it won’t flag a single failed attempt if it’s followed by a successful one in the same session.
The New Behavior
With the updated regex, here’s what happens now:
- Deployment script connects via SSH ✅
- Switches to FTP ✅
- Uploads files ✅
- Continuously logged and monitored, but not blocked ✅
If a real hacker tries to fake this behavior, they’d need to mimic the exact pattern of a working deployment. That’s hard—and even then, fail2ban now asks, “Hmm, is this really an attack?”
Lessons Learned
This issue taught us a few important things about automation and security:
- Regex can be too sensitive – Even a small oversight can cause bans for legit users.
- Logs have context – A line in isolation can look dangerous, but patterns over time tell the real story.
- Test security during deployments – If you deploy automatically, make sure nothing in the security stack blocks it.
- Whitelisting carefully – Sometimes, giving known IPs or deploy servers a pass is a safer way to go.
How to Protect Your Deployments
If you’re managing a WordPress site with automated deployments, here are a few steps to stay safe and efficient:
- Update to the latest WP fail2ban version that includes the new regex.
- Review your
/etc/fail2ban/jail.localfile and adjust bans for your deployment IP addresses. - Add “deploy” tags or comments in your scripts to help create log trail clues.
- Check logs regularly to spot unnecessary bans.
If you’re unsure about your regex configs, now’s a great time to brush up on regex—or ask your devops folks to help fine-tune it.
The Bigger Picture
Security tools are awesome. They save our sites from daily attacks. But they’re not perfect. Sometimes, we need to tweak them to understand the difference between “bad guy creeping in” and “dev trying to push to live.”
The goal isn’t to weaken security—it’s to build smart security. And smart means knowing the context.
Final Thoughts
Automation is only as good as the systems watching it. WP fail2ban is still a rock-solid line of defense—it just needed to be taught the difference between foe and friend.
If you’ve been hitting walls during deployment, check your logs and regex rules. It might just be a robot misunderstanding another robot.
After all, even machines need a little empathy.
Happy deploying, and may your scripts always complete without being blocked!