4 Fail2Ban and Docker
pixel::doc edited this page 2025-01-10 00:03:44 +01:00

There are so many tutorials, most inaccurate, regarding best practices with Fail2Ban and Docker environments. Some will suggest running duplicate Fail2Ban instances, while others will tell you to change the default chain across the board to DOCKER-USER. Both of these are bad ideas. Let's look at them both.

Running Duplicate Fail2Ban instances:

The idea that you want more server resources used just to accomplish what is a relatively simple task is a bit silly. A single Fail2Ban instance can protect your entire server and there is no need for duplicate instances.

Changing the default chain to DOCKER-USER:

While this will protect your docker based software, it will leave any bare metal services wide open (i.e. SSH and often FTP). Again, bad idea (if you would not set the chain for every such a jail to INPUT).

The correct way to consider your server protection:

When you are running both bare metal and Docker based software, you should use the jail.local file to custom configure each jail independently. This way, not only can you provide a specific name for each chain (i.e. f2b-<name>, where by default <name> is name of jail), which will separate out the banned IP addresses depending on the used banaction, but you can also set the chain option to specify the chain of iptables or nftables in which it should reside.

Let's look at SSH running on the host, and Apache running in a Docker container. The only items of note here are the chain entries.

Remember, you can always manually unban an IP address across all jails with fail2ban-client unban IPADDR.

Edit your /etc/fail2ban/jail.local file with the following entries:

[DEFAULT]
chain = INPUT

[apache-auth]
enabled = true
logpath = /path/to/*error_log
chain = DOCKER-USER

[sshd]
enabled = true
# chain = INPUT by default

[pam-generic]
enabled = true
# chain = INPUT by default

With this configuration, any IP that is banned due to Apache will be placed in the f2b-apache-auth chain and that jump will be placed at the top of the DOCKER-USER chain. Likewise, any IP that is banned due to SSH or PAM will be placed in the f2b-sshd or f2b-pam-generic chains and that jump will be placed at the top of the INPUT chain.

Now you are directly protecting the services in which the attack is occurring, rather than trying to manage an all-in-one solution that will either tax your system resources OR not really offer you the protection you want/need.

Error: "iptables: No chain/target/match by that name" with Docker Host using iptables-legacy

Check if the Docker Container and the Docker Host are using the same iptables Version. Run iptables --version on the Docker Host and in the Docker Container.

If the Docker Host is using iptables-legacy, than you need to change the banaction in your fail2ban.local:

[DEFAULT]
banaction = iptables-multiport[iptables=iptables-legacy]

NOTE: UNRAID 6.12.14 as Docker Host is using iptables v1.8.9 (legacy) and the fail2ban 1.1.0 docker container is using iptables v1.8.10 (nf_tables) by default.