The issue arose for me when one of our test servers started getting hammered by script kiddies from China and so on.
They didn't get in, but that wasn't the point.
The point was that the web site was for Australian users only.
Now to short circuit any comments I can say:
1) The solution had to work for several frameworks (Elgg, Joomla, etc)
2) I wasn't redirecting traffic to a special page
3) I wanted to black all access except Australian IPv4 ranges
I could have gone to MaxMind or its ilk, but that would make '1' problematic.
The first step was to locate a *correct* and *regularly updated* list of CIDR and range formatted IPv4 list.
I tried several including http://www.ipdeny.com/ipblocks/ with no luck.
Most have gaps in their lists because they use 'official' sources.
And ISP ranges are not always covered in those lists.
Eventually I found http://software77.net/geo-ip/
I downloaded the zone and CIDR lists for the countries I was interested in.
Then I modified the /etc/apache2/sites-available/my-site.something.com file to look like this:
Abbreviated for this post. :-)
<VirtualHost *:80> ServerAdmin email@example.com ServerName my-site.something.com ServerSignature Off DocumentRoot /home/my-user/my-site/site LogLevel warn ErrorLog /home/my-user/my-site/logs/error.log CustomLog /home/my-user/my-site/logs/access.log combined ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory /home/my-user/my-site/site/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order Deny,Allow # See .htaccess for country limiting </Directory> </VirtualHost>
Then in the /home/my-user/my-site/site/.htaccess file I added the following to the bottom:
<Limit GET HEAD POST> Order Deny,Allow Deny from all # Report generated on Mon Apr 22 01:02:36 2013 # by http://software77.net/geo-ip/ # Report Type : CIDR format # Country : Australia # ISO 3166 CC : ALPHA-2 AU; ALPHA-3 AUS # Registry : APNIC # Records found: 6,160 BEFORE flattening (As they appear in the database) # Records : 3,999 AFTER flattening (Adjoining CIDR blocks concatenated into single blocks where possible) Allow from 184.108.40.206/24 Allow from 220.127.116.11/22 ...elided for brevity... Allow from 18.104.22.168/22 Allow from 22.214.171.124/24 </Limit>
The block from under the 'Deny from all' to the end is the CIDR formatted file for a country.
You have to add the 'Allow from ' in front of the address, but if you use vi that's trivial.
If you want to allow another country access, then simply add the CIDR formatted file below the first.
Then I ran '/etc/init.d/apache2 reload' and all is well.
IMPORTANT NOTE: Things change. You have to check for additions and deletions on the CIDR files on a regular basis - say, once a month to ensure that you .htaccess file is up to date.
Some readers may have noticed that I suggest downloading the zone files as well.
This is to allow you to read your apache logs and see which country that access came from.
I will be posting another entry soon that shows how to do that in Ruby.