Skip to main content

Getting started with Fail2Ban on Linux

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.


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


 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.

# 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.:
# 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 #



# "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



#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 = ::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.

loglevel = INFO
the default level is INFO

Status & Logging #

After starting the service, you can check the current status with:
sudo fail2ban-client status
sudo fail2ban-client 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:

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:

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 - 2023-08-04 09:16:44
2023-08-04 09:21:53,547 fail2ban.filter         [2144579]: INFO    [sshd] Found - 2023-08-04 09:21:53
2023-08-04 09:27:03,055 fail2ban.filter         [2144579]: INFO    [sshd] Found - 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.

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:

Another method would be to show all banned hosts in all jails.

sudo fail2ban-client banned
[{'sshd': []}, {'perm': ['']}]

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.

sudo iptables -nL
Chain f2b-sshd (1 references)
target     prot opt source               destination         
REJECT     all  --            reject-with icmp-port-unreachable
RETURN     all  --             

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

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:

sudo fail2ban-client -vvv set sshd banip

 +   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/, [INFO] logging to /var/log/fail2ban.log
 +   65 7F1DE7AAE1C0 fail2ban                  HEAVY CMD: ['set', 'sshd', 'banip', '']
 +  151 7F1DE7AAE1C0 fail2ban                  HEAVY OK : 1
 +  151 7F1DE7AAE1C0 fail2ban.beautifier       HEAVY Beautify 1 with ['set', 'sshd', 'banip', '']
 +  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.

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 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!


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.

E-Mail hellofoo@ittafoovern.comcom

More reading: