Step 1: Add a New Fail2ban Jail
Edit jail.local
file:
sudo nano /etc/fail2ban/jail.local
Add a new jail "wplogin" if it doesn't exist:
[wplogin]
enabled = true
port = http,https
filter = wplogin
chain = DOCKER-USER
logpath = /var/lib/docker/containers/*/*-json.log
banaction = docker-action
Note
This jail will use a new filter named wplogin
(we will create later) and use default settings to ban, which is my configuration:bantime = 604800
findtime = 100
maxretry = 2
means that if there is a failed attempt twice within 100 seconds, then the IP will be banned for 604800 seconds.
The log file for the Docker container to be monitored is located on the Docker host under /var/lib/docker/containers/<CONTAINERID>/<CONTAINERID>-json.log
Step 2: Create a Custom Fail2ban Filter
Create a new filter file on /etc/fail2ban/filter.d/wplogin.conf
[Definition]
failregex = {"log":"<HOST> -.*POST.*wp-login.php.*
ignoreregex =
Step 3: Create a Fail2ban action
Create a new action file: nano /etc/fail2ban/action.d/docker-action.conf
[Definition]
actionstart = iptables -N f2b-wplogin
iptables -A f2b-wplogin -j RETURN
iptables -I INPUT -p tcp -m multiport --dports 80,443 -j f2b-wplogin
actionstop = iptables -D INPUT -p tcp -m multiport --dports 80,443 -j f2b-wplogin
iptables -F f2b-wplogin
iptables -X f2b-wplogin
actioncheck = iptables -n -L INPUT | grep -q 'f2b-wplogin[ \t]'
actionban = iptables -I f2b-wplogin 1 -s <ip> -j DROP
actionunban = iptables -D f2b-wplogin -s <ip> -j DROP
After adding a new jail, filter, and action, Fail2ban should be restarted. Restart fail2ban with:
sudo systemctl stop fail2ban
sudo systemctl start fail2ban
Step 4: Let's try it out!
Like the other tutorials [nginx-auth, and mysql-auth], we need to test Fail2ban policies to ensure they block traffic as expected.
In order to test it, you need to:
- Install Docker Engine (docs)
- A docker-compose wordpress-mysql (gists)
- Nginx proxy, if you deployed WP on a different port

After the container was deployed, we can check the list of docker containers using:
root@server:~/wp# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c269ebb7a16 wordpress:latest "docker-entrypoint.s…" 12 minutes ago Up 12 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp wp-wordpress-1
5ece75d940d0 mariadb:10.6.4-focal "docker-entrypoint.s…" 12 minutes ago Up 12 minutes 3306/tcp, 33060/tcp wp-db-1
You can see my WP container ID is 9c269ebb7a16
Now, check the jail status with the following command:
root@server:~/wp# fail2ban-client status wplogin
Status for the jail: wplogin
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/lib/docker/containers/9c269ebb7a16e891383c388b7eeb21f6cdb01e803c33508ba39d6153991e9a5f/9c269ebb7a16e891383c388b7eeb21f6cdb01e803c33508ba39d6153991e9a5f-json.log
/var/lib/docker/containers/5ece75d940d06a39b0e7de6b65548080735982b1276bca19f802bbbea9851b2c/5ece75d940d06a39b0e7de6b65548080735982b1276bca19f802bbbea9851b2c-json.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
My Fail2ban log path/file list matches with my wp and mysql container.
Now open your wordpress site, and install wordpress as usual (like http://yourdomain.com/wp-admin/install.php) until you can log in on wp-login.php.
And the last step, let's try creating an error to trigger fail2ban jail.

List Blocked IP
To get a list of blocked IPs in your server, run the following command:
fail2ban-client status wplogin
Output
root@server:~/wp# fail2ban-client status wplogin
Status for the jail: wplogin
|- Filter
| |- Currently failed: 0
| |- Total failed: 6
| `- File list: /var/lib/docker/containers/6390d681392a6a38830f51e8fb5ea7e9c8c3a2fedc57383de3fe816f2d8838d6/6390d681392a6a38830f51e8fb5ea7e9c8c3a2fedc57383de3fe816f2d8838d6-json.log /var/lib/docker/containers/b344eed0327b7645da323249b8d44c5d19e403f87a441840d8da9301734dab13/b344eed0327b7645da323249b8d44c5d19e403f87a441840d8da9301734dab13-json.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 192.168.0.6
Unblock IP
To unblock banned IPs, run the following command
fail2ban-client set wplogin unbanip 192.168.0.6
Thanks for reading!
Reference:
- https://www.the-lazy-dev.com/en/install-fail2ban-with-docker/ (a bit inaccurate, fixed by fail2ban wiki)