GeoIP Blocking – examples for Apache
The GOOD news – using the GeoIP module (mod_geoip.c.) can be quite simple. The module provides much more than simply a relatively easy means to manage web server access – it opens up some opportunities for data mining.
The BAD news – when limiting access make sure that this is what you really want/need to do
otherwise you may be denying access from ‘the good guys’…
With Apache you have multiple options to control access via domains, folders or application code:
- edit the server configuration file (usually httpd.conf)
- edit .htaccess files (per virtual host or even per folder)
- use PHP (or other GeoIP code to manage access)
Before you can use it you will need to download, compile, install and configure mod_geoip on your system (make sure to get the correct version of mod_geoip for your version of Apache…) You will also need the data sets from http://MaxMind.com (or some other source.) The ‘lite’ data sets are currently free so the only ‘cost’ is your time to set things up and test…
What can you do with mod_geoip?
- limit/control access to your web server(s) (limit access by location, i.e. only visitors from IP space from a specific location are allowed, OR deny ‘bad guy’ access or allow ‘good guys’)
- redirect access to location specific services (i.e. a visit to the company ‘global site’ redirects the visitor to a site customized for their location)
- build dynamic Geo-localized/customized results for your web site visitors (based on their location – I would suggest that you add an opportunity for visitors to confirm or change ‘locations’…)
- data mining - when data is available, create content (or aggregate data about visitors) that reaches into: area codes, zip codes, Lat/Long, Cites, States, Regions, Countries and Continents. Whew! The fields that you can access depend upon the data that you use, for instance:
GeoIP City Edition: Sets GEOIP_CONTINENT_CODE, GEOIP_COUNTRY_CODE, GEOIP_REGION, GEOIP_REGION_NAME, GEOIP_CITY, GEOIP_DMA_CODE, GEOIP_AREA_CODE, GEOIP_LATITUDE, GEOIP_LONGITUDE and GEOIP_POSTAL_CODE
mod_geoip – Post-install Setup (from the README file)
Before implementing this server-wide I would suggest trying this via .htaccess. In either case I would also suggest that you maintain a separate geoip.ban.conf file (or as many such files as needed – perhaps you need to be selected based on the domain being accessed?) Once created you simply include the ‘ban file’ that you wish to use with the domain that is appropriate.
## turn the module ‘on’ (enable it) in your httpd.conf (or other configuration file)
GeoIPEnable On
## specify the location of your GeoIP data, i.e. from Maxmind.com
GeoIPDBFile /path/toGeoIP.dat ## optional GeoIPFlag(s) – see the README file…
SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry ## block China
SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry ## block Russia
# … place more countries here
Deny from env=BlockCountry
At this point, if you make the change in your server configuration file and provided you restart the Apache server, any traffic that matches ‘BlockCountry‘ will be denied access with a 403 error (note that this is not a guarantee (see below**) – IP addresses can change so you need to update your GeoIP.dat file to avoid missing target IPs or catching ‘false positives’, for instance, the IP was in China last month but is now in the IP space of some other country…)
How about explicit ‘allow’ by Location?
Ok, reverse the logic and add some more refinements:
GeoIPEnable On ## specify the location of your GeoIP data, i.e. from Maxmind.com GeoIPDBFile /path/toGeoIP.dat ## optional GeoIPFlag(s) - see the README file... SetEnvIf GEOIP_COUNTRY_CODE CN AllowCountry ## allow China SetEnvIf GEOIP_COUNTRY_CODE RU AllowCountry ## allow Russia SetEnvIf GEOIP_COUNTRY_CODE US BlockCountry ## block US SetEnvIf GEOIP_CITY MOSCOW AllowCity ## allow from Moscow SetEnvIf GEOIP_AREA_CODE 404 AllowAreaCode ## from from US area code (phone) # ... add more locations with 'flags' (Allow/Block[Country, City, Area Code, etc.]) Order deny,allow Deny from all Allow from env=AllowCountry Allow from env=AllowAreaCode Allow from env=AllowCity Allow from a.b.c.d ### a specific IP address in the US Allow from a.b.c.0/24 ### a specific IP address range in the US
** What about ‘misses’ or missing GeoIP data?
Blocked countries/regions/cities may still gain access to your server. There are a number of reasons for misses including:
- ‘unknown’ IP addresses (access will be allowed unless you flag ‘unknown’ as a ‘BlockCountry’…)
- access via a third party solution, i.e. Google cache
- access via subterfuge, i.e. via a bot-net machine located in a location that is not blocked
- missing updates to the database
- possibly bad data in the database
In a future post I will provide some coding examples – perhaps PHP, Ruby, Perl and Bash. I may also provide some mod_security rule examples. Remember the three T’s - TEST! TEST! TEST!
Related posts:
- GeoIP and Php – simple examples This is a brief/simple example of using PHP with the...
- Apache, mod_security & GEO-IP I previously posted about using the mod_geoip Apache module to...
- Blocking web SPAM with Apache and Wordpress Ignorance is bliss, right? After many years of publishing traditional...
- It happened to Google – are you next? Well, it happened to Google (and a number of other...
- Converting Server Logs to GeoIP data (kml) – (1) This is part one of a multi-part part post on...