Access control using Fail2Ban and geoip: Difference between revisions

From munkjensen.net/wiki
 
(32 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Debian]]
[[Category:Debian]][[Category:DNS]][[Category:RaspBerry Pi]][[Category:Pi-Hole]][[File:ANY_flooding_smack_down.PNG|350px|thumb|right|A flood of [ANY] queries started around 4 am. Configuration and tuning of Fail2Ban started around 8 am and was effectively banning DNS queries from ip's outside Denmark at 10 am. ]]
= Preface =


This 'guide' explains how to make Debian [http://wiki.debian.org/iptables iptables] block (silently drop) DNS requests to my [[See my Pi-Hole| Pi-Hole]] from anywhere in the world but Denmark. Of course you can change that so another country is allowed... or even a selection of countries ;-)


== Preface ==
This [https://www.fail2ban.org Fail2ban] configuration can raise an effective [https://en.wikipedia.org/wiki/Geo-fence Geo-Fence] for other server services, if configuration of the regular expression, the ports and logfile location is done properly ;-)


This 'guide' explains how to block DNS requests to my [[See my Pi-Hole| 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 ;-)
== Geolookup ==
 
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.
In order to do a geolookup from the command line, we have to get the GeoIP binary and database installed.
 
<blockquote>
<code>apt-get install geoip-bin geoip-database</code>
<blockquote><code>apt-get install geoip-bin geoip-database</code></blockquote>


Test it:
Test it:
<code>geoiplookup 159.20.6.38</code>
<blockquote><code>geoiplookup 159.20.6.38</code></blockquote>
should give you  
should give you  
<code>GeoIP Country Edition: DK, Denmark</code>
<blockquote><code>GeoIP Country Edition: DK, Denmark</code></blockquote>
</blockquote>


=== Fail2Ban ===
== Fail2Ban ==


I assume [https://www.fail2ban.org Fail2ban] is already installed and configured.
I assume [https://www.fail2ban.org Fail2ban] is already installed and running.
 
<blockquote>
==== dnsmasq ====
----
 
The configuration will ban ip adresses from countries that <u>is not</u> included in the ''country_list'' found in the ''[init]'' section of the file ''/etc/fail2ban/action.d/iptables-pihole-geoip-fence.conf''. If you dont want to totally block dns requests from countries not included in the 'country_list', you can use the regular expression that will filter all 'query[ANY]' requests. it is configured in the file ''/etc/fail2ban/filter.d/pihole-geoip.conf''


<blockquote>
<blockquote>
Line 27: Line 32:
Create a filter script: <code>sudo vi /etc/fail2ban/filter.d/pihole-geoip.conf</code>
Create a filter script: <code>sudo vi /etc/fail2ban/filter.d/pihole-geoip.conf</code>
<div class="mw-collapsible-content">
<div class="mw-collapsible-content">
<syntaxhighlight lang="xml" line># Fail2Ban filter file for pihole.
<syntaxhighlight lang="xml" line># Fail2Ban filter file for Pi-Hole.
#
#


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


Line 39: Line 43:
failregex = query\[.*\].* from <HOST>$
failregex = query\[.*\].* from <HOST>$


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


Line 92: Line 96:
# Notes.:  command executed when banning an IP. Take care that the
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
#          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
# Tags:    See jail.conf(5) man page
# Values:  CMD
# Values:  CMD
Line 114: Line 114:


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


# Default name of the chain
# Default name of the chain
#
#
name = default
name = pihole


# Option:  port
# Option:  port
Line 137: Line 143:
chain = INPUT
chain = INPUT


# Option:  country_list
# Option:  blocktype
# Notes.:  List of exempted countries separated by pipe "|"
# Note:    This is what the action does with rules. This can be any jump target
# Values:  STR  Default:
#          as per the iptables man page (section 8). Common values are DROP
#
#          REJECT, REJECT --reject-with icmp-port-unreachable
country_list = DK|Denmark
# Values:  STRING
blocktype = DROP
</syntaxhighlight>
</syntaxhighlight>
</div>
</div>
Line 156: Line 163:
bantime  = 900
bantime  = 900
destemail = fm@localhost
destemail = fm@localhost
#banaction = geohostsdeny


[pihole-geoip]
[pihole-geoip]
enabled  = true
enabled  = true
port    = domain,53
port    = 53
protocol = udp
protocol = udp
banaction = iptables-pihole-geoip-fence
banaction = iptables-pihole-geoip-fence
filter  = pihole-geoip
filter  = pihole-geoip
logpath  = /var/log/pihole.log
logpath  = /var/log/pihole.log
bantime  = 604800  ; 1 week
findtime = 86400  ; 1 day
maxretry = 1
</syntaxhighlight>
</syntaxhighlight>
</div>
</div>
Line 172: Line 181:
Restart Fail2Ban like this <code>sudo service fail2ban restart</code>
Restart Fail2Ban like this <code>sudo service fail2ban restart</code>


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


==== Files ====
'''Files'''


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


<blockquote><pre>/etc/fail2ban/
<blockquote><pre>/etc/fail2ban/
Line 185: Line 194:
     │  └── pihole-geoip.conf §
     │  └── pihole-geoip.conf §
     ├── jail.conf
     ├── jail.conf
     └── jail.local §</pre></blockquote>
     └── jail.local §</pre></blockquote></blockquote>
 
<blockquote>
==== lighttpd ====
----
 
This configuration will ban ip adresses from countries that <u>is not</u> included in the ''country_list'' located in the ''[init]'' section of the file ''/etc/fail2ban/action.d/iptables-pihole-adminweb-geoip-fence.conf'' '''if''' they try to access ''http://[your.domain]/admin'' and subfolders.
 
<blockquote>
<div class="toccolours mw-collapsible mw-collapsed">
Create a filter script: <code>sudo vi /etc/fail2ban/filter.d/pihole-geoip.conf</code>
<div class="mw-collapsible-content">
<syntaxhighlight lang="xml" line># Fail2Ban filter file for pihole.
#
 
# This filter find IP adresses that try to access the
# /admin folder and everything below, served by the lighttpd daemon.
#
 
[Definition]
 
# This will filter all GET and HEAD requests for /admin* in lighttpd.log
# Example line: 1496389170|123.123.123.123|cloud.pulspc.dk|GET /admin/api.php?overTimeData10mins HTTP/1.1|200|4901
#
failregex = ^\|<HOST>\|.*\|GET \/admin.*
            ^\|<HOST>\|.*\|HEAD \/admin.*
 
# This will filter all GET and HEAD requests for all GET requests
#
#failregex = ^\|<HOST>\|.*\|GET.*
#failregex = ^\|<HOST>\|.*\|HEAD.*
 
#
</syntaxhighlight>
</div>
</div>
</blockquote>
 
 
<blockquote>
<div class="toccolours mw-collapsible mw-collapsed">
Create an action script: <code>sudo vi /etc/fail2ban/action.d/iptables-pihole-adminweb-geoip-fence.conf</code>
<div class="mw-collapsible-content">
<syntaxhighlight lang="xml" line># 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.
# 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]
 
# Option:  country_list
# Notes.:  List of exempted countries separated by pipe "|"
# Values:  STR  Default:
#
country_list = DK|Denmark
 
# Default name of the chain
#
name = ph-admweb
 
# 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:  blocktype
# Note:    This is what the action does with rules. This can be any jump target
#          as per the iptables man page (section 8). Common values are DROP
#          REJECT, REJECT --reject-with icmp-port-unreachable
# Values:  STRING
blocktype = DROP
</syntaxhighlight>
</div>
</div>
</blockquote>
 
 
<blockquote>
<div class="toccolours mw-collapsible mw-collapsed">
Enable it by editing/adding <code>sudo vi /etc/fail2ban/jail.local</code>
<div class="mw-collapsible-content">
<syntaxhighlight lang="xml" line>[pihole-adminweb-geoip]
enabled  = true
port    = 80,443
protocol = tcp
banaction = iptables-pihole-adminweb-geoip-fence
filter  = pihole-adminweb-geoip
logpath  = /var/log/lighttpd/access.log
bantime  = 604800  ; 1 week
findtime = 86400  ; 1 day
maxretry = 1
</syntaxhighlight>
</div>
</div>
</blockquote>
 
Restart Fail2Ban like this <code>sudo service fail2ban restart</code>
 
Hopefully it restarts without any errors... if you get errors in ''/var/log/fail2ban.log'' try to dum the config using the command <code>fail2ban-client -d</code> and hunt the bugs using this info.
 
'''Files'''
 
This is the file/folder structure for Fail2Ban. I edited/created the files marked with an §
 
<blockquote><pre>/etc/fail2ban/
    ├── action.d/
    │  └── iptables-pihole-adminweb-geoip-fence.conf §
    ├── fail2ban.conf
    ├── filter.d/
    │  └── pihole-adminweb-geoip.conf §
    ├── jail.conf
    └── jail.local §</pre></blockquote></blockquote>


== Reference ==
== Reference ==
* http://kbeezie.com/geoiplookup-command-line/
* http://kbeezie.com/geoiplookup-command-line/
* https://www.webfoobar.com/node/54
* https://www.webfoobar.com/node/54

Latest revision as of 11:33, 13 June 2017

A flood of [ANY] queries started around 4 am. Configuration and tuning of Fail2Ban started around 8 am and was effectively banning DNS queries from ip's outside Denmark at 10 am.

Preface

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

This Fail2ban configuration can raise an effective Geo-Fence for other server services, if configuration of the regular expression, the ports and logfile location is done properly ;-)

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 running.

dnsmasq


The configuration will ban ip adresses from countries that is not included in the country_list found in the [init] section of the file /etc/fail2ban/action.d/iptables-pihole-geoip-fence.conf. If you dont want to totally block dns requests from countries not included in the 'country_list', you can use the regular expression that will filter all 'query[ANY]' requests. it is configured in the file /etc/fail2ban/filter.d/pihole-geoip.conf

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

# Fail2Ban filter file for Pi-Hole.
#

# This filter blocks attacks against PiHole (dnsmasq).
#

[Definition]

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

# This will 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.
# 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]

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

# Default name of the chain
#
name = pihole

# 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:  blocktype
# Note:    This is what the action does with rules. This can be any jump target
#          as per the iptables man page (section 8). Common values are DROP
#          REJECT, REJECT --reject-with icmp-port-unreachable
# Values:  STRING
blocktype = DROP


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

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

[pihole-geoip]
enabled  = true
port     = 53
protocol = udp
banaction = iptables-pihole-geoip-fence
filter   = pihole-geoip
logpath  = /var/log/pihole.log
bantime  = 604800  ; 1 week
findtime = 86400   ; 1 day
maxretry = 1

Restart Fail2Ban like this sudo service fail2ban restart

Hopefully it restarts without any errors... if you get errors in /var/log/fail2ban.log 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 §

lighttpd


This configuration will ban ip adresses from countries that is not included in the country_list located in the [init] section of the file /etc/fail2ban/action.d/iptables-pihole-adminweb-geoip-fence.conf if they try to access http://[your.domain]/admin and subfolders.

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

# Fail2Ban filter file for pihole.
#

# This filter find IP adresses that try to access the
# /admin folder and everything below, served by the lighttpd daemon.
#

[Definition]

# This will filter all GET and HEAD requests for /admin* in lighttpd.log
# Example line: 1496389170|123.123.123.123|cloud.pulspc.dk|GET /admin/api.php?overTimeData10mins HTTP/1.1|200|4901
#
failregex = ^\|<HOST>\|.*\|GET \/admin.*
            ^\|<HOST>\|.*\|HEAD \/admin.*

# This will filter all GET and HEAD requests for all GET requests
#
#failregex = ^\|<HOST>\|.*\|GET.*
#failregex = ^\|<HOST>\|.*\|HEAD.*

#
# Author: [email protected]


Create an action script: sudo vi /etc/fail2ban/action.d/iptables-pihole-adminweb-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.
# 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]

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

# Default name of the chain
#
name = ph-admweb

# 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:  blocktype
# Note:    This is what the action does with rules. This can be any jump target
#          as per the iptables man page (section 8). Common values are DROP
#          REJECT, REJECT --reject-with icmp-port-unreachable
# Values:  STRING
blocktype = DROP


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

[pihole-adminweb-geoip]
enabled  = true
port     = 80,443
protocol = tcp
banaction = iptables-pihole-adminweb-geoip-fence
filter   = pihole-adminweb-geoip
logpath  = /var/log/lighttpd/access.log
bantime  = 604800  ; 1 week
findtime = 86400   ; 1 day
maxretry = 1

Restart Fail2Ban like this sudo service fail2ban restart

Hopefully it restarts without any errors... if you get errors in /var/log/fail2ban.log 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-adminweb-geoip-fence.conf §
     ├── fail2ban.conf
     ├── filter.d/
     │   └── pihole-adminweb-geoip.conf §
     ├── jail.conf
     └── jail.local §

Reference