A WordPress server exposed to the internet is scanned continuously by automated bots probing for weak passwords, exposed admin endpoints, and unpatched software. Fail2ban monitors log files for repeated failed authentication attempts and automatically adds firewall rules to block the offending IP address for a configurable duration. Unattended-upgrades automatically installs security patches for the operating system without administrator intervention, closing known vulnerability windows within hours of a CVE being published. These two tools together address different threat layers: Fail2ban stops brute-force attacks at the network level, while unattended-upgrades removes the software vulnerabilities those attacks would exploit. A Fail2ban jail consists of a filter — a set of regex patterns that detect failures in a specific log file — and a jail configuration that sets the ban threshold and duration. The [wordpress] jail monitors the Nginx or Apache access log for repeated POST /wp-login.php requests returning HTTP 200 (incorrect credentials) or 403 responses from other security rules. The bantime, findtime, and maxretry parameters balance false positive risk against security — five retries in ten minutes with a 24-hour ban is a common starting point for production sites. The recidive jail is a meta-jail that watches the Fail2ban log itself and applies a much longer ban to IPs that have been banned multiple times, discouraging persistent attackers. Fail2ban actions can extend beyond firewall rules — the sendmail action delivers an email notification for each ban, which is useful for monitoring during the initial deployment period. The XML-RPC and login protection post covers the application-level rules that complement Fail2ban’s network-level banning. The Nginx caching guide explains the access log format that Fail2ban parses — the log path and format must match the logpath setting in the jail configuration. After enabling unattended-upgrades, confirm it is working with unattended-upgrade --dry-run --debug before relying on it in production.
Problem: WordPress servers without automated brute-force protection and OS patch management are vulnerable to credential attacks and known software vulnerabilities that accumulate without manual intervention.
Solution: Install Fail2ban and configure a WordPress-specific jail that bans IPs after repeated login failures, then enable unattended-upgrades to automatically apply OS security patches.
# Install both tools
# apt install fail2ban unattended-upgrades
# /etc/fail2ban/filter.d/wordpress.conf
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
^<HOST> .* "POST /xmlrpc.php
ignoreregex =
# /etc/fail2ban/jail.d/wordpress.conf
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 86400
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = iptables-allports
bantime = 604800
findtime = 86400
maxretry = 3
# Reload Fail2ban and check status:
# fail2ban-client reload
# fail2ban-client status wordpress
# /etc/apt/apt.conf.d/50unattended-upgrades (key lines)
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
NOTE: Set Automatic-Reboot "false" in the unattended-upgrades config — kernel updates that require a reboot should be applied during a scheduled maintenance window, not automatically, to avoid unexpected downtime for a running WordPress site.