Skip to content

Instantly share code, notes, and snippets.

@kmjones1979
Last active July 9, 2024 10:53
Show Gist options
  • Save kmjones1979/fcabb4731bbf85b9c50189e90d76b1c1 to your computer and use it in GitHub Desktop.
Save kmjones1979/fcabb4731bbf85b9c50189e90d76b1c1 to your computer and use it in GitHub Desktop.
Example NGINX configuration to route based on country code using GeoIP
# load dynamic modules
load_module /etc/nginx/modules/ngx_http_geoip_module.so;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
default_type text/html;
log_format main 'remote_addr: $remote_addr, remote_user: $remote_user [time_local: $time_local] request: "$request" '
'status: $status, body_bytes_sent: $body_bytes_sent, http_referer: "$http_referer" '
'http_user_agent: "$http_user_agent:", http_x_forwarded_for: "$http_x_forwarded_for" '
'geoip_area_code: $geoip_area_code, geoip_city: $geoip_city, geoip_city_continent_code: $geoip_city_continent_code, geoip_city_country_code: $geoip_city_country_code, geoip_city_country_code3: $geoip_city_country_code3, geoip_city_country_name: $geoip_city_country_name, geoip_country_code: $geoip_country_code, geoip_country_code3: $geoip_country_code3, geoip_country_name: $geoip_country_name, geoip_dma_code: $geoip_dma_code, geoip_latitude: $geoip_latitude, geoip_longitude: $geoip_longitude, geoip_org: $geoip_org, geoip_postal_code: $geoip_postal_code, geoip_region: $geoip_region, geoip_region_name: $geoip_region_name';
access_log /var/log/nginx/access.log main;
# load Maxmind GeoIP library
geoip_country /etc/nginx/GeoIP/GeoIP.dat;
geoip_city /etc/nginx/GeoIP/GeoLiteCity.dat;
geoip_proxy 127.0.0.1;
# map country code to specific NGINX upstream
map $geoip_country_code $upstream {
LR web_lr;
US web_us;
RU web_russia;
default $subnet;
}
# map private subnets to $subnet variable (used in upstream map above)
geo $subnet {
127.0.0.0/24 web_us;
10.0.0.0/24 web_us;
192.168.1.0/24 web_us;
default web_default;
}
upstream web_lr {
zone web-lr 64k;
server 127.0.0.1:3001;
}
upstream web_russia {
zone web-russia 64k;
server 127.0.0.1:4001;
}
upstream web_us {
zone web-us 64k;
server 127.0.0.1:5001;
}
upstream web_default {
zone web-default 64k;
server 127.0.0.1:6001;
}
server {
status_zone web-lr-backend;
listen 3001;
location / {
return 200 "GeoIP has matched this request to a LR country code.
http_x_realip:\t $http_x_real_ip\n
http_x_forwarded_for:\t $http_x_forwarded_for\n
geoip_country_code:\t $geoip_country_code\n";
}
}
server {
status_zone web-russia-backend;
listen 4001;
location / {
return 200 "GeoIP has matched this request to a RU country code.
http_x_realip:\t $http_x_real_ip\n
http_x_forwarded_for:\t $http_x_forwarded_for\n
geoip_country_code:\t $geoip_country_code\n";
}
}
server {
status_zone web-us-backend;
listen 5001;
location / {
return 200 "GeoIP has matched this request to a US country code.\n
http_x_realip:\t $http_x_real_ip\n
http_x_forwarded_for:\t $http_x_forwarded_for\n
geoip_country_code:\t $geoip_country_code\n";
}
}
server {
status_zone web-default-backend;
listen 6001;
location / {
return 200 "NGINX has routed this request to the default site.\n
http_x_realip:\t $http_x_real_ip\n
http_x_forwarded_for:\t $http_x_forwarded_for\n
geoip_country_code:\t $geoip_country_code\n";
}
}
server {
status_zone nginx-frontend;
listen 80;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-GeoIP-Country-Code $geoip_country_code;
real_ip_header X-Forwarded-For;
proxy_pass http://$upstream;
}
}
server {
listen 8080;
status_zone status-page;
root /usr/share/nginx/html;
location = /status.html { }
location = /status-old.html { }
location = / {
return 301 /status.html;
}
location /status {
status;
status_format json;
access_log off;
}
location /upstream_conf {
upstream_conf;
}
}
}
@ram94638
Copy link

ram94638 commented Apr 9, 2022

Hello, how to make setup with geoip2 .mmdb file. I want to run GeoIP2+Nginx+NginxLoadBalancer for tomcat country wise. My current file is

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb{
$geoip2_data_country_code $upstream;
}

map $geoip2_data_country_code $upstream {
IN in_lb;
DE de_lb;
CA ca_lb;
}

upstream in_lb {
server 192.168.1.5:8080;
}

upstream de_lb {
server 192.168.5.10:8080;
}

upstream ca_lb {
server 192.168.10.10:8080;
}
server {
listen 80;
server_name my.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-GeoIP-Country-Code $geoip2_data_country_code;
real_ip_header X-Forwarded-For;
proxy_pass http://$upstream;
}

}

Error: 500 Internal Server Error
nginx

@kmjones1979
Copy link
Author

kmjones1979 commented Apr 9, 2022 via email

@ram94638
Copy link

Thanks @kmjones1979 for reply

Now I not going to set multi upstream here and main issue was in variables. New configurations working fine as below

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb{
$geoip2_data_country_iso_code country iso_code;
}

map $geoip2_data_country_iso_code $upstream {
IN 192.168.1.5: (there is already load balancer working on 192.168.1.5 )
DE 192.168.5.10; (there is already load balancer working on 192.168.5.10)
}

It seems me good way, Is there any loop fall in this .conf ?

@ram94638
Copy link

ram94638 commented Apr 30, 2022

Hello, I am getting output "502 bad gateway" using below configuration. What may issue ? if I mentioned port with IP under upstream and and remove port in proxy_pass then its working but that will not fulfill my requirement. Actually there are running 5 tomcat with 5 different ports on single server like 172.16.1.5 only

upstream lb_ind {
server 172.16.1.5;
server 172.16.1.6;
}

upstream lb_france {
server 172.17.1.7;
}
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb{
$geoip2_data_country_iso_code country iso_code;
}

map $geoip2_data_country_iso_code $itsupstream {
IN lb_ind;
DE lb_german;
CA lb_canada;
FR lb_france;
US lb_france;
}
server {
listen 80;
server_name my.domain.com;

            location /oauth2/ {
                    proxy_set_header    X-Real-IP $remote_addr;
                     proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header    X-Forwarded-Proto $scheme;
                    proxy_set_header    Host $host;
                    proxy_pass http://$itsupstream:8282$request_uri/;
            }

            location /producer/ {
                    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header    X-Forwarded-Proto $scheme;
                     proxy_http_version 1.1;
                     proxy_set_header Upgrade $http_upgrade;
                     proxy_set_header Connection "upgrade";
                     proxy_set_header Host $host;
                    proxy_pass http://$itsupstream:8181$request_uri;
            }

    }

@kmjones1979
Copy link
Author

kmjones1979 commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment