Access control using Fail2Ban and geoip

From munkjensen.net/wiki


Preface

This 'guide' explains how to block DNS requests to my Pi-Hole from anywhere in the world but Denmark. Ofcourse you can change that so another country is allowed... or even a selection of countries ;-)

It uses the file hosts.deny at the moment... iptables might be better... we will see if i care to change it later :-P

Geolookup

In order to do a geolookup from the command line, we have to get the GeoIP binary and database installed.

apt-get install geoip-bin geoip-database

Test it: geoiplookup 159.20.6.38 should give you GeoIP Country Edition: DK, Denmark

Fail2Ban

I assume Fail2ban is already installed and configured.

Create a filter script: sudo vi /etc/fail2ban/filter.d/pihole-geoip.conf

# Fail2Ban filter file for pihole.
#

# This filter blocks attacks against named (bind9) however it requires special
# configuration on bind.
#

[Definition]

# This will filter all 'query' requests.
failregex = query\[.*\].* from <HOST>$

# This wil filter all 'query[ANY]' requests.
#failregex = query\[ANY\].* from <HOST>$

#
# Author: [email protected]


Create an action script: sudo vi /etc/fail2ban/action.d/iptables-pihole-geoip-fence.conf

# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
# Modified by [email protected] for pihole use.
#

[INCLUDES]

before = iptables-blocktype.conf

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = iptables -N f2b-<name>
              iptables -A f2b-<name> -j RETURN
              iptables -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
             iptables -F f2b-<name>
             iptables -X f2b-<name>

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = iptables -n -L <chain> | grep -q 'f2b-<name>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# BE AWARE:
#          If an IP adr. belongs to a country in the <country_list>
#          it will be listed as a BAN in fail2ban.log BUT NOT in 
#          iptables -n -L
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = IP=<ip> &&
            COUNTRY=$(geoiplookup $IP | egrep "<country_list>") && [ "$COUNTRY" ] ||
            (iptables -I f2b-<name> 1 -s <ip> -j <blocktype>)

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = IP=<ip> &&
              COUNTRY=$(geoiplookup $IP | egrep "<country_list>") && [ "$COUNTRY" ] ||
              (iptables -D f2b-<name> -s <ip> -j <blocktype>)

[Init]

# Default name of the chain
#
name = default

# Option:  port
# Notes.:  specifies port to monitor
# Values:  [ NUM | STRING ]  Default:
#
port = 53

# Option:  protocol
# Notes.:  internally used by config reader for interpolations.
# Values:  [ tcp | udp | icmp | all ] Default: tcp
#
protocol = all

# Option:  chain
# Notes    specifies the iptables chain to which the fail2ban rules should be
#          added
# Values:  STRING  Default: INPUT
chain = INPUT

# Option:  country_list
# Notes.:  List of exempted countries separated by pipe "|"
# Values:  STR  Default:
#
country_list = DK|Denmark


Enable it by editing sudo vi /etc/fail2ban/jail.local

[DEFAULT]
maxretry = 3
bantime  = 900
destemail = fm@localhost
#banaction = geohostsdeny

[pihole-geoip]
enabled  = true
port     = domain,53
protocol = udp
banaction = iptables-pihole-geoip-fence
filter   = pihole-geoip
logpath  = /var/log/pihole.log

Restart Fail2Ban like this sudo service fail2ban restart

Hopefully it restarts without any errors... if you get errors in /var/log/fail2ban try to dum the config using the command fail2ban-client -d and hunt the bugs using this info.

Files

This is the file/folder structure for Fail2Ban. I edited / created the files marked with an §

/etc/fail2ban/
     ├── action.d/
     │   └── iptables-pihole-geoip-fence.conf §
     ├── fail2ban.conf
     ├── filter.d/
     │   └── pihole-geoip.conf §
     ├── jail.conf
     └── jail.local §

Reference