Running WordPress on a VPS gives you full control over server configuration but also full responsibility for its security. Two tools that every WordPress server administrator should deploy immediately after provisioning are UFW (Uncomplicated Firewall) and fail2ban. UFW is a front end to iptables that lets you define allow and deny rules with simple commands, exposing only the ports your server genuinely needs: SSH, HTTP, and HTTPS. fail2ban watches log files for repeated failed authentication attempts and automatically bans the offending IP addresses via iptables rules, making brute-force attacks against your SSH and WordPress login endpoint far less effective. Together they form a practical first line of defence that takes less than ten minutes to configure. You should combine both with the application-level login protection described in an earlier guide. This article walks through enabling UFW with the minimum required ports, verifying the rule set, installing fail2ban, and writing a custom jail for the WordPress xmlrpc.php and wp-login.php endpoints. All commands assume Ubuntu 20.04 LTS or later and a non-root sudo user. The configuration is intentionally minimal; you should adjust the bantime and maxretry values to match your site’s traffic volume. Remember that locking yourself out of SSH is the most common mistake: always allow port 22 before enabling UFW. Pair this setup with the HTTP security headers guide for defence in depth.
Problem: Your WordPress VPS is exposed to brute-force attacks on SSH and the login endpoint and you need to block malicious IPs automatically without complex firewall rules.
Solution: Enable UFW to allow only SSH, HTTP, and HTTPS, then configure a fail2ban jail that watches your web server access log and bans offending IPs:
# 1. Install and enable UFW
sudo apt update && sudo apt install ufw -y
# Allow SSH before enabling to avoid lockout
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable the firewall (answer 'y' at the prompt)
sudo ufw enable
sudo ufw status verbose
# 2. Install fail2ban
sudo apt install fail2ban -y
# 3. Create a local override file (do NOT edit jail.conf directly)
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = auto
[sshd]
enabled = true
port = ssh
[wordpress-auth]
enabled = true
port = http,https
filter = wordpress-auth
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 24h
EOF
# 4. Create the WordPress filter
sudo tee /etc/fail2ban/filter.d/wordpress-auth.conf << 'EOF'
[Definition]
failregex = ^<HOST> .* "POST /wp-login\.php
^<HOST> .* "POST /xmlrpc\.php
ignoreregex =
EOF
# 5. Restart fail2ban and verify
sudo systemctl restart fail2ban
sudo fail2ban-client status wordpress-auth
NOTE: The logpath above assumes Nginx; for Apache change it to /var/log/apache2/access.log. If your server is behind Cloudflare or another reverse proxy, the logged IP will be the proxy IP, not the real visitor — configure mod_remoteip (Apache) or the real_ip module (Nginx) so that the real IP is logged before fail2ban reads the file. Also review the backup automation guide so that you have a recovery snapshot before making firewall changes.