Using fail2ban with iptables instead of firewalld

In the previous post I wrote about the minor configuration changes needed to get fail2ban to actually do something.

I have been working primarily with CentOS 7 and have been using iptables instead of firewalld. Normally, fail2ban works with iptables by default. However, installing fail2ban on CentOS 7 also installs fail2ban-firewalld — which changes that default. Even with a properly configured fail2ban jail, you will not see the expected results. fail2ban will log events as expected, but no traffic will actually be banned.

The fail2ban-firewalld package places a file in /etc/fail2ban/jail.d/00-firewalld.conf. It overrides the default banaction (iptables) and sets it to firewallcmd-ipset.

The top of the 00-firewalld.conf file says:

You can remove this package (along with the empty fail2ban meta-package) if you do not use firewalld

When I tried removing fail2ban-firewalld, it removed fail2ban as a dependency. I have a feeling the referenced fail2ban meta-package may have something to so with that.

I have not yet investigated the meta-package and de-coupling fail2ban-firewalld from fail2ban (see Update below). My solution, for now, has been to move 00-firewalld.conf and restart fail2ban:

$ sudo mv /etc/fail2ban/jail.d/00-firewalld.conf /etc/fail2ban/jail.d/00-firewalld.disabled
$ sudo systemctl restart fail2ban

The default banaction defined in jail.conf is no longer overridden and performs as expected:
banaction = iptables-multiport

Update
According to Fail2ban with FirewallD, The fail2ban package itself is a meta-package that contains several other packages, including fail2ban-firewalld and fail2ban-server. Removing the meta-package will not remove fail2ban-server.

If you’ve already moved 00-firewalld.conf to 00-firewalld.disabled, you’ll get a warning:
warning: file /etc/fail2ban/jail.d/00-firewalld.conf: remove failed: No such file or directory

You can ignore the warning, or remove 00-firewalld.disabled.

fail2ban fails to ban SSH login failures

fail2ban is one of those magical programs that, in my experience, just works. I’ve inherited many systems with a working fail2ban configuration, and therefore I didn’t know much about configuring it or troubleshooting it.

Summary: by default, fail2ban on CentOS 7 does absolutely nothing!

One of the things that it is reported (falsely!) to do out-of-the-box is to block repeated SSH login failures. According to Protecting SSH with Fail2ban:

Fail2ban should now protect SSH out of the box. If Fail2ban notices six failed login attempts in the last ten minutes, then it blocks that IP for ten minutes.

I wanted to test this, so I set up 2 virtual machines, a victim and an attacker.

On the victim VM:
[ariel]# sudo yum install epel-release
[ariel]# sudo yum install fail2ban
[ariel]# sudo systemctl start fail2ban
[ariel]# sudo tail -f /var/log/fail2ban

On the attacker VM:
[caliban]# sudo yum install epel-release
[caliban]# sudo yum install sshpass
[caliban]# for i in `seq 1 100`; do sshpass -p 'TopSecret!' admin@ariel; done

And then I waited. And waited. And waited.

I confirmed that the defaults described matched what was in my /etc/fail2ban/jails.conf (excerpted):
bantime = 600
findtime = 600
maxretry = 5

In my test, I definitely exceeded that: about 30 failed attempts in 5 minutes. The failures appear in /var/log/secure, but nothing appears in /var/log/fail2ban.log!

From How To Protect SSH With Fail2Ban on CentOS 7 I found the fail2ban-client status command:

[ariel]# fail2ban-client status
Status
|- Number of jail: 0
`- Jail list:

Zero jails! That’s definitely a problem.

As mentioned in the above, I created a file, /etc/fail2ban/jail.local containing the following:
[sshd]
enabled = true

New results:
[ariel]# systemctl restart fail2ban
[ariel]# fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd

That looks better! /var/log/fail2ban.log now has new entries, and the attacker IP address has been banned! Just to confirm I tried to SSH to the machine from the attacker:

[caliban]# ssh admin@ariel
ssh_exchange_identification: Connection closed by remote host

Great! Exactly what I expected to happen.

When I look at the /etc/fail2ban/jails.conf, I do not see enabled = true under the [sshd] section. In fact, part of that file explains that all jails are disabled by default:

# "enabled" enables the jails.
# By default all jails are disabled, and it should stay this way.
# Enable only relevant to your setup jails in your .local or jail.d/*.conf
#
# true: jail will be enabled and log files will get monitored for changes
# false: jail is not enabled
enabled = false

On CentOS 7, fail2ban is configured to work with firewalld. My next post describes using fail2ban with iptables on CentOS 7.