--- Alias: ["Fail2ban", "fail2ban"] Tag: ["💻", "🖥️", "🔎"] Date: 2022-03-17 DocType: "Personal" Hierarchy: "NonRoot" TimeStamp: location: [47.3639129,8.55627491017841] CollapseMetaTable: true --- Parent:: [[Selfhosting]], [[Server Alias]], [[Server Cloud]], [[Server Tools]], [[Server VPN]] --- ^Top   ```button name Save type command action Save current file id Save ``` ^button-ConfiguringFail2banNSave   # Configuring Fail2ban   ```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. ```   ```toc style: number ```   ---   ### Installing Fail2Ban [[#^Top|TOP]]   Type the following over command line and hit enter to begin installing Fail2Ban: ```ad-command ~~~bash sudo apt-get install fail2ban ~~~ ```   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.   ---   ### Modifying the general settings in Fail2Ban [[#^Top|TOP]]   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 ~~~ ```   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 ~~~ ```   #### 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.   ---   ### Configuring with a MTA [[#^Top|TOP]]   #### 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 ~~~ ```   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 ~~~ ```   3. Create postfix.auth filter ```ad-path /etc/fail2ban/filter.d/postfix.auth.conf ```   ```ad-code ~~~bash [Definition] failregex = lost connection after AUTH from (.*)\[\] ignoreregex = ~~~ ```   4. Restart fail2ban ```ad-command ~~~bash sudo systemctl restart fail2ban ~~~ ```   ---   ### Configuring with a webserver [[#^Top|TOP]]   #### 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 ~~~ ```   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 ~~~ ```   **NOTE**: make sure to substitute your own static IP address for “192.0.2.0” in the ***`ignoreip`*** field..   3. Save and close the file, then restart Fail2Ban for the changes to take effect: ```ad-command ~~~bash sudo systemctl restart fail2ban ~~~ ```   Now you can use the following command to check the firewall rules added by Fail2Ban: ```ad-command ~~~bash sudo iptables -L ~~~ ```   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 ~~~ ```   #### 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 ~~~ ```   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 ~~~ ```   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.**   ###### nginx-403 configuration [[#^Top|TOP]] ```ad-path /location/fail2ban/filter.d/nginx-403.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*"(GET|POST|HEAD).*HTTP.*" 403 ignoreregex = ~~~ ```   ###### nginx-404 configuration ```ad-path /location/fail2ban/filter.d/nginx-404.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*"(GET|POST|HEAD).*HTTP.*" 404 ignoreregex = ~~~ ```   ###### nginx-noagent configuration ```ad-path /location/fail2ban/filter.d/nginx-noagent.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*"-" "-"$ ^ -.*"-" "curl.*"$ ignoreregex = ~~~ ```   ###### nginx-noauth configuration [[#^Top|TOP]] ```ad-path /location/fail2ban/filter.d/nginx-noauth.conf ```   ```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 = ~~~ ```   ###### nginx-no-x-spam configuration ```ad-path /location/fail2ban/filter.d/nginx-no-x-spam.conf ```   ```ad-code ~~~bash [Definition] failregex = {"log":" .* ".*\\x.*" .*$ ignoreregex = ~~~ ```   ###### nginx-noscript configuration ```ad-path /location/fail2ban/filter.d/nginx-noscript.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*GET.*(\.asp|\.exe|\.pl|\.cgi|\.scgi) ignoreregex = ~~~ ```   ###### nginx-noproxy configuration [[#^Top|TOP]] ```ad-path /location/fail2ban/filter.d/nginx-noproxy.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*GET http.* ^ -.*CONNECT.* ignoreregex = ~~~ ```   ###### nginx-nowordpress configuration ```ad-path /location/fail2ban/filter.d/nginx-nowordpress.conf ```   ```ad-code ~~~bash [Definition] failregex = ^ -.*"(GET|POST|HEAD) /+(?i)(wp(-|/)|xmlrpc.php|\?author=1) ^ -.* "(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) ^ -.* "(GET|POST|HEAD) /[^"]+.(asp|cgi|exe|jsp|mvc|pl)( |\?) ^ -.*(?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 ~~~ ```   ###### portscan-block configuration ```ad-path /location/fail2ban/filter.d/portscan-block.conf ```   ```ad-code ~~~bash [Definition] failregex = .*\[UFW BLOCK\] IN=.* SRC= 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+)$ ~~~ ```   4. Save and close the file, then restart Fail2Ban for the changes to take effect: ```ad-command ~~~bash sudo systemctl restart fail2ban ~~~ ```   #### 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 ~~~ ```   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 ~~~ ```   3. Create the filter file ```ad-path /etc/fail2ban/filter.d/caddy-4xx.conf ```   ```ad-code ~~~bash [Definition] failregex = ^.*"(GET|POST).*" (404|444|403|400) .*$ ignoreregex = ~~~ ```   4. Save and close the file, then restart Fail2Ban for the changes to take effect: ```ad-command ~~~bash sudo systemctl restart fail2ban ~~~ ```   ---   ### Test fail2ban filters [[#^Top|TOP]]   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]]