In many web development and system administration scenarios, knowing the geographical origin of a request is essential. Whether you are tailoring content for specific regions, managing security by identifying high-risk ASNs, or simply improving your analytics, moving geolocation logic to the web server level is more efficient than handling it within the application layer.

This guide covers how to compile, install, and configure mod_maxminddb to inject GeoIP2 data directly into Apache environment variables.
1. Prerequisites
Before starting, ensure your system has the necessary development headers and build tools. You will need the Apache development package and the MaxMind DB library.
apt install apache2-dev libmaxminddb-dev build-essential
2. Installation from Source
While some repositories offer pre-built packages, compiling from source ensures you have the latest version compatible with your specific environment.
Option A: Using the Release Tarball
wget https://github.com/maxmind/mod_maxminddb/releases/download/1.3.0/mod_maxminddb-1.3.0.tar.gz
tar -xvf mod_maxminddb-1.3.0.tar.gz
cd mod_maxminddb-1.3.0
./configure
make
make install
Option B: Using Git (Development Version)
cd /usr/local/src
git clone [https://github.com/maxmind/mod_maxminddb.git](https://github.com/maxmind/mod_maxminddb.git)
cd mod_maxminddb
./bootstrap
./configure
make
make install
After installation, enable the module and reload Apache:
a2enmod maxminddb
systemctl reload apache2
3. Configuration
The following configuration defines which MaxMind database files to use and maps specific database fields to environment variables. This example assumes your .mmdb files are located in /usr/share/GeoIP/.
Create the configuration file at /etc/apache2/conf-available/maxminddb.conf:
<IfModule mod_maxminddb.c>
MaxMindDBEnable On
# Path to GeoLite2 or GeoIP2 database files
MaxMindDBFile CITY_DB /usr/share/GeoIP/GeoLite2-City.mmdb
MaxMindDBFile COUNTRY_DB /usr/share/GeoIP/GeoLite2-Country.mmdb
MaxMindDBFile ASN_DB /usr/share/GeoIP/GeoLite2-ASN.mmdb
# Export ASN Data
MaxMindDBEnv MM_ASN ASN_DB/autonomous_system_number
MaxMindDBEnv MM_ASORG ASN_DB/autonomous_system_organization
MaxMindDBNetworkEnv ASN_DB ASN_DB_NETWORK
# Export City and Location Data
MaxMindDBEnv MM_COUNTRY_CODE CITY_DB/country/iso_code
MaxMindDBEnv MM_COUNTRY_NAME CITY_DB/country/names/en
MaxMindDBEnv MM_CITY_NAME CITY_DB/city/names/en
MaxMindDBEnv MM_LONGITUDE CITY_DB/location/longitude
MaxMindDBEnv MM_LATITUDE CITY_DB/location/latitude
MaxMindDBNetworkEnv CITY_DB CITY_DB_NETWORK
# Populate $_SERVER variables for PHP/CGI using RewriteEngine
RewriteEngine On
RewriteCond %{ENV:MM_ASN} .+
RewriteRule .* - [E=MM_ASN:%{ENV:MM_ASN}]
RewriteCond %{ENV:MM_ASORG} .+
RewriteRule .* - [E=MM_ASORG:%{ENV:MM_ASORG}]
RewriteCond %{ENV:ASN_DB} .+
RewriteRule .* - [E=ASN_DB:%{ENV:ASN_DB}]
RewriteCond %{ENV:MM_COUNTRY_CODE} .+
RewriteRule .* - [E=MM_COUNTRY_CODE:%{ENV:MM_COUNTRY_CODE}]
RewriteCond %{ENV:MM_COUNTRY_NAME} .+
RewriteRule .* - [E=MM_COUNTRY_NAME:%{ENV:MM_COUNTRY_NAME}]
RewriteCond %{ENV:MM_CITY_NAME} .+
RewriteRule .* - [E=MM_CITY_NAME:%{ENV:MM_CITY_NAME}]
RewriteCond %{ENV:MM_LATITUDE} .+
RewriteRule .* - [E=MM_LATITUDE:%{ENV:MM_LATITUDE}]
RewriteCond %{ENV:MM_LONGITUDE} .+
RewriteRule .* - [E=MM_LONGITUDE:%{ENV:MM_LONGITUDE}]
RewriteCond %{ENV:CITY_DB} .+
RewriteRule .* - [E=CITY_DB:%{ENV:CITY_DB}]
# Update Log Formats to include ASN and Organization
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" \"%{MM_ASORG}e\" %{MM_ASN}e" vhost_combined_geoip
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" \"%{MM_ASORG}e\" %{MM_ASN}e" combined
</IfModule>
4. Activation and Verification
Enable the new configuration and reload the service:
a2enconf maxminddb
systemctl reload apache2
Summary of Benefits
By implementing mod_maxminddb, you achieve:
Lower Latency: Geolocation lookup happens in C during the request phase, avoiding the overhead of external APIs or heavyweight language libraries.
Enhanced Logging: Your access logs will now contain ASN and Organization data, which is invaluable for identifying traffic patterns or DDoS sources. It can be easily used to set a Fail2Ban filter, or get stats by ASN.
Application Integration: Since the variables are exported to the environment, they are automatically available in PHP via
$_SERVER['MM_CITY_NAME']or similar variables in other languages.

Comments
Leave a Comment