(Plesk for Linux) Setting up IP Geolocation for a Website¶
IP geolocation maps a website visitor’s IP address to their real-world geographical location, for example, a country or a city.
With IP geolocation, you can tailor how to display your website to visitors depending on the place they live in. For example, you can redirect your visitors to location-specific web pages or you can block access to your website for visitors from a specific country.
In this topic, you will learn how to set up IP geolocation in Plesk and how to use IP geolocation with common use cases, such as:
- Blocking access to a website for visitors from a specific country.
- Blocking access to all websites hosted on the server for visitors from a specific country.
- Redirecting website visitors to a geolocation-specific URL.
- Applying geolocation-based decisions to websites that belong to one hosting plan.
- Protecting a website from brute-force attacks from the same country.
Setting up IP Geolocation in Plesk¶
You set up IP geolocation in Plesk using the built-in ngx_http_geoip2_module
nginx module
and MaxMind geolocation databases, which you need to download.
1. Downloading MaxMind Geolocation Databases¶
The MaxMind company offers two geolocation databases: free GeoLite2 and paid GeoIP2, which is more accurate than its free counterpart.
In this topic, we will use the free GeoLite2 database as an example. You can always upgrade it to GeoIP2.
To download the GeoLite2 geolocation database, you first need to create a free GeoLite2 account and then choose how to download the databases. You can do so in the following ways:
Directly download the databases’ archives and then upload them to your Plesk server.
Get permalinks. To download the databases, use these permalinks with scripts or
curl
andget
commands. You will also need to generate and then use a license key for your GeoLite2 account. Learn more how to get and use permalinks.(Recommended) Use the
geoipupdate
utility.We recommend this way of downloading the geolocation databases because this utility is available from system package repositories in major Linux distributions. With the
geoipupdate
utility, you can not only download but also update the geolocation databases.
To download the GeoLite2 geolocation database using the geoipupdate
utility:
Note
To see which utility version is available and the utility settings, run geoipupdate -v
.
Log in to your GeoLite2 account and generate a license key. Once you have done so, copy the key and keep it safe. For security reasons, license keys are shown only when they are generated.
When you generate a license key, you will also see your account ID. You will need both the account ID and the license key at the next step.
Open the
/etc/GeoIP.conf
file for editing. The path to theGeoIP.conf
file may differ depending on your Linux distribution.Paste your account ID, license key, and the edition IDs of the databases you want to download. Separate multiple editions with spaces. Once you complete the setup, save the file.
To download the databases, run
sudo geoipupdate
orsudo geoipupdate -v
(to see the detailed information on which databases are downloaded and where to).
2. Enabling ngx_http_geoip2_module in Plesk¶
In Plesk 18.0.46 and later, nginx is already compiled with ngx_http_geoip2_module. By default, the module is disabled.
Note
To check if nginx is compiled with the module, run nginx -V
. If it is, you will see mod_geoip2
in the output.
To enable ngx_http_geoip2_module:
- Log in to your Plesk server via SSH.
- Enable the module by running
plesk bin nginx -e geoip2
.
The module is enabled. You will see it in the list of enabled nginx modules if you run plesk bin nginx -s
.
3. Configuring variables¶
To use geolocation data and make decisions based on them, you need to map a website visitor’s IP address to various properties (such as a country or city name) and store them as variables in nginx configuration files.
To configure variables:
Add the following directives to the
/etc/nginx/conf.d/geoip2.conf
file:geoip2 <path-to-the-database>/GeoLite2-Country.mmdb { auto_reload 5m; $geoip2_metadata_country_build metadata build_epoch; $geoip2_data_country_code country iso_code; $geoip2_data_country_name country names en; } geoip2 <path-to-the-database>/GeoLite2-City.mmdb { $geoip2_data_city_name city names en; }
Substitute
<path-to-the-database>
with the actual database path, for example, /usr/share/GeoIP/GeoLite2-Country.mmdbOn CentOS, AlmaLinux, and other Red Hat-like operating systems, the default locations of the databases are the following:
/usr/share/GeoIP/GeoLite2-ASN.mmdb
/usr/share/GeoIP/GeoLite2-City.mmdb
/usr/share/GeoIP/GeoLite2-Country.mmdb
On Debian and Ubuntu, the default location of the databases is
/var/lib/GeoIP
.Run the
service nginx reload
command to reload the nginx configuration file.
You have completed setting up IP geolocation in Plesk.
You can now use ngx_http_geoip2_module
with various use cases described below.
To apply these use cases, you need to configure nginx directives referencing the following variables:
Variable name | Variable meaning |
---|---|
$geoip2_metadata_country_build |
Build time of the GeoLite2-Country database |
$geoip2_data_country_code |
Two-letter ISO code of the country |
$geoip2_data_country_name |
Country name in English |
$geoip2_data_city_name |
City name in English |
Blocking Access to a Website For Visitors From a Specific Country¶
You can deny website access to visitors from a specific country. When they try to access the website, they will see the HTTP 403 status code, which means access to the requested resource is forbidden.
To block access to a website for visitors from a specific country:
Go to Websites & Domains > domain > the “Hosting & DNS” tab > Apache & nginx Settings.
Put the following in the “Additional nginx directives” textbox and then click OK.
if ($geoip2_data_country_code = "XX") { return 403; }
Where
XX
is the two-letter ISO code of the country whose visitors you want to block (for example,AQ
for Antarctica).
Visitors from the country whose ISO code you have specified no longer have access to your website.
Redirecting Website Visitors to a Geolocation-specific URL¶
You can redirect visitors who access the general URL (for example, https://example.com/test
) to a country-specific URL (for example, https:// example.com/US/test
).
To redirect website visitors to a geolocation-specific URL:
Go to Websites & Domains > domain > the “Hosting & DNS” tab > Apache & nginx Settings.
Put the following in the “Additional nginx directives” textbox and then click OK.
location = /test { return 301 https://$host/$geoip2_data_country_code/<geolocation-specific-URL-part>; }
Where
<geolocation-specific-URL-part>
is the geolocation-specific URL part (for example,test
).
Visitors, for example, from the United States, will now be redirected to https://example.com/US/test
.
Applying Geolocation-based Decisions to Websites that Belong to One Hosting Plan¶
You can, for example, block or redirect visitors from a specific country but apply it not to one individual website but to all websites that belong to one hosting plan. This case is similar to the two previous ones with an individual website. The only difference is that you need to use not a domain’s but a hosting plan’s nginx settings.
Let’s see how to do so on the example of website access block.
To block access to websites that belong to one hosting plan for visitors from a specific country:
Go to Service Plans and click the name of the service plan access to whose websites you want to block.
Go to the “Web Server” tab, add the following to the “Additional nginx directives” textbox, and then click OK.
if ($geoip2_data_country_code = "XX") { return 403; }
Where
XX
is the two-letter ISO code of the country whose visitors you want to block (for example,AQ
for Antarctica).
Visitors from the country whose ISO code you have specified no longer have access to all websites that belong to the hosting plan.
Block Access to All Websites Hosted on the Server for Visitors From a Specific Country¶
There are two ways to implement this use case: using configuration templates or hosting plan settings. We have described how to use hosting plan settings earlier. Below we will show you how to use custom configuration templates.
Note
You need to use either configuration templates or hosting plan settings.
It is not possible to deny access to all websites hosted on the server by adding the global nginx configuration file to /etc/nginx/conf.d
.
To block access to all websites hosted on the server for visitors from a specific country:
Create a custom configuration template
nginxDomainVirtualHost.php
using this procedure.Find the following text at the end of the copied default template:
<?php if (is_file($VAR->domain->physicalHosting->customNginxConfigFile)) : ?> include "<?php echo $VAR->domain->physicalHosting->customNginxConfigFile ?>"; <?php endif ?> }
And insert your access restriction directives before the right brace as follows:
<?php if (is_file($VAR->domain->physicalHosting->customNginxConfigFile)) : ?> include "<?php echo $VAR->domain->physicalHosting->customNginxConfigFile ?>"; <?php endif ?> if ($geoip2_data_country_code = "XX") { return 403; } }
Where
XX
is the two-letter ISO code of the country whose visitors you want to block (for example,AQ
for Antarctica).Run the following command to check that the modified templates are valid PHP files:
php -l nginxDomainVirtualHost.php
Run the following command to generate new configuration files:
plesk sbin httpdmng --reconfigure-all
Visitors from the country whose ISO code you have specified no longer have access to all websites hosted on the server.
Protecting a Website From Brute-force Attacks From the Same Country¶
You can protect your website from brute-force attacks by limiting requests from IP addresses that have the same ISO country code. You can apply this protection to the following:
- A single website
- All websites that belong to one hosting plan
- All websites hosted on the server
- One or multiple web pages (for example,
example.com/test
)
To protect one or multiple websites from brute-force attacks from the same country:
Add the directive of the following pattern to the
/etc/nginx/conf.d/limit_req_zone.conf
file:limit_req_zone $geoip_data_country_code zone=country_code:10m rate=5r/m;
This creates a memory zone shared among nginx worker processes. The zone stores the state of each IP address and how often it has accessed a request‑limited URL. The directive above limits requests from IP addresses with the same ISO country code to five per minute (
rate=5r/m
).The second step varies depending on which and how many websites you want to protect:
(A single website) Go to Websites & Domains > domain > the “Hosting & DNS” tab > Apache & nginx Settings, put the following in the “Additional nginx directives” textbox, and then click OK:
limit_req zone=country_code;
(All websites that belong to one hosting plan) Go to Service Plans and click the name of the service plan whose websites you want to protect. Then go to the “Web Server” tab, add the following to the “Additional nginx directives” textbox, and click OK:
limit_req zone=country_code;
(All websites hosted on the server) Put the following to the
/etc/nginx/conf.d/limit_req.conf
file:limit_req zone=country_code;
You have limited requests to one or multiple websites from IP addresses with the same country ISO code to five per minute.
You can also protect a single or multiple web pages by limiting requests from IP addresses that have the same ISO country code. The procedure differs depending on your website hosting type:
- Apache+nginx hosting
- nginx-only hosting
- nginx configured to serve PHP directly
(Apache+nginx hosting) To protect a particular web page from brute-force attacks from the same country:
Add the directive of the following pattern to the
/etc/nginx/conf.d/limit_req_zone.conf
file:limit_req_zone $geoip_data_country_code zone=country_code:10m rate=5r/m;
This creates a memory zone shared among nginx worker processes. The zone stores the state of each IP address and how often it has accessed a request‑limited URL. The directive above limits requests from IP addresses with the same ISO country code to five per minute (
rate=5r/m
).Create a custom configuration template
nginxDomainVirtualHost.php
using this procedure.Find the following text at the end of the copied default template:
<?php if ($VAR->domain->physicalHosting->proxySettings['nginxProxyMode']): ?> location / { <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> proxy_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/proxy.php', $OPT) ?> }
And insert your directives after it as follows replacing
example.com
with your domain name and/test
—with the exact web page you want to apply the limit to:<?php if ($VAR->domain->physicalHosting->proxySettings['nginxProxyMode']): ?> location / { <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> proxy_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/proxy.php', $OPT) ?> } <?php if ($VAR->domain->asciiName == 'example.com'): ?> location = /test { limit_req zone=country_code; <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> proxy_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/proxy.php', $OPT) ?> } <?php endif ?>
Run the following command to check that the modified templates are valid PHP files:
php -l nginxDomainVirtualHost.php
Run the following command to generate new configuration files:
plesk sbin httpdmng --reconfigure-all
You have limited requests to the web page from IP addresses with the same country ISO code to 5 per minute.
(nginx-only hosting) To protect a particular web page from brute-force attacks from the same country:
Add the directive of the following pattern to the
/etc/nginx/conf.d/limit_req_zone.conf
file:limit_req_zone $geoip_data_country_code zone=country_code:10m rate=5r/m;
This creates a memory zone shared among nginx worker processes. The zone stores the state of each IP address and how often it has accessed a request‑limited URL. The directive above limits requests from IP addresses with the same ISO country code to five per minute (
rate=5r/m
).Go to Websites & Domains > domain > the “Hosting & DNS” tab > Apache & nginx Settings.
Put the following in the “Additional nginx directives” textbox replacing
/test
with the exact web page you want to apply the limit to:location = /test { limit_req zone=country_code; }
Click OK.
You have limited requests to the web page from IP addresses with the same country ISO code to 5 per minute.
(nginx serves PHP directly) To protect a particular PHP script from brute-force attacks from the same country:
Add the directive of the following pattern to the
/etc/nginx/conf.d/limit_req_zone.conf
file:limit_req_zone $geoip_data_country_code zone=country_code:10m rate=5r/m;
This creates a memory zone shared among nginx worker processes. The zone stores the state of each IP address and how often it has accessed a request‑limited URL. The directive above limits requests from IP addresses with the same ISO country code to five per minute (
rate=5r/m
).Create a custom configuration template
nginxDomainVirtualHost.php
using this procedure.Find the following text at the end of the copied default template:
location ~ \.php(/.*)?$ { <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> fastcgi_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/fpm.php', $OPT) ?> }
And insert the following directives before the text including
limit_req
and replacingexample.com
with your domain name and/test\.php
—with the exact PHP script you want to apply the limit to:<?php if ($VAR->domain->asciiName == 'example.com'): ?> location ~ ^/test\.php$ { limit_req zone=country_code; <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> fastcgi_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/fpm.php', $OPT) ?> } <?php endif ?> location ~ \.php(/.*)?$ { <?php if ($VAR->domain->physicalHosting->scriptTimeout): ?> fastcgi_read_timeout <?php echo min($VAR->domain->physicalHosting->scriptTimeout, 2147483) ?>; <?php endif ?> <?php echo $VAR->includeTemplate('domain/service/fpm.php', $OPT) ?> }
Run the following command to check that the modified templates are valid PHP files:
php -l nginxDomainVirtualHost.php
Run the following command to generate new configuration files:
plesk sbin httpdmng --reconfigure-all
You have limited requests to the PHP script from IP addresses with the same country ISO code to 5 per minute.