Fail2ban is a complementary tool to your firewall. It works by scanning log files and bans IPs which present suspicious activity such as failed logins. It is compatible with many UNIX-like systems and is a security tool to have in your arsenal. It can filter not only ssh logins, but other services too, for example CMS web sites as WordPress or Drupal, repositories such as your own GitLab, and even your Postfix (or other) mail server.
In this how to install Fail2ban on FreeBSD I will just cover two services to protect SSH connections. There is much more to read and enjoy from the official project’s documentation. But first of all some of you, as I did quite some time ago now, may be asking a simple question. Why? Why do I need such a tool since I already have a firewall in place. The answer is similar to the one I gave on the firewall article, people, bots trying to reach your server, your device. Not only to steal information (which may be irrelevant and useless) but to use your computer, your computer’s identity, power, etc.
If you find the articles in Adminbyaccident.com useful to you, please consider making a donation.
Use this link to get $200 credit at DigitalOcean and support Adminbyaccident.com costs.
Get $100 credit for free at Vultr using this link and support Adminbyaccident.com costs.
Mind Vultr supports FreeBSD on their VPS offer.
If you ever logged in to the router web page at home you may have already visited the corner where the failed login attempts are logged. If you’ve never done that you can click on this link and look at the picture I placed for the failed logins in a firewall I had a couple or years ago. Nowadays you put a device connected to the internet and it seems like the world wants to get inside of it and tear it apart. And no, there is not a legion of people manually trying to get into your home’s or office’s network.
People has programmed bots to do that in a big scale and automatically for them, only reporting the successful logins. Bots which are also equipped with dictionaries of usernames and passwords. Those who have been stolen in very notorious intrusions and their creators collected in the black market. Why? People repeat passwords. If one password is used here it may well be used somewhere else. Malicious actors know this and this is the reason you see “people” knocking at your server saying they are the admin user or even john and their password is bla bla bla.
Fail2ban prevents brute force attacks by banning the failed login IPs. You can determine the services to filter, the max failed login attempts prior to banning, the time the IP will be banned, etc. And that will be automatically written in your firewall configuration, be it whatever you may be using, from the Linux Iptables, IPFW from FreeBSD, PF which is used in FreeBSD, comes from OpenBSD but used in macOS and Solaris. Name a firewall and probably
So here we are on this server which already happens to have a full WordPress site. If you want to do that install there’s a guide already. Don’t forget the SSL/TLS bits. It is not necessary for what we’re doing though.
This is our FreeBSD server and uname makes the testimony.
test@host:~ % uname -a
FreeBSD host 11.2-RELEASE-p2 FreeBSD 11.2-RELEASE-p2 #0: Tue Aug 14 21:45:40 UTC 2018 [email protected]:/usr/obj/usr/src/sys/GENERIC amd64
test@host:~ %
Let’s look for the package we are needing.
test@host:~ % pkg search fail2ban
py27-fail2ban-0.10.1_1 Scans log files and bans IP that makes too many password failures
py36-fail2ban-0.10.1_1 Scans log files and bans IP that makes too many password failures
test@host:~ %
There are two versions, one running on Python2 and another one on Python3. Choose your poison. I will select the latter but both work the same.
test@host:~ % sudo pkg install py36-fail2ban-0.10.3.1_1
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 4 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
py36-fail2ban: 0.10.3.1_1
python36: 3.6.6_1
py36-setuptools: 40.0.0
py36-sqlite3: 3.6.6_7
Number of packages to be installed: 4
The process will require 108 MiB more space.
16 MiB to be downloaded.
Proceed with this action? [y/N]: y
.......
some amount of output
test@host:~ %
Now the thing is installed. Let’s tackle the first goal which is protecting the SSH service. In this scenario I am using IPFW firewall. Here is a simple example of setting it up. Others will use PF and it doesn’t work very differently for Fail2ban.
In Fail2ban there is a directory named jail.d (not to be confused with FreeBSD jails) where you set the services you want to protect. We will create our configuration file.
test@host:~ % sudo vi /usr/local/etc/fail2ban/jail.d/ssh-ipfw.local
We’ll add the following rules:
[ssh-ipfw]
enabled = true
filter = sshd
action = ipfw[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
findtime = 600
maxretry = 3
bantime = 3600
And now, what to they mean?
First we state the service and the firewall type. And of course we say it is on. Then we state what to filter and our answer is the ssh daemon. After that we tell it what actions to take, and that is based on the ipfw firewall, the name of the service, the port and the protocol. Once this is set the path to the log to check comes next. We give it a time to play, a maximum attempts to successfully login and how many seconds the IP will be banned in case it fails to provide the credentials.
After this we will configure the main file for our firewall type by giving the localhost sentence the real IP we are using.
To check our IP as always issue this command:
ifconfig | grep inet
In this particular case this is the output:
test@host:~ % ifconfig | grep inet
inet 192.168.1.105 netmask 0xffffff00 broadcast 192.168.1.255
test@host:~ %
Now it’s time to set the localhost address correctly:
test@host:~ % sudo vi /usr/local/etc/fail2ban/action.d/ipfw.conf
At the end of the file you will encounter the localhost entry. Just change the IP numbers.
localhost = 192.168.1.105
It is time to edit the rc.conf file so Fail2ban starts as a service every time we boot the server. You can manually edit the file or issue this command:
test@host:~ % sudo sysrc fail2ban_enable="YES"
fail2ban_enable: -> YES
test@host:~ %
Let’s fire up the service.
test@host:~ % sudo service fail2ban onestart
Server ready
test@host:~ %
Now, grab another machine or account and try to login to the server you are protecting with a user that does not exist. Do it several times, more than 3 since that is the max login attempts we set in our configuration.
test@T430:~$ ssh [email protected]
[email protected]: Permission denied (publickey).
test@T430:~$ ssh [email protected]
[email protected]: Permission denied (publickey).
test@T430:~$ ssh [email protected]
[email protected]: Permission denied (publickey).
test@T430:~$ ssh [email protected]
[email protected]: Permission denied (publickey).
test@T430:~$
Fail2ban has a client program and after hitting and making one not existent user fail you will see an entry similar to this:
test@host:~ % sudo fail2ban-client status ssh-ipfw
Status for the jail: ssh-ipfw
|- Filter
| |- Currently failed: 1
| |- Total failed: 29
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 192.168.1.102
test@host:~ %
As you can see I’ve failed 29 times. I did it using a non existent user called “test” and now the IP which was related to that activity appears as banned. For 3600 seconds, which is one exact hour. You can increase that to whatever the ban time you want. Be aware that if you are connecting to your server using passwords instead of keys (an idea I wouldn’t recommend, so please use keys), and you forget the password and hit the ban list if you’ve set a very long ban time, you will have to wait that amount of time. Get the keys by reading this article here.
If by issuing some other commands such as netstat or reading your access logs there is a particular IP you want to ban manually without waiting you can issue the following command.
test@host:~ % sudo fail2ban-client set ssh-ipfw banip 192.168.1.106
192.168.1.106
test@host:~ %
And now you can recheck the ban status. As you can see there is a second banned IP.
test@host:~ % sudo fail2ban-client status ssh-ipfw
Status for the jail: ssh-ipfw
|- Filter
| |- Currently failed: 0
| |- Total failed: 30
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 192.168.1.102 192.168.1.106
test@host:~ %
As the ones who read me regularly know I am a big fan of FreeBSD jails. You can click on the link or if you don’t have the time think about them like the Docker of Linux but in FreeBSD land and with many more features and maturity. If you are using Fail2ban you will have to set it up on the host, not inside the jail. As you may be already aware this is also how the firewall has to be setup. If you are using FreeBSD jails the main difference when configuring Fail2ban is the logpath setting.
People using iocage as it is my case for managing jails their logpath should be similar to this:
/iocage/jails/jailname.example/root/var/log/auth.log
People using ezjail, which is another awesome tool for jails management their logpath should be similar to this other one:
/usr/jails/jailname.example/var/log/auth.log
This is all for this how to install Fail2ban on FreeBSD guide. If you need more information do not hesitate to check the official documentation. I hope this has been useful for you.
If you find the articles in Adminbyaccident.com useful to you, please consider making a donation.
Use this link to get $200 credit at DigitalOcean and support Adminbyaccident.com costs.
Get $100 credit for free at Vultr using this link and support Adminbyaccident.com costs.
Mind Vultr supports FreeBSD on their VPS offer.