All our shared/enterprise/reseller hosting servers include the MaxMind DB module, which uses a database to map a website visitor's IP address to their country. This can be used to deny/allow access to your website from specific regions.
Please note:
- The MaxMind DB database has been compiled by MaxMind, a third-party provider.
- The country database is estimated to have 99.8% accuracy, but that isn't perfect, so it should not be used for critical applications.
- New IP ranges will take some time to appear in the database or may be mapped to the wrong country initially.
- Users can always get around a country allow/deny access by using a VPN/proxy.
- Multinational corporations often have an IP range based on where their headquarters are, this could result in false positive results for these users.
- Mod_GeoIP is the legacy module that was discontinued and has been replaced by Mod_MaxMindDB.
- You can find information about Mod_MaxMindDB here: mod_maxminddb - an Apache module that allows you to query MaxMind DB files
Enable MaxMind DB on your website
The MaxMind DB module is usually pre-enabled on the server configuration level, but if you want to assure that it's actually enabled, you can add the following 3 lines to the top of your .htaccess
file:
<IfModule mod_maxminddb.c> MaxMindDBEnable On </IfModule>
You can also change the setting from On
to Off
if you want to temporarily disable the module and the associated rules, for example while testing the configuration.
If you do not have a .htaccess
file, simply create one in the main directory of your website. The main directory is normally called public_html
unless you are working with a sub-domain or addon domain, which will have its own directory.
MaxMind DB Variables
The main MaxMind DB variables that are made available on our server to your website are:
MM_ASN - Autonomous System Number (ASN)
MM_ASORG - ASN Organisation Name
MM_CONTINENT_CODE - Continent Code
MM_CONTINENT_NAME_EN - Continent Name MM_COUNTRY_CODE - Country Code MM_COUNTRY_NAME - Country Name MM_CITY - City Name MM_POSTAL_CODE - Postal Code MM_LOCATION_TIME_ZONE - Location Time-zone MM_LOCATION_LATITUDE - Approximate Latitude Coordinates
MM_LOCATION_LONGITUDE - Approximate Longitude Coordinates
There are also other variables that we have enabled, but the above are usually the most relevant.
In this guide we'll concentrate on MM_COUNTRY_CODE
which outputs a 2-digit ISO country code, from AF (Afghanistan) to ZW (Zimbabwe). The full list of country codes can be found here: https://www.nationsonline.org/oneworld/country_code_list.htm
We will provide four examples, to deny access, to allow access, to redirect visitors and to use in PHP code.
Example 1 - Deny access from 3 countries with Deny rule
In this example, the code will deny access from visitors in 4 countries: RU (Russia), CN (China) and US (United States).
Add this to your .htaccess
file:
<IfModule mod_maxminddb.c>
SetEnvIf MM_COUNTRY_CODE ^(RU|CN|US) BlockCountry
Order Deny,Allow
Deny from env=BlockCountry
Allow from All
</IfModule>
Any users from RU, CN or US will encounter a "403 Forbidden" error when visiting the website.
Example 2 - Allow access from only 2 countries with Allow rule
In this example, the code will allow access from visitors in two countries only, DE (Germany) and GB (United Kingdom).
Add this to your .htaccess
file:
<IfModule mod_maxminddb.c>
SetEnvIf MM_COUNTRY_CODE ^(DE|GB) PermitCountry
Order Deny,Allow
Deny from All
Allow from env=PermitCountry
</IfModule>
Any users not from DE or GB will encounter a "403 Forbidden" error when visiting the website.
Example 3 - Deny access from 3 countries with Mod_Rewrite
In this example, the code will use Mod_Rewrite and deny access to visitors in 3 countries (Ireland, United Kingdom, Netherlands). Any other countries will be able to access the website normally.
Add this to your .htaccess
file:
<IfModule mod_maxminddb.c>
RewriteEngine on
RewriteCond %{ENV:MM_COUNTRY_CODE} ^(IE|GB|NL)
RewriteRule .* - [F]
</IfModule>
Any users from the 3 countries will encounter a "403 Forbidden" error when visiting the website.
Example 4 - Redirect access from 3 countries with Mod_Rewrite
In this example, the code will redirect visitors in 3 countries (Ireland, United Kingdom, Netherlands) to Google. Any other countries will be able to access the website normally.
Add this to your .htaccess
file:
<IfModule mod_maxminddb.c>
RewriteEngine on
RewriteCond %{ENV:MM_COUNTRY_CODE} ^(IE|GB|NL)$
RewriteRule ^(.*)$ https://google.com/$1 [L]
</IfModule>
If you want to switch it around so only those 3 countries are allowed access and all other countries are redirected, you would include a !
symbol before the list of country codes, like this:
RewriteCond %{ENV:MM_COUNTRY_CODE} !^(IE|GB|NL)$
Example 5 - Allow specific user agents and search engine bots
In this example, the code will allow specific user agents to access your site, for example uptime monitoring services, search engine bots or other external services that you may use. It is important to allow search engine bots to your site, regardless of their location, otherwise your site may be delisted and your search engine rankings may be affected. For this reason it's always important to apply geo-restrictions with caution.
<IfModule mod_maxminddb.c>
SetEnvIfNoCase User-Agent .*pingdom.* allowed_user_agents
SetEnvIfNoCase User-Agent .*Googlebot.* allowed_user_agents
SetEnvIfNoCase User-Agent .*Google-InspectionTool.* allowed_user_agents
SetEnvIfNoCase User-Agent .*Storebot-Google.* allowed_user_agents
Allow from env=allowed_user_agents
</IfModule>
For an overview of the Google crawlers, please check this article: Google Crawler (User Agent) Overview | Google Search Central | Documentation | Google for Developers
Please remember that malicious bots and hackers can manipulate their user agent to impersonate search engine bots to bypass restrictions.
Please also note that these rules will not work if there are any prior Order
and Deny
rules that could override them.
Example 6 - Allow access from specific countries, but block certain IP addresses from those countries
In this example, we will first allow access from specific countries only with Mod_Rewrite, then block three IP addresses from one of those countries with Allow/Deny rules:
Let's allow access only from Germany and Spain by adding this to your .htaccess
file:
<IfModule mod_maxminddb.c>
RewriteEngine on
RewriteCond %{ENV:MM_COUNTRY_CODE} !^(DE|ES)
RewriteRule .* - [F]
</IfModule>
Now we'll block three IP addresses, which we'd assume to be from Germany and Spain in this example:
<Files 403.shtml>
order allow,deny
allow from all
</Files>
deny from 12.34.56.78
deny from 23.45.67.89
deny from 34.56.78.90
Any users from those three IP addresses and from non-allowed countries will encounter a "403 Forbidden" error when visiting the website, while all others from the allowed countries will be able to access it.
This set of rules is recommended if you restrict IPs on the "IP Blocker" page in cPanel.
Example 7 - Block access from specific Autonomous System Numbers (ASNs) and Organisations
This will be a more advanced example where we would block IP addresses based on their ASN or ASN Organisation. This is useful if you need to block specific providers who may have servers and IP addresses at multiple locations across the globe.
An Autonomous System Number (ASN) is like a unique address assigned to a provider on the internet. The ASN can contain multiple IP ranges that belong to a specific provider.
For example, if we'd want to block an ASN that belongs to Amazon Web Services (AWS), we would add this set of rules:
<IfModule mod_maxminddb.c>
SetEnvIf MM_ASN ^(16509) BlockASN
Order Deny,Allow
Deny from env=BlockASN
Allow from All
</IfModule>
Since companies and providers can hold multiple ASNs, we can also block them by the ASN organisation name:
<IfModule mod_maxminddb.c>
SetEnvIf MM_ASORG ^(AMAZON) BlockASNOrg
Order Deny,Allow
Deny from env=BlockASNOrg
Allow from All
</IfModule>
This would block all IPs that belong to an ASN of which organisation name starts with "AMAZON" (e.g. AMAZON-01, AMAZON-02, etc.).
These rules should be used with caution, as some providers like AWS hold tens of millions of IP addresses from data centers across the globe that are used by a very large number of businesses and services.
The ASNs can be found and looked up here:
Many WHOIS databases will list the ASN as well.
Example 8 - Use the variable in PHP code
In this example, we will use PHP code to output the country code and country name. Add this code to a PHP file:
<?php print "Your 2-digit country code is " . $_SERVER['MM_COUNTRY_CODE'] . " so you are visiting from " .$_SERVER['MM_COUNTRY_NAME'];
This example will print a message to visitors from Canada, then use the exit()
function to prevent the rest of the web page from loading:
<?php if ($_SERVER['MM_COUNTRY_CODE'] === 'CA') { print "Visitors from Canada are blocked."; exit(); }
Allowing Certificate Authorities (CAs) to Complete the Domain Validation
For AutoSSL and Let's Encrypt, but also for all other Certificate Authorities (CAs), it is necessary to add exceptions to allow them to complete the HTTP DCV (Domain Control Validation) to validate your domain name and have the SSL certificate issued or renewed, regardless of the origin of the IP address from which they attempt the validation.
For this, it is necessary to add a SetEnvIf User-Agent
and an Allow from
rule to allow the CA user agents to access your site despite any geo-restrictions.
Add the following rule below the last SetEnvIf
rule:
SetEnvIf User-Agent "^.*(Cpanel-HTTP-Client|Let's Encrypt validation server).*$" PermitUserAgent
The highlighted part can be extended by adding additional user agents separated by a vertical bar (|
).
Add the following rule above the last Allow from
rule:
Allow from env=PermitUserAgent
Here is a full example:
<IfModule mod_maxminddb.c>
SetEnvIf MM_COUNTRY_CODE ^(RU|CN|US) BlockCountry
SetEnvIf User-Agent "^.*(Cpanel-HTTP-Client|Let's Encrypt validation server).*$" PermitUserAgent
Order Deny,Allow
Deny from env=BlockCountry
Allow from env=PermitUserAgent
Allow from All
</IfModule>
Applying the Rules for All Domains
If your account has multiple addon domains, it can be challenging to add the rules and keep them in sync for all domains. There's a simple solution for this by adding all rules to the .htaccess
file in the home directory (e.g. /home/user/.htaccess
), which will act recursively and impact all websites / directories of the entire account. This file does not exist by default, you may need to create it first.
When using an .htaccess
file in the home directory, it's still possible to add more rules to the other .htaccess
files (in the addon domains' document root directories, public_html
directory or any other directories), but please keep in mind that the rules in the home directory apply recursively, possibly causing a redirect loop or unexpected behaviour if there's a conflict between the other rules. Rigorous testing is recommended for such setups.
An overview of the directories:
Final Note
We recommend implementing any country deny/allow rules or .htaccess
rewrite rules in conjunction with your website developer / IT person.
DISCLAIMER: The scripts provided in our knowledgebase are for informational purposes only. We do not provide any warranty or support. It is essential to review and modify the scripts to fit your site's specific needs. There may be unforeseen outcomes when adding new script code to an existing website. You should discuss it with your website manager and seek advice from an experienced website developer if you are unsure.
Updated by SP on 10/04/2024