Recently, automated malicious traffic originating from different networks, mass requests from bots, and DDoS-like attacks against websites and services have become increasingly common. In addition, various crawlers, AI bots and other automated clients can also generate significant load.
In some cases, it may also be necessary to restrict access to a website based on the visitor’s country – for example, if the service is intended only for users from specific countries or if unnecessary traffic from regions where no actual customers are expected should be reduced.
For this purpose, we have added GeoIP-based country access restriction functionality to our servers.
1. Adding/enabling GeoIP restrictions and examples
2. Enabling GeoIP restrictions while allowing search engine crawlers from a blocked country
3. Server-side restriction added by the automated security monitor
GeoIP-based restrictions allow access to a website to be permitted or denied based on the country associated with the visitor’s IP address.
On our servers, GeoIP country information is already available to the Apache web server through the following environment variable:
MM_COUNTRY_CODE
Its value is normally a two-letter ISO country code, for example:
EE = Estonia FI = Finland SE = Sweden US = United States CN = China
A more detailed list can be found HERE, and the ISO country code is listed in the “Alpha-2 code” column!
Customers do not need to enable the GeoIP database or Apache module separately. Restrictions can be added to the website’s .htaccess file.
For example, to block China, Russia and the United States:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{ENV:MM_COUNTRY_CODE} ^(CN|RU|US)$ [NC]
RewriteRule ^ - [F,L]
</IfModule>
In this case, visitors from all other countries will continue to have normal access to the website.
For example, if the website is intended only for users from Estonia, Finland, Latvia, Lithuania and Sweden:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{ENV:MM_COUNTRY_CODE} !^$
RewriteCond %{ENV:MM_COUNTRY_CODE} !^(EE|FI|LV|LT|SE)$ [NC]
RewriteRule ^ - [F,L]
</IfModule>
The first condition:
RewriteCond %{ENV:MM_COUNTRY_CODE} !^$
is important. It prevents a situation where all visitors are accidentally blocked if GeoIP information is unavailable or a temporary error occurs.
If desired, blocked visitors can be shown a custom error page instead of the standard βForbiddenβ message:
ErrorDocument 403 /geo-blocked.html
For example:
# BEGIN GeoIP Block
<If "reqenv('MM_COUNTRY_CODE') != '' && reqenv('MM_COUNTRY_CODE') !~ m#^(EE|FI|LV|LT|SE)$#">
ErrorDocument 403 /geo-blocked.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/geo-blocked\.html$
RewriteRule ^ - [F,L]
</IfModule>
</If>
# END GeoIP Block
The geo-blocked.html file must be located in the website’s document root and must itself be accessible through the web server.
The blocked request will still return the HTTP status:
403 Forbidden
GeoIP detection is based on an IP address geolocation database and is not 100% accurate. When using a VPN, proxy, mobile operator, cloud service or another intermediary network, the detected country may differ from the user’s actual location.
Country-based blocking should therefore be used as an additional traffic restriction and security measure, not as absolute proof of a user’s physical location.
When applying country-based restrictions, keep in mind that search engine crawlers may also make requests from countries whose traffic has been blocked on the website.
For example, Googlebot may make requests from the United States. If US is blocked, this may interfere with indexing of the website by Google Search.
It is not recommended to allow Googlebot solely based on the User-Agent header, as this value can easily be spoofed.
Apache can verify the origin of Googlebot using DNS. For example, traffic from Estonia, Finland, Latvia, Lithuania and Sweden can be allowed while also permitting verified Googlebot:
<IfModule mod_authz_core.c>
<IfModule mod_authz_host.c>
<RequireAny>
# Allowed countries
Require expr "reqenv('MM_COUNTRY_CODE') =~ m#^(EE|FI|LV|LT|SE)$#"
# If no GeoIP result is available, do not block the visitor
Require expr "reqenv('MM_COUNTRY_CODE') == ''"
# Verified Googlebot
Require host googlebot.com
</RequireAny>
</IfModule>
</IfModule>
Require host googlebot.com does not simply trust the name presented by the browser or bot. Apache performs a reverse DNS lookup on the IP address and then verifies the resulting hostname again using a forward DNS lookup.
Therefore, simply spoofing the Googlebot User-Agent header is not sufficient to gain access.
NB! This configuration must be used instead of the previous GeoIP RewriteRule ... [F] blocking rule, not in addition to it.
If only regular users from the United States should be blocked while Googlebot remains allowed, the following can be used:
<RequireAny>
Require expr "reqenv('MM_COUNTRY_CODE') != 'US'"
Require expr "reqenv('MM_COUNTRY_CODE') == ''"
Require host googlebot.com
</RequireAny>
In addition to the customer’s own .htaccess rules, the server-side security monitor may detect unusually high or malicious traffic and, when necessary, additionally apply a temporary GeoIP-based restriction.
The purpose of such a restriction is to reduce, for example:
A server-side restriction may be applied to a specific domain or service and does not depend on the contents of the customer’s own .htaccess file.
Such a restriction may be temporary and may be changed or removed after the problematic traffic has stopped.
If website visitors unexpectedly receive a country-based 403 error, check the .htaccess file in the domain or account root directory to see whether the following lines have been added (the contents of “(FI|EE|LT|LV|SE)” may differ, but the line “# BEGIN automated GeoIP Block” will be present):
# BEGIN automated GeoIP Block
<If "reqenv('MM_COUNTRY_CODE') != '' && reqenv('MM_COUNTRY_CODE') !~ m#^(FI|EE|LT|LV|SE)$#">
ErrorDocument 403 "<div style='text-align:center'><b>403</b> - Access to this website is restricted based on IP geolocation</div>"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ - [F,L]
</IfModule>
</If>
# END automated GeoIP Block
If desired, the contents between the BEGIN and END tags can be modified or removed entirely once the issue has passed and you wish to reopen access to the website from countries other than those specified in the corresponding rules.