---

Alias: ["Fail2ban", "fail2ban"]
Tag: ["Computer", "Server", "Monitoring"]
Date: 2022-03-17
DocType: "Personal"
Hierarchy: "NonRoot"
TimeStamp:
location: [47.3639129,8.55627491017841]
CollapseMetaTable: Yes

---

Parent:: [[Selfhosting]], [[Server Alias]], [[Server Cloud]], [[Server Tools]], [[Server VPN]]

---

 ^Top
 
&emsp;

```button
name Save
type command
action Save current file
id Save
```
^button-ConfiguringFail2banNSave

&emsp;

# Configuring Fail2ban

&emsp;

```ad-abstract
title: Summary
collapse: open
This note runs through [fail2ban](https://www.fail2ban.org), a free open-source tool to monitor running programs and deamons on a VPs.
```

&emsp;

```toc
style: number
```

&emsp;

---

&emsp;

### Installing Fail2Ban
[[#^Top|TOP]]
&emsp;

Type the following over command line and hit enter to begin installing Fail2Ban:

```ad-command
~~~bash
sudo apt-get install fail2ban
~~~
```

&emsp;

That will install the software for you however, by default Fail2Ban is only configured to ban failed SSH login attempts. For it to work more effectively, we need to enable some additional rules that will check the webserver or mtc logs for patterning indicating malicious activity.

&emsp;

---

&emsp;

### Modifying the general settings in Fail2Ban
[[#^Top|TOP]]
&emsp;

First, we need to modify the configuration file that Fail2Ban uses to determine which application logs should be monitored, and what actions should be taken when offending entries are identified. 

For this you can use the supplied `/etc/fail2ban/jail.conf` file.

We must first however, copy this file over to prevent changes being overwritten if a package updated changes the default file.

To copy the default configuration file to a new file, named `/etc/fail2ban/jail.local`, use the following command:

```ad-command
~~~bash
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
~~~
```

&emsp;

Now we can open the newly copied file in order to set up the Apache log monitoring:

```ad-command
~~~bash
sudo nano /etc/fail2ban/jail.local
~~~
```

&emsp;

#### Adjusting the default settings
[[#^Top|TOP]]
The first thing to look at within the configuration file are the defaults, which are found under the `[DEFAULT]` section within the file. These items set the general policy, and all of them can be individually overridden in specific jails.

Here there are a few options you may want to configure, depending on your requirements.

A common option to change is the ***`ignoreip`*** setting. This allows you to specify an IP address that Fail2Ban should ignore, and not ban under any circumstances. It can be helpful to add your own IP address or network to this list to avoid locking yourself out! To add an IP address, just append it to the line separated by a space, and make sure that the line is uncommented.

Another item you may want to change is the ***`bantime`*** setting. This setting determines how long an offending IP address will be banned from the system for. Ideally, you want to set this to a long enough time to be effective at dissuading malicious parties, but also short enough to allow legitimate users to correct their mistakes and access the system.

The final two items to look at are the ***findtime*** and ***`maxretry`*** settings. The ***`findtime`*** item specifies an amount of time, and the ***`maxretry`*** item indicates the number of login attempts that will be tolerated within that time period. If a client attempting to access the system makes more than ***`maxtry`*** attempts within the amount of time set by ***`findtime`***, Fail2Ban will ban them.

&emsp;

---

&emsp;

### Configuring with a MTA
[[#^Top|TOP]]
&emsp;

#### Postfix

In order to monitor [[Configuring Postfix|Postfix]]'s SMTP connections through Fail2Ban, a few steps need to be taken.

1. Open the conf file

```ad-path
~~~bash
/etc/fail2ban/jail.conf
~~~
Or
~~~bash
/etc/fail2ban/jail.local
~~~
```

&emsp;

2. Edit Postfix & create Postfix-auth

```ad-code
~~~bash
[postfix]
enabled = true
maxretry = 3
bantime = 1h
filter  = postfix
mode    = aggressive
action  = iptables-multiport[name=postfix, port="http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve", protocol=tcp]
	telegram
port    = smtp,465,submission
logpath = %(postfix_log)s
backend = %(postfix_backend)s

[postfix-auth]
enabled  = true
bantime  = 1h
filter   = postfix.auth
action   = iptables-multiport[name=postfix, port="http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve", protocol=tcp]
        telegram
logpath  = /var/log/mail.log
ignoreip = 127.0.0.1/8
maxretry = 3
~~~
```

&emsp;

3. Create postfix.auth filter

```ad-path
/etc/fail2ban/filter.d/postfix.auth.conf
```

&emsp;

```ad-code
~~~bash
[Definition]
failregex = lost connection after AUTH from (.*)\[<HOST>\]
ignoreregex =
~~~
```

&emsp;

4. Restart fail2ban

```ad-command
~~~bash
sudo systemctl restart fail2ban
~~~
```

&emsp;

---

&emsp;

### Configuring with a webserver
[[#^Top|TOP]]
&emsp;

#### Apache

This section focusses on enabling the Apache-specific jails that will monitor the logs of our web server for specific behaviour patterns, which it can then act upon.

Each jail within the configuration file is marked by a header, containing the jail name in square brackets.

1. Open the conf file

```ad-path
~~~bash
/etc/fail2ban/jail.conf
~~~
Or
~~~bash
/etc/fail2ban/jail.local
~~~
```

&emsp;

2. Add the following code

```ad-code
~~~bash
# detect password authentication failures
 [apache]
 enabled  = true
 filter   = apache-auth
 action   = iptables-multiport[name=auth, port="http,https"]
 logpath  = /var/log/httpd/fail2ban.log
 bantime  = 3600
 maxretry = 3
 ignoreip = 192.0.2.0

 # detect spammer robots crawling email addresses
 [apache-badbots]
 enabled  = true
 filter   = apache-badbots
 action   = iptables-multiport[name=badbots, port="http,https"]
 logpath  = /var/log/httpd/fail2ban.log
 bantime  = 3600
 maxretry = 1
 ignoreip = 192.0.2.0

 # detect potential search for exploits
 [apache-noscript]
 enabled  = true
 filter   = apache-noscript
 action   = iptables-multiport[name=noscript, port="http,https"]
 logpath  = /var/log/httpd/fail2ban.log
 bantime  = 3600
 maxretry = 6
 ignoreip = 192.0.2.0

 # detect Apache overflow attempts
 [apache-overflows]
 enabled  = true
 filter   = apache-overflows
 action   = iptables-multiport[name=overflows, port="http,https"]
 logpath  = /var/log/httpd/fail2ban.log
 bantime  = 3600
 maxretry = 2
 ignoreip = 192.0.2.0 
~~~
```

&emsp;

**NOTE**: make sure to substitute your own static IP address for “192.0.2.0” in the ***`ignoreip`*** field..

&emsp;

3.  Save and close the file, then restart Fail2Ban for the changes to take effect:

```ad-command
~~~bash
sudo systemctl restart fail2ban
~~~
```

&emsp;

Now you can use the following command to check the firewall rules added by Fail2Ban:

```ad-command
~~~bash
sudo iptables -L
~~~
```

&emsp;

You should see something like the following:

```ad-code
~~~bash
Chain fail2ban-apache (1 references) 
  target prot opt source destination 
  RETURN all -- anywhere anywhere
  Chain fail2ban-apache-badbots (1 references) 
  target prot opt source destination 
  RETURN all -- anywhere anywhere
  Chain fail2ban-apache-noscript (1 references) 
  target prot opt source destination 
  RETURN all -- anywhere anywhere
  Chain fail2ban-apache-overflows (1 references) 
  target prot opt source destination 
  RETURN all -- anywhere anywhere 
~~~
```

&emsp;

#### NGINX
[[#^Top|TOP]]
This section focusses on enabling the NGINX-specific jails that will monitor the logs of our web server for specific behaviour patterns, which it can then act upon.

Each jail within the configuration file is marked by a header, containing the jail name in square brackets.

1. Edit the conf file

```ad-command
~~~bash
sudo nano /etc/fail2ban/jail.conf
~~~
```

&emsp;

2. Now, copy and paste which jails you prefer to use, remember to see the next section for the actual filter.

```ad-code
~~~bash
[nginx-403]
 enabled = true
 port     = http,https
 filter = nginx-403
 action = iptables-allports
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 4

[nginx-404]
 enabled = true
 port     = http,https
 filter = nginx-404
 action = iptables-allports
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 30 # <--- monitor and adjust, all servers are different.

[nginx-noagent]
 enabled = true
 port     = http,https
 filter = nginx-noagent
 action = iptables-allports
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 3

[nginx-noauth]
 enabled = true
 filter = nginx-noauth
 action = iptables-allports
 logpath = %(nginx_error_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 5

[nginx-no-x-spam]
 enabled = true
 filter = nginx-no-x-spam
 action = iptables-allports
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 5

[nginx-noscript]
 enabled = true
 action = iptables-allports
 filter = nginx-noscript
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 3

[nginx-noproxy]
 enabled = true
 action = iptables-allports
 filter = nginx-noproxy
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 0

[nginx-nowordpress]
 enabled = true
 action = iptables-allports
 filter = nginx-nowordpress
 logpath = %(nginx_access_log)s
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 3

[portscan-block]
 enabled = true
 action = iptables-allports
 filter = portscan-block
 logpath = /var/log/ufw.log  <--- this has to be direct to your UFW logs.
 bantime = 1440m # 1 day
 findtime = 1440m # 1 day
 maxretry = 5

~~~
```

&emsp;

3. Next, you need to make a new filter file for each of these filters and put ***.conf*** at the end of the file.

**Note, the created file is something you need to do yourself.**

&emsp;

###### nginx-403 configuration
[[#^Top|TOP]]
```ad-path
/location/fail2ban/filter.d/nginx-403.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 403

 ignoreregex =
~~~
```

&emsp;

###### nginx-404 configuration

```ad-path
/location/fail2ban/filter.d/nginx-404.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404

 ignoreregex =

~~~
```

&emsp;

###### nginx-noagent configuration

```ad-path
/location/fail2ban/filter.d/nginx-noagent.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

 failregex = ^<HOST> -.*"-" "-"$
                   ^<HOST> -.*"-" "curl.*"$

 ignoreregex =

~~~
```

&emsp;

###### nginx-noauth configuration
[[#^Top|TOP]]
```ad-path
/location/fail2ban/filter.d/nginx-noauth.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

 failregex = no user/password was provided for basic authentication.client:              user . was not found in.client:              user . password mismatch.*client: 

 ignoreregex =
~~~
```

&emsp;

###### nginx-no-x-spam configuration

```ad-path
/location/fail2ban/filter.d/nginx-no-x-spam.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

 failregex = {"log":"<HOST> .* ".*\\x.*" .*$

 ignoreregex =
~~~
```

&emsp;

###### nginx-noscript configuration

```ad-path
/location/fail2ban/filter.d/nginx-noscript.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

 failregex =     ^<HOST> -.*GET.*(\.asp|\.exe|\.pl|\.cgi|\.scgi)

 ignoreregex =
~~~
```

&emsp;

###### nginx-noproxy configuration
[[#^Top|TOP]]
```ad-path
/location/fail2ban/filter.d/nginx-noproxy.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]

 failregex = ^<HOST> -.*GET http.*
                   ^<HOST> -.*CONNECT.*

 ignoreregex =
~~~
```

&emsp;

###### nginx-nowordpress configuration

```ad-path
/location/fail2ban/filter.d/nginx-nowordpress.conf
```

&emsp;

```ad-code
~~~bash
 [Definition]
            
 failregex = ^<HOST> -.*"(GET|POST|HEAD) /+(?i)(wp(-|/)|xmlrpc.php|\?author=1)
                   ^<HOST> -.* "(GET|POST|HEAD|PROPFIND) /+(?i)    (a2billing|admin|apache|axis|blog|cfide|cgi|cms|config|etc|.git|hnap|inc|jenkins|jmx-|joomla|lib|linuxsucks|msd|muieblackcat|mysql|myadmin|n0w|owa-autodiscover|pbxip|pma|recordings|sap|sdk|script|service|shell|sqlite|vmskdl44rededd|vtigercrm|w00tw00t|webdav|websql|wordpress|xampp|xxbb)
             ^<HOST> -.* "(GET|POST|HEAD) /[^"]+.(asp|cgi|exe|jsp|mvc|pl)( |\?)
             ^<HOST> -.*(?i)(/bash|burger-imperia|changelog|hundejo|hvd-store|jorgee|masscan|pizza-imperia|pizza-tycoon|servlet|testproxy|uploadify)

 ignoreregex =

 journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

~~~
```

&emsp;

###### portscan-block configuration

```ad-path
/location/fail2ban/filter.d/portscan-block.conf
```

&emsp;

```ad-code
~~~bash
[Definition]

failregex = .*\[UFW BLOCK\] IN=.* SRC=<HOST>

ignoreregex = SRC=(10.|172.1[6-9].|172.2[0-9].|172.3[0-1].|192.168.|fe\w:). DST=(static.ip.address.here|224.0.0.). PROTO=(2|UDP)(\s+|.* DPT=(1900|3702|5353|5355) LEN=\d*\s+)$

~~~
```

&emsp;

4. Save and close the file, then restart Fail2Ban for the changes to take effect:

```ad-command
~~~bash
sudo systemctl restart fail2ban
~~~
```

&emsp;

#### Caddy
[[#^Top|TOP]]
This section focusses on enabling the [[Configuring Caddy|caddy]]-specific jails that will monitor the logs of our web server for specific behaviour patterns, which it can then act upon.

Each jail within the configuration file is marked by a header, containing the jail name in square brackets.

1. Open the conf file

```ad-path
~~~bash
/etc/fail2ban/jail.conf
~~~
Or
~~~bash
/etc/fail2ban/jail.local
~~~
```

&emsp;

2. Add the following code

```ad-code
~~~bash
[caddy-4xx]
port    = http,https
logpath = /var/log/caddy/caddy.log
enabled = true
filter = caddy-4xx
action = iptables-multiport[name=auth, port="http,https"]
banTime = 3600
findTime = 600
maxretry = 5
~~~
```

&emsp;

3. Create the filter file

```ad-path
/etc/fail2ban/filter.d/caddy-4xx.conf
```

&emsp;

```ad-code
~~~bash
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" (404|444|403|400) .*$
ignoreregex =
~~~
```

&emsp;

4. Save and close the file, then restart Fail2Ban for the changes to take effect:

```ad-command
~~~bash
sudo systemctl restart fail2ban
~~~
```

&emsp;

---

&emsp;

### Test fail2ban filters
[[#^Top|TOP]]
&emsp;

Fail2ban allows to test filters on a defined logfile through the below command. This enables to test filters when occurences are present in the log.

```ad-command
~~~bash
sudo fail2ban-regex < path to logfile > < filter name >
~~~
```

[[#^Top|TOP]]

&emsp;
&emsp;