1

In Nginx I am checking to see if an IP is coming from a blocked country. If it is then the visitor gets a 403. I need the capability to add whitelisted IPs to allow them in even if they are part of the blocked countries.

I would prefer to whitelist the IPs at the nginx.conf location so I don't need to update 30+ virtual host files. How can I do this?

In each of the nginx virtual host files in /etc/nginx/sites-enabled

location / { if ($allowed_country = no) { return 403; } try_files $uri $uri/ /index.php$is_args$args; } 

The country list is created in /etc/nginx/nginx.conf

## GEOIP settings geoip_country /usr/share/GeoIP/GeoIP.dat; map $geoip_country_code $allowed_country { default yes; RU no; BR no; UA no; PH no; IN no; CN no; } 

2 Answers 2

2

To have an filter on geoip country as well as IP Adress you need geo module Resulting in something as:

location / { if ($allowed_country = no) { return 403; } if ($allowed_ip = no) { return 403; } try_files $uri $uri/ /index.php$is_args$args; } 

Plus the mapping in nginx.conf

geo $allowed_ip { default no; 127.0.0.1 yes; 192.168.1.0/24 yes; } 

This should be possible but the map directive has to be under the http context.

I would suggest to have an include in every vhost, having the geoip settings in a separate file, to be more flexible.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi Ben, This geoip is already in a separate file (GeoIP.dat) and country blocking is working correctly. The include is already a part of the nginx.conf file. I am looking for a way to add whitelisted IPs to this functionality but I do not know the syntax for including it either in the map $geoip_country_code $allowed_country function in the nginx.conf file or in each virtual host file. That is what I need assistance with. Thanks!
I see, I misunderstood the question then. The way to do that would be the geo module. I will update my answer
Hi Ben, when I implement this or similar solutions I get a 403 from all IP addresses. It looks like the geo $allowed_ip denies all IP addresses by default. Is there no way to not set a default = no and set if ($allowed_ip = yes) { try files ...
You could skip the default and override allowed_country geo $allowed_country { 127.0.0.1 yes; 192.168.1.0/24 yes; }
0

Here's an updated one in a more streamlined way that simplifies the filtering logic, ensuring that it checks both the allowed country and IP address using a single condition. Plus, it's now compatible with Cloudflare's CDN.

map $http_cf_connecting_ip $remote_ip { default $http_cf_connecting_ip; '' $remote_addr; } geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb { $geoip2_country_code default=- source=$remote_ip country iso_code; } geo $remote_ip $allowed_ip { default no; 1.2.3.4/32 yes; 5.6.7.8/32 yes; } map $geoip2_country_code $access_granted { default $allowed_ip; US yes; SG yes; } 

This should be used under server/ location context

if ($access_granted = no) { return 403; } location / { try_files $uri $uri/ /index.php$is_args$args; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.