How to Configure the Nginx Geoip2 Module for Country-based Traffic Routing and Access Control on Ubuntu Server

Learning how to configure the Nginx GeoIP2 module for country-based traffic routing and access control on Ubuntu Server gives you powerful control over who can access your web applications. Whether you want to block traffic from specific regions, redirect users to localized content, or restrict sensitive areas of your site, GeoIP2 makes it possible directly at the web server level. This approach is faster and more efficient than handling geo-restrictions at the application layer. In this tutorial, you’ll install the required MaxMind GeoIP2 database, compile or install the Nginx GeoIP2 module, and write real configuration rules that route and restrict traffic based on country codes.

Prerequisites and Requirements for Nginx GeoIP2 Country-based Routing

Before you start, make sure you have the following in place.

Required software and access:

  • Ubuntu Server 20.04 or 22.04 (fresh or existing install)
  • Nginx already installed (version 1.18 or later recommended)
  • Root or sudo access to the server
  • A free MaxMind account to download the GeoLite2 database
  • Basic familiarity with the Linux command line and Nginx config files

Estimated time: 30–45 minutes.

You’ll need a MaxMind account to get the GeoLite2-Country database. Sign up free at MaxMind’s official site. After signing up, generate a license key from your account dashboard. You’ll use this key to download and auto-update the database. Keep it handy before moving to the next section.

Installing the GeoIP2 Module and MaxMind Database on Ubuntu

Related tutorial: How to Provision a Digitalocean Droplet with Terraform and Run Post-deployment Scripts

This section walks you through installing all the required components step by step.

Step 1: Update your package list

Always start with a system update. This ensures you install the latest available packages.

sudo apt update && sudo apt upgrade -y

Step 2: Install the libmaxminddb library

This C library lets Nginx read the MaxMind binary database format. Install it now.

sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin -y

Step 3: Install the Nginx GeoIP2 module

If you’re running Nginx from the default Ubuntu repositories, install the dynamic module package directly.

sudo apt install libnginx-mod-http-geoip2 -y

This installs the module as a dynamic module. It also drops a load directive into your Nginx configuration automatically on most Ubuntu setups.

Step 4: Install the geoipupdate tool

MaxMind provides a tool called geoipupdate that downloads and refreshes the database automatically.

sudo apt install geoipupdate -y

Step 5: Configure geoipupdate with your MaxMind credentials

Open the configuration file for editing.

sudo nano /etc/GeoIP.conf

Replace the placeholder values with your actual MaxMind account ID and license key.

AccountID YOUR_ACCOUNT_ID
LicenseKey YOUR_LICENSE_KEY
EditionIDs GeoLite2-Country GeoLite2-City

Save and close the file. Then run the updater to download the databases.

sudo geoipupdate

The databases will download to /usr/share/GeoIP/ by default. Confirm they exist.

ls /usr/share/GeoIP/

You should see GeoLite2-Country.mmdb and GeoLite2-City.mmdb listed.

Step 6: Verify the module loads correctly

Check that Nginx can load the GeoIP2 module without errors.

sudo nginx -t

If you see a warning about the module not being loaded, add this line to the top of your /etc/nginx/nginx.conf file manually.

load_module modules/ngx_http_geoip2_module.so;

Run sudo nginx -t again to confirm no errors appear.

How to Configure the Nginx GeoIP2 Module for Country-based Traffic Routing

Now you’ll write the actual Nginx configuration rules. This is where you define routing and access control logic based on country codes.

Step 7: Add GeoIP2 directives to your nginx.conf

Open your main Nginx configuration file.

sudo nano /etc/nginx/nginx.conf

Inside the http block, add the following GeoIP2 configuration.

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
    auto_reload 5m;
    $geoip2_metadata_country_build metadata build_epoch;
    $geoip2_data_country_code default=US source=$remote_addr country iso_code;
    $geoip2_data_country_name country names en;
}

This block tells Nginx to read the country database, auto-reload it every 5 minutes, and expose two variables: $geoip2_data_country_code and $geoip2_data_country_name.

Step 8: Create a map block to define allowed countries

Still inside the http block, add a map directive. This controls which countries are allowed.

map $geoip2_data_country_code $allowed_country {
    default yes;
    CN no;
    RU no;
    KP no;
}

This example blocks traffic from China (CN), Russia (RU), and North Korea (KP). All other countries are allowed by default. Adjust the country codes to match your needs. You can find ISO 3166-1 alpha-2 codes in the official Nginx GeoIP documentation.

Step 9: Apply access control in your server block

Open your site’s server block configuration file.

sudo nano /etc/nginx/sites-available/your-site.conf

Inside the server block or a specific location block, add this rule.

if ($allowed_country = no) {
    return 403;
}

This returns a 403 Forbidden response to any visitor from a blocked country.

Step 10: Add country-based traffic routing

You can also redirect users to country-specific pages instead of blocking them. Add this inside your server block.

if ($geoip2_data_country_code = "DE") {
    return 301 https://yourdomain.com/de/;
}

if ($geoip2_data_country_code = "FR") {
    return 301 https://yourdomain.com/fr/;
}

German visitors go to the German page. French visitors go to the French page. All others see the default site.

Step 11: Reload Nginx to apply changes

Test your configuration first.

sudo nginx -t

If the test passes, reload Nginx.

sudo systemctl reload nginx

Troubleshooting Common Nginx GeoIP2 Configuration Issues

Even with careful setup, things can go wrong. Here are the most common problems and their fixes.

Problem: “unknown directive geoip2” error

This means the module isn’t loaded. Add load_module modules/ngx_http_geoip2_module.so; to the very top of nginx.conf, before the events block.

Problem: Database file not found

Run sudo geoipupdate again and check that the .mmdb files exist in /usr/share/GeoIP/. Double-check your credentials in /etc/GeoIP.conf.

Problem: All visitors get blocked or see the wrong country

If you’re behind a load balancer or proxy, $remote_addr may return the proxy IP. Use $http_x_forwarded_for as the source instead.

$geoip2_data_country_code default=US source=$http_x_forwarded_for country iso_code;

Problem: GeoIP2 database goes stale

Set up a weekly cron job to auto-update.

sudo crontab -e

Add this line to run the update every Sunday at 2 AM.

0 2   0 /usr/bin/geoipupdate && systemctl reload nginx

Tip: Always test with sudo nginx -t before reloading. A bad config file will take your site offline.

Conclusion

You’ve

Similar Posts