NGINX: Blocking users by country

Updated: January 19, 2024 By: Guest Contributor Post a comment

Introduction

NGINX is a powerful web server that can also be used as a reverse proxy, load balancer, mail proxy, and HTTP cache. In some cases, there may be a need to block traffic from specific countries for security, compliance, or traffic management reasons. In this extensive tutorial, we’ll guide you through the process of blocking users by country using NGINX.

Prerequisite Knowledge

Before proceeding, you should have a basic understanding of NGINX, server configuration, and SSH access to your server. Additionally, you should have the GeoIP database downloaded, as this is required for determining the user’s country based on their IP address.

Getting Started with GeoIP

Our first step involves installing the GeoIP module and dependencies on your server. You can typically do this via package manager:

sudo apt-get install nginx libnginx-mod-http-geoip

Once installed, it’s time to configure NGINX to use GeoIP by editing the NGINX configuration file:

sudo nano /etc/nginx/nginx.conf

Add the following lines to the nginx.conf file. Please ensure that the path corresponds to where the GeoIP databases are located on your system:

http {
    ...
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    ...
}

Blocking a Single Country

Now, let’s start by blocking a single country. In this example, we’ll block traffic coming from a specific country, let’s say ‘CN’ for China:

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $blocked_country {
    default 0;
    CN 1;
}

server {
    ...
    if ($blocked_country) {
        return 403;
    }
    ...
}

This configuration will serve a 403 Forbidden error to any traffic from China.

Implement Advanced Country Blocking

Now, for a more advanced setup: You may want to block multiple countries and possibly incorporate logging to understand who gets blocked. To block both China and Russia (‘RU’), and log the attempts, you can expand the previous setup:

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $blocked_country {
    default 0;
    CN 1;
    RU 1;
}

server {
    ...
    if ($blocked_country) {
        access_log /path/to/your/blocked.log blocked;
        return 403;
    }
    ...
}

Make sure to replace ‘/path/to/your/’ with the actual path where you’d like to store the logs regarding the blocked attempts.

Blocking with Whitelisting

In some cases, you may want to allow one or two countries and block the rest of the world. To implement this, use a whitelist approach:

map $geoip_country_code $allowed_country {
    default 1;
    US 0;
    CA 0;
}

server {
    ...
    if ($allowed_country) {
        return 403;
    }
    ...
}

This configuration allows only traffic from the United States (‘US’) and Canada (‘CA’), blocking all other countries.

Testing Your Configuration

After making changes in your NGINX configuration, it’s always a good idea to test the configuration and restart NGINX:

sudo nginx -t
sudo service nginx restart

The nginx -t command checks for syntax errors and lets you know if any needs to be corrected. After ensuring that there are no errors, proceed with restarting NGINX to apply the new configurations.

Using Third-Party Modules

If you need more advanced geo-blocking capabilities, you might consider using third-party modules like ngx_http_geoip2_module. This module provides more functionality and works with the newer GeoIP2 databases. The installation process and configuration for these modules will vary, so refer to the specific module documentation for guidance.

Conclusion

In this tutorial, we walked through setting up country-based blocking in NGINX using the GeoIP module. This method is effective for managing incoming traffic strategically and can be critical for regulating access and strengthening server security.