I want to show you how to get started with Fail2Ban to keep your Linux servers more secure. For this blog post, I've used **Ubuntu 22.04 LTS** as a reference and will use it to secure my **SSH service** with **iptables** as the firewall. I assume that you already installed it on your system.
# General
Every internet-facing service will be attacked, and brute-forcing login attempts to gain access is one of the most common attacks you will encounter. Fail2Ban will follow certain rules and place any suspicious IP on the deny list of the firewall to minimize the risks.
In short:
: Fail2Ban checks logs > sees suspicious logs in reference to set rules > adds suspicious IP to the deny list of the firewall
: (jails > logs > filters > actions > configuration > firewall)
# Running Fail2Ban with systemd #
Make sure to systemd starts Fail2Ban automatically:
: `sudo systemctl enable fail2ban`
If you have never worked with Fail2Ban, it probably will be deactivated. You can check the status with:
`sudo systemctl status fail2ban`
Result:
```bash
○ fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:fail2ban(1)
```
It is currently not running!
You can start the Fail2Ban service with:
: `sudo systemctl start fail2ban`
After changes to the configuration, you have to restart the service with:
: `sudo systemctl restart fail2ban`
# Configuration file #
The **default configuration file** can be found in the `/etc/fail2ban/` directory and is called `jail.conf`. You can modify options within this file, create a new file called `jail.local` or create a new `*.conf` file in the `jail.d/` directory.
For this blog post, we'll create a **new configuration file** in the directory `jail.d/` called `custom.conf`:
`sudo cp jail.conf ./jail.d/custom.conf`
In the same file, it is stated **TO NOT customize** `jail.conf` and rather use the above-mentioned alternatives since the default file might get overwritten with upcoming updates.
```bash
# Changes: in most cases, you should not modify this
# file but provide customizations in jail.local file,
# or separate .conf files under jail.d/ directory, e.g.:
#
# YOU SHOULD NOT MODIFY THIS FILE.
#
# It will probably be overwritten or improved in a distribution update.
#
# Provide customizations in a jail.local file or a jail.d/customisation.local.
# For example to change the default bantime for all jails and to enable the
# ssh-iptables jail, the following (uncommented) would appear in the .local file.
# See man 5 jail.conf for details.
```
As you can see in this example, lines that begin with a `#` are getting ignored by Fail2Ban and won't change any configuration. This can be used for **comments** or **disabling options**.
Important is that you have to restart Fail2Ban after changes. If you run Fail2Ban with systemd, you can restart it with `sudo systemctl restart fail2ban`.
#### Configuration syntax #
**Example:**
```bash
[DEFAULT]
# "bantime" is the number of seconds that a host is banned.
bantime = 10m
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 10m
# "maxretry" is the number of failures before a host gets banned.
maxretry = 5
#
# JAILS
#
[sshd]
#mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
```
So, at the beginning of the configuration file, you can find the `[DEFAULT]` settings. Those apply to all `JAILS` if it is not overwritten within the `JAILS` configuration. Those `JAILS` are the services of which Fail2Ban checks the logs. In this example, the jail is the SSH server.
Important: you have to enable a jail by adding the following line:
: `enabled = true`
: that said, `sshd` is enabled by default
A jail requires the configurations segment, an action, and a filter. But this is beyond the scope of this blog post.
# Configurations #
I'll focus on the basics since Fail2Ban provides you with many options. You can check out the manual or default configuration for more options.
Adjust the length of the ban:
: `bantime = 10m` # *10 minutes is the default*
: you can change it to whatever time you want.
Rules for Fail2Ban when to set an IP on the ban list:
: `findtime = 10m`
: `maxretry = 5`
: this means if Fail2Ban finds 5 unsuccessful attempts to access a service within the last 10 minutes, the source host will be placed on the ban list for the duration of the configured `bantime`.
Exclude certain hosts from Fail2Ban:
: `ignoreip = 127.0.0.1/8 ::1`
: You can use IP addresses, networks with CIDR notation, or DNS hosts.
: By default, the loopback addresses are already excluded. You can add your trusted hosts.
: Multiple hosts or networks can be separated by using space and/or commas.
You can find more configuration options with `man jail.conf`.
Keep in mind to **restart Fail2Ban** after your changes!
#### Log level
You can set the verbosity of the logs with `loglevel` in the configuration.
Example:
: `loglevel = INFO`
: the default level is `INFO`
: your options are: ` CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG, TRACEDEBUG and HEAVYDEBUG`
# Status & Logging #
After starting the service, you can check the current status with:
: `sudo fail2ban-client status`
```bash
sudo fail2ban-client status
Status
|- Number of jails: 1
`- Jail list: sshd
```
This is a simple way to check what jails are active.
To get more information about one specific jail, simply add the name at the end like this:
```bash
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
```
#### Logs #
The Fail2Ban logs can be found `/var/log/fail2ban.log` here and look like the following example:
```bash
sudo tail /var/log/fail2ban.log
2023-08-04 09:11:46,772 fail2ban.filter [2144579]: INFO Added logfile: '/var/log/auth.log' (pos = 0, hash = 74ba42c53c7cf9f04857abd99b024ee7018ac4be)
2023-08-04 09:11:46,777 fail2ban.jail [2144579]: INFO Jail 'sshd' started
2023-08-04 09:16:44,756 fail2ban.filter [2144579]: INFO [sshd] Found 170.64.141.213 - 2023-08-04 09:16:44
2023-08-04 09:21:53,547 fail2ban.filter [2144579]: INFO [sshd] Found 170.64.141.213 - 2023-08-04 09:21:53
2023-08-04 09:27:03,055 fail2ban.filter [2144579]: INFO [sshd] Found 170.64.141.213 - 2023-08-04 09:27:03
```
#### Check what hosts are banned #
There are multiple ways to do so.
As previously shown, you can see the banned hosts of a certain jail.
```bash
sudo fail2ban-client status perm
Status for the jail: perm
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list:
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 170.64.141.213
```
---
Another method would be to **show all banned hosts in all jails**.
```bash
sudo fail2ban-client banned
[{'sshd': []}, {'perm': ['170.64.141.213']}]
```
If you want to search for a **single IP**, simply add it after 'banned' and only the jails containing this IP will be shown.
---
The third way would be to check it on the firewall itself.
```bash
sudo iptables -nL
[...]
Chain f2b-sshd (1 references)
target prot opt source destination
REJECT all -- 170.64.141.213 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
```
I bet there are way more ways to show your banned hosts, but those should be good enough for now.
# Banning or unbanning hosts manually
Sometimes you have to work on Fail2Ban manually.
#### Manually unbanning hosts #
It most likely will happen that Fail2Ban is one of your hosts. To **remove a host from the deny list**, just use the following command:
`sudo fail2ban-client set sshd unbanip 170.64.141.213`
You don't need to restart Fail2Ban after this command.
#### Manually banning hosts #
There might be a need to place hosts on a ban list. You can do it with the following command:
```bash
sudo fail2ban-client -vvv set sshd banip 170.64.141.213
+ 61 7F1DE7AAE1C0 fail2ban.configreader INFO Loading configs for fail2ban under /etc/fail2ban
+ 61 7F1DE7AAE1C0 fail2ban.configreader DEBUG Reading configs for fail2ban under /etc/fail2ban
+ 62 7F1DE7AAE1C0 fail2ban.configreader DEBUG Reading config files: /etc/fail2ban/fail2ban.conf
+ 63 7F1DE7AAE1C0 fail2ban.configparserinc INFO Loading files: ['/etc/fail2ban/fail2ban.conf']
+ 63 7F1DE7AAE1C0 fail2ban.configparserinc TRACE Reading file: /etc/fail2ban/fail2ban.conf
+ 64 7F1DE7AAE1C0 fail2ban.configparserinc INFO Loading files: ['/etc/fail2ban/fail2ban.conf']
+ 64 7F1DE7AAE1C0 fail2ban.configparserinc TRACE Shared file: /etc/fail2ban/fail2ban.conf
+ 65 7F1DE7AAE1C0 fail2ban INFO Using socket file /var/run/fail2ban/fail2ban.sock
+ 65 7F1DE7AAE1C0 fail2ban INFO Using pid file /var/run/fail2ban/fail2ban.pid, [INFO] logging to /var/log/fail2ban.log
+ 65 7F1DE7AAE1C0 fail2ban HEAVY CMD: ['set', 'sshd', 'banip', '170.64.141.213']
+ 151 7F1DE7AAE1C0 fail2ban HEAVY OK : 1
+ 151 7F1DE7AAE1C0 fail2ban.beautifier HEAVY Beautify 1 with ['set', 'sshd', 'banip', '170.64.141.213']
1
+ 151 7F1DE7AAE1C0 fail2ban DEBUG Exit with code 0
```
In this example, we use `-vvv` for more verbose output and place a random IP on the ban list for our `sshd` service.
You can check the ban list with `sudo fail2ban-client status sshd` or `sudo iptables -nL`.
**Important**: the length of the ban will depend on the `bantime` configured for the jail.
#### Permanently ban hosts #
From what I know, you can't ban hosts permanently. You could create a new jail with the same configurations as a reference jail and change the `bantime` to let's say, `999y` - I'd say 999 years is more or less permanent.
```bash
[perm]
enabled = true
port = ssh
filter = sshd
action = iptables-multiport[name=sshd, port="ssh", protocol=tcp]
bantime = 999y
```
You now can use `sudo fail2ban-client -vvv set perm banip 170.64.141.213` to ban a host for a long time.
# Testing your configuration #
That is probably the easiest part. Make sure you have access to the server, open the logs, and try to connect with the wrong credentials.
**Important**: just to make sure that you don't lose access to your remote machine!
# Conclusion
This blog post shows you how to get started with Fail2Ban. There are some more specific topics that I am going to write about later, like filters and actions to customize it even more for custom services or sending emails out as soon as an IP gets banned.
---
{{% contact %}}
---
**More reading:**
{{% post-list tags=ssh stop=5 %}}{{% /post-list %}}
{{% post-list stop=5 %}}{{% /post-list %}}