Linux fail2ban Setup

From bibbleWiki
Jump to navigation Jump to search

Introduction

fail2ban is a tool to monitor http requests and activate ip firewall based on a config

How I use it

On my domain I monitor for 403 http codes if this is found then the IP is blocked for a configurable amount to time. We need to -Install fail2ban (just use apt) -Make a filter -Make/Append jail.local -Restart -Monitoring

Make a filter

To make a filter you pointer you create a file in /etc/fail2ban/filters.d. In this case we look for 403 errors and extract the remote host

[Definition]
failregex = ^.*"remote_ip":\s*"<HOST>".*"status":\s*403
datepattern = "ts": {UNIX_TIMESTAMP}
ignoreregex =

Make/Append jail.local

If it exists append to /etc/fail2ban/jail.local

[caddy-json]
enabled  = true
filter   = caddy-json
port     = http,https
logpath  = /var/log/caddy/caddy_blah.access.log
maxretry = 5
findtime = 600
bantime  = 3600

Restart

sudo systemctl restart fail2ban

The robot mucked mine up the first time through but you can check with

sudo fail2ban-regex /var/log/caddy/access.json /etc/fail2ban/filter.d/caddy-json.conf

Once all working you can list bans with

fail2ban-client status caddy-json

This shows

Status for the jail: caddy-json
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     26
|  `- File list:        /var/log/caddy/caddy_blah.access.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     1
   `- Banned IP list:

To remove a ban you can do the following (replace the IP you fool)

 sudo fail2ban-client set caddy-json unbanip 10.10.10.10

Monitoring

Like most things you can send metrics to prometheous. Make a script to extract the metric /usr/local/bin/fail2ban_metrics.sh

#!/bin/bash
echo "# HELP fail2ban_banned_total Number of banned IPs per jail"
echo "# TYPE fail2ban_banned_total gauge"

# Get list of jails
#jails=$(fail2ban-client status | grep 'Jail list:' | sed 's/.*Jail list:\s*//g' | tr ',' ' ')
jails=$(fail2ban-client status | awk -F': *' '/Jail list:/ {print $2}' | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

# Loop through each jail and get banned count
#for jail in $jails; do
#    banned=$(fail2ban-client status "$jail" | grep 'Currently banned' | awk '{print $NF}')
#    echo "fail2ban_banned_total{jail=\"$jail\"} $banned"
#done
for jail in $jails; do
  banned=$(fail2ban-client status "$jail" 2>/dev/null | grep 'Currently banned' | awk '{print $NF}')
  if [[ "$banned" =~ ^[0-9]+$ ]]; then
    echo "fail2ban_banned_total{jail=\"$jail\"} $banned"
  else
    echo "fail2ban_banned_total{jail=\"$jail\"} 0"
  fi
done

Stick it in the cron tab and check with prometheus that it is being processed.

curl  -u admin:notsaying-k --cacert /etc/prometheus/yourcert.crt  "https://localhost:9090/api/v1/query?query=fail2ban_banned_total" |jq