In this article, we will take a look on how to exempt from banning visitors from a specific country using Fail2ban and geoip. It is assumed that Fail2ban is already installed and configured in your server.
Lets install first the geoip:
yum install geoip
Create Fail2ban action script:
vi /etc/fail2ban/action.d/geohostsdeny.conf
Copy the following script:
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Excludes PH|Philippines from banning.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = IP=<ip> &&
COUNTRY=$(geoiplookup $IP | egrep "<country_list>") && [ "$COUNTRY" ] ||
(printf %%b "<daemon_list>: $IP\n" >> <file>)
# 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> && sed -i.old /ALL:\ $IP/d <file>
[Init]
# Option: country_list
# Notes.: List of exempted countries separated by pipe "|"
# Values: STR Default:
#
country_list = PH|Philippines
# Option: file
# Notes.: hosts.deny file path.
# Values: STR Default: /etc/hosts.deny
#
file = /etc/hosts.deny
# Option: daemon_list
# Notes: The list of services that this action will deny. See the man page
# for hosts.deny/hosts_access. Default is all services.
# Values: STR Default: ALL
daemon_list = ALL
The script above will exempt from banning the visitors from Philippines which defined in "country_list".
To enable our action script in Fail2Ban:
vi /etc/fail2ban/jail.local
... and add the following line in your jail.local
file:
banaction = geohostsdeny
Restart Fail2Ban:
systemctl restart fail2ban
For the opposite (which is to ban), please check the article here.
Comments
This is my /etc/hosts.deny…
This is my /etc/hosts.deny
contents as of today:
#
# hosts.deny This file contains access rules which are used to
# deny connections to network services that either use
# the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
#
# The rules in this file can also be set up in
# /etc/hosts.allow with a 'deny' option instead.
#
# See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
#
ALL: 5.10.115.6
ALL: 158.85.169.152
ALL: 113.28.44.14
ALL: 175.126.103.65
ALL: 106.187.96.51
ALL: 175.45.48.218
ALL: 190.85.89.30
ALL: 223.105.0.129
ALL: 41.254.9.240
ALL: 41.254.9.60
ALL: 37.211.66.180
ALL: 202.3.77.44
ALL: 104.217.216.174
ALL: 104.223.6.154
ALL: 104.223.72.169
ALL: 107.6.166.234
ALL: 122.226.102.202
ALL: 123.176.36.2
ALL: 173.254.236.10
ALL: 180.97.215.154
ALL: 180.97.215.49
ALL: 192.240.106.50
ALL: 198.2.197.153
ALL: 204.151.201.20
ALL: 222.171.107.116
ALL: 222.186.130.243
ALL: 222.186.21.113
ALL: 222.186.21.35
ALL: 222.186.21.52
ALL: 222.186.51.61
ALL: 222.186.58.81
ALL: 222.187.222.35
ALL: 23.253.62.189
ALL: 37.49.226.124
ALL: 42.114.146.128
ALL: 45.32.26.28
ALL: 58.187.135.69
ALL: 58.215.79.87
ALL: 58.218.204.163
ALL: 58.64.155.107
ALL: 61.160.247.11
ALL: 85.125.187.98
If you will check each of the IP address, there is no IP address from Philippines banned in my server. This shows that the script in this article works just fine. It was tested for several times before I publish this article.
Make sure you have "filter" enabled in your "jail.local". E.g. in /etc/fail2ban/jail.local
:
[DEFAULT]
ignoreip = 127.0.0.1/8
maxretry = 3
bantime = 900
banaction = geohostsdeny
[sshd-ddos]
enabled = true
I enabled the filter ssh-ddos. All bad traffic that will be detected by fail2ban and falls under ssh-ddos rules 3 times, fail2ban will ban these IP addresses (except Philippine IP address) for 15 minutes.
geoip
fail2ban does not start again with this jail.local since no filter in filter.d is defined. Any suggestions? Moreover, I do not declare deohostdeny as a DEFAULT banaction. Therefore actions, banactions and filter need to set under - in this example - [sshd-ddos].
If I would not define the…
[DEFAULT]
ignoreip = 127.0.0.1/8
maxretry = 3
bantime = 900
[sshd-ddos]
banaction = geohostsdeny
enabled = true
GeoIP -database update
# cat /etc/GeoIP.conf
UserId 999999
LicenseKey 000000000000
ProductIds 506 517 533
Cron update
# cd /etc/cron.weekly/
# cat GeoIP-update.cron
/usr/bin/geoipupdate
# chmod 0755 GeoIP-update
Manual update
# /usr/bin/geoipupdate -v
geoipupdate 2.2.1
Opened License file /etc/GeoIP.conf
UserId 999999
LicenseKey 000000000000
Insert product_id 506
Insert product_id 517
Insert product_id 533
Read in license key /etc/GeoIP.conf
Number of product ids 3
url: https://updates.maxmind.com/app/update_getfilename?product_id=506
md5hex_digest: 1e43a1a5c531cc8e11fb4f83a1c0ec7a
url: https://updates.maxmind.com/app/update_getipaddr
Client IP address: xxx.yyy.zzz.qqq
md5hex_digest2: f2850ecb81886a81b8cb689829f0872a
url: https://updates.maxmind.com/app/update_secure?db_md5=1e43a1a5c531cc8e11fb4f83a1c0ec7a&challenge_md5=f2850ecb81886a81b8cb689829f0872a&user_id=999999&edition_id=506
No new updates available
url: https://updates.maxmind.com/app/update_getfilename?product_id=517
md5hex_digest: 0f1573e51b06f114cfd4f934e37ffd82
url: https://updates.maxmind.com/app/update_getipaddr
Client IP address: xxx.yyy.zzz.qqq
md5hex_digest2: f2850ecb81886a81b8cb689829f0872a
url: https://updates.maxmind.com/app/update_secure?db_md5=0f1573e51b06f114cfd4f934e37ffd82&challenge_md5=f2850ecb81886a81b8cb689829f0872a&user_id=999999&edition_id=517
No new updates available
url: https://updates.maxmind.com/app/update_getfilename?product_id=533
md5hex_digest: 0637ec47d9b4d8107d32e94c35f7f311
url: https://updates.maxmind.com/app/update_getipaddr
Client IP address: xxx.yyy.zzz.qqq
md5hex_digest2: f2850ecb81886a81b8cb689829f0872a
url: https://updates.maxmind.com/app/update_secure?db_md5=0637ec47d9b4d8107d32e94c35f7f311&challenge_md5=f2850ecb81886a81b8cb689829f0872a&user_id=999999&edition_id=533
No new updates available
Thanks for the article
I still seem to still be getting hits from Russia, but I'll take another look tomorrow. For now, it seems to be working fine. Didn't have to do any weird tricks. Using CentOS 6.9
Thx for the Article
Just implemented it on multiple Servers - and it's working like a charm! ;-)
other approach to Geo-Blocking
Hey there,
thx for your Article - but maybe an approach using "ignorecommand" would be more lean ... ?
Implemented it with "ignorecommand" on multiple Servers and it's working like a charm ... ;-)
bye from Austria
Andreas Schnederle-Wagner
how do I go about testing this?
Hi
noob here
I have a moodle site on a gcloud instance
I just setup fail2ban and also I followed the instructions on this article
the only thing I changed was country_list = CO|Colombia|CA|Canada
as I want only users from Colombia and Canada to be able to use my moodle instance.
but when I try to test going to my site from a webproxy sourced in Germany, it still allows the moodle site to show?
am I missing something?
Thank you
arpeggio
Wed, 06/19/2019 - 12:24
In reply to how do I go about testing this? by Francisco (not verified)
Check if your geoiplookup is…
Check if your geoiplookup is working. Try to execute:
geoiplookup 8.8.8.8 | egrep "US|United States"
... the output should be:
GeoIP Country Edition: US, United States
Try to change the 8.8.8.8 above with IP of the country you want and change "US|United States" as well in egrep.
Francisco Cortes (not verified)
Thu, 06/20/2019 - 10:47
In reply to Check if your geoiplookup is… by arpeggio
geoiplookup is working.. but still no ban outside of countrylist
Hi arpeggio
Thank you for your reply
geoiplookup seems to be working
I got this:
[franciscojaviercortes@centos6 ~]$ geoiplookup 8.8.8.8 | egrep "US|United States"
GeoIP Country Edition: US, United States
GeoIP City Edition, Rev 1: US, N/A, N/A, N/A, N/A, 37.750999, -97.821999, 0, 0
[franciscojaviercortes@centos6 ~]$
---
my jail.local file has this:
[DEFAULT]
#
#default time a user is banned after maxretry login attempts
bantime = 3600
#
[sshd]
enabled = true
#
[sshd-ddos]
banaction = geohostsdeny
enabled = true
# See jail.conf(5) man page for more information
---
and my geohostsdeny.conf file shows this
[Init]
# Option: country_list
# Notes.: List of exempted countries separated by pipe "|"
# Values: STR Default:
#
country_list = CO|Colombia|CA|Canada
...
bad even after restarting fail2ban (which restarts ok), when I try to access my site from a country that is not either Colombia or Canada the site still comes up as you can see here:
https://prnt.sc/o45snk
is there anything else that I'm missing?
arpeggio
Thu, 06/20/2019 - 11:28
In reply to geoiplookup is working.. but still no ban outside of countrylist by Francisco Cortes (not verified)
Please create a fresh filter…
Please create a fresh filter and follow carefully the steps mentioned in the article above, including the file names.
Francisco (not verified)
Fri, 06/21/2019 - 12:05
In reply to Please create a fresh filter… by arpeggio
I'm not sure how do I go about creating a filter
Hi arpeggio
I'm sorry, I'm not sure how to create a filter
I see that there's a filter.d folder that have all the configuraiton files used on the jail.conf's params but I though all that was needed to do was to create the action file with the script provided and have this added in the banaction parameter within one of the jails being enabled in our jail.local
what I did try was to create a brand new jail.local that only contains the following:
-sof---
[DEFAULT]
enable = true
filter = DEFAULT
logpath = /var/log/secure
maxretry = 5
bantime = 3600
banaction = geohostsdeny
######################
[sshd]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/secure
findtime = 600
maxretry = 6
bantime = 86400
banaction = geohostsdeny
-eof--
and the action file was created with the same name you indicated within the filter.d folder
[fcortes@centos6 fail2ban]$ ls -l /etc/fail2ban/action.d/ | grep geo*
-rw-r--r--. 1 root root 1582 Jun 19 02:52 geohostsdeny.conf
but after I restart fail to ban and try to access the site from germany with hide-my-ass webproxy, the site still comes up.
if I need to create a filter .conf file within filter.d for what I'm trying to do, is there any guide on how to do so? I guess I could make a copy of the drupal file that it's already there and tweak it for my moodle but tbh I'm not even sure how I would go about doing that.
I thank you so much for your patience and guidance.
arpeggio
Fri, 06/21/2019 - 12:25
In reply to I'm not sure how do I go about creating a filter by Francisco (not verified)
The /etc/hosts.deny
Based on /etc/fail2ban/action.d/geohostsdeny.conf configuration, all the banned IP addresses should be seen here:
/etc/hosts.deny
If you don't see the IP addresses, something wrong with your setup.
nothing on my hosts.deny but there are banned ips.. why?
Hi Arpeggio
I don't have anything logged in my hosts.deny but fail2ban does show some ip's banned. does that make sense?
franciscojaviercortes@centos6 ~]$ cat /etc/hosts.deny
#
# hosts.deny This file contains access rules which are used to
# deny connections to network services that either use
# the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
#
# The rules in this file can also be set up in
# /etc/hosts.allow with a 'deny' option instead.
#
# See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
#
[franciscojaviercortes@centos6 ~]$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
[franciscojaviercortes@centos6 ~]$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 56
| `- File list: /var/log/secure
`- Actions
|- Currently banned: 13
|- Total banned: 13
`- Banned IP list: 104.248.81.157 128.199.55.17 134.209.10.41 134.209.82.3 134.209.84.42 159.65.148.178 36.92.
21.50 68.183.80.186 68.183.80.232 68.183.95.97 142.93.221.103 142.93.211.234 221.2.158.154
I'm looking to discontinue this vm in the next few months so once I restart elsewhere I will give it another shot, I hope to have better luck at that time
It does appear like something is certainly off with my instance but I can't figure out exactly what that is. That's what prompted me to start looking into fail2ban and other security strategies (I know I should've done that a while ago but well I'm a noob so I guess I gotta bleed before I learn my lesson)
I do thank you again for getting back to me
cheers :)
arpeggio
Sat, 06/22/2019 - 11:04
In reply to nothing on my hosts.deny but there are banned ips.. why? by Francisco Cortes (not verified)
Review your setup
You're welcome. Review your setup, always check /etc/hosts.deny when troubleshooting as all IP addresses listed here are banned in your server.
For ipv6?
How would you change the code for checking up geoiplookup6?
You don't need to worry for…
You don't need to worry for checking IPv6 as it will be taken care of geoip when the IP pass to it as parameter.
Where to put Banaction
I don't understand, my jail.local is full of stuff. And currently, the default is set to banaction = iptables-multiport. How can I add multiple banaction? So I can set like banaction = iptables-multiport, geohostsdeny. Does this work?
That will not work. Instead,…
That will not work. Instead, you can assign different "banaction" to specific filter.
Question
If you have multiple countries you want to block, how do I do?
Multiple countries
In your /etc/fail2ban/action.d/geohostsdeny.conf
, you can do this:
country_list = PH|Philippines|SG|Singapore|AU|Australia
Jail postfix-sasl ??
Excellent article.
In the case of the jail Postfix-sasl, what would it be like?
thank you very much!
As for now I don't have the…
As for now I don't have the script for Postfix-sasl yet. I will post an update here as soon as I have one. Thanks.
Block certain Country
Thanks for the article, in my case I only want to block 3 countries.
The procedure describes how to allow countries through: country_list = PH|Philippines , etc.
How can I allow all countries except 2 or 3? So, how can I block only 1 country, for example Singapore?
Ban visitors from a specific country
William Smith (not verified)
Wed, 03/17/2021 - 19:24
In reply to Ban visitors from a specific country by admin
Ban or Not Ban ?
But this is to exempt not ban...
Are there different scripts ?
Thanks
The codes in this article…
country_list
. If you are looking for the opposite (which is to ban), please check the article here.does banning still work from brute attacks of countries allowed?
What about brute force attacks from countries that are allowed to connect? What options can be used to ban and jail these?
arpeggio
Sun, 04/18/2021 - 19:52
In reply to does banning still work from brute attacks of countries allowed? by Leah H Lawrence (not verified)
Yes, Fail2Ban allows you to…
Yes, Fail2Ban allows you to automate the process of blocking brute-force attacks by limiting the number of failed authentication attempts a user can make before being blocked. You will need to use service specific filter, a log filter. Fail2Ban uses regular expressions to monitor log files for patterns corresponding to authentication failures, seeking for exploits, and other entries that can be considered suspicious.
Allow specific countries and ban the rest.
Thanks for the article. I have read your comment 435: https://www.webfoobar.com/comment/435#comment-435
That is about blocking multiple countries, while I would like to allow specific countries and ban the rest, for any and all ports.
How would I modify the script to allow India and United States; and ban the rest.
arpeggio
Wed, 12/08/2021 - 11:08
In reply to Allow specific countries and ban the rest. by Jack (not verified)
Please see the article above
You're welcome. For your case, just follow the article. The article shows how to allow specific countries and ban the rest, for all services.
Better approach
jail.local
ignorecache = key="", max-count=100, max-time=5m
ignorecommand = COUNTRY=$(geoiplookup "" | egrep ""); [ "$COUNTRY" ] && exit 0 || exit 1
ban but it doesn't work
Debian 11, everything seems to work, the ip not belonging to the geolocation Italy (in my case) are banned. The ip address is successfully added to the /etc/hosts.deny file but connection after the ban is still allowed. I'm using UFW to close affected ports...any suggestions?
The IP addresses listed in…
The IP addresses listed in hosts.deny should all be banned. How did you test it? Please double check your procedure in testing it.
script doesn't do anything
Tried it, doesn't work. I've set up country_list = PH|Philippines|IN|India|CN|China|US|United States|KR|South Korea|IR|Iran|RU|Russia|BR|Brazil|AR|Argentina as banned countries and get a bunch of IPs in hosts.deny from Russia, China, the US etc. Really looks like the script doesn't do anything. Moreover, I get about 277 banned IPs in fail2ban Banned IP List for sshd compared to about 100 in hosts.deny.
Fyi, the countries listed in…
Fyi, the countries listed in country_list
will be exempted (not banned) in the script presented in this article. If you are looking for script that will ban countries listed in country_list
, you can find it here.
That's the one I'm using.
That's the one I'm using.
actionban value
What is the value of your actionban
?
how to check
I've followed you instruction, however it's not banning from outside country list.
Can you please suggest any other configuration required or any other checklist.