Web运维

设置Nginx Plus通过GeoIP2模块限制其他国家的访问

NGINX Plus可以根据用户的地理位置来区分用户。例如,您可以为不同的国家/地区提供不同的网站内容,或者可以将内容分发限制为特定的国家或城市。

NGINX Plus使用第三方MaxMind数据库来匹配用户的IP地址及其位置。知道地理位置后,便可以在map或split_clients模块中使用基于Geoip的变量。

菜鸟笔记:如何用Nginx实现 反向绑定/缓存加速/自动更新缓存/获取真实IP/CDN加速

1. 概述

NGINX Plus可以根据用户的地理位置来区分用户。例如,您可以为不同的国家/地区提供不同的网站内容,或者可以将内容分发限制为特定的国家或城市。

NGINX Plus使用第三方MaxMind数据库来匹配用户的IP地址及其位置。知道地理位置后,便可以在mapsplit_clients模块中使用基于Geoip的变量。

注意: MaxMind GeoLite传统数据库目前已停止开发,应改用MaxMind GeoIP2或GeoLite2数据库和NGINX Plus GeoIP2模块

HTTP 和 TCP/UDP 协议都支持基于地理位置的访问限制。

2. 先决条件

3. 在NGINX Plus中配置 GeoIP

  1. 为NGINX Plus安装GeoIP2动态模块:

    对于Amazon Linux,CentOS,Oracle Linux和RHEL系统的安装方法:

    $ yum install nginx-plus-module-geoip2

    对于Debian和Ubuntu系统的安装方法:

    $ apt-get install nginx-plus-module-geoip2

    对于SLES系统的安装方法:

    $ zypper install nginx-plus-module-geoip2
  2. 通过在配置文件主上下文中添加 load_module 指令在 Nginx Plus 中开启 GeoIP 动态模块:

    load_module modules/ngx_http_geoip2_module.so;
    load_module modules/ngx_stream_geoip2_module.so;
    
    http {
        # ...
    }
  3. MaxMind下载页面获取和解压缩GeoIP2或GeoLite2数据库:

    在此示例中,使用了免费的GeoLite2数据库:

    $ wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
    $ wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
    $ gunzip GeoLite2-Country.mmdb.gz
    $ gunzip GeoLite2-City.mmdb.gz
    
  4. 通过 http段、stream段或两者中的 geoip2指令将 国家和城市地理位置数据库 路径添加到nginx配置中:

    http {
        #...
        geoip2 GeoIP2/GeoLite2-Country.mmdb;
        geoip2 GeoIP2/GeoLite2-City.mmdb;
        #...
     }
       
    stream {
        #...
        geoip2 GeoIP2/GeoLite2-Country.mmdb;
        geoip2 GeoIP2/GeoLite2-City.mmdb;
        #...
    }
  5. 使用GeoIP2模块中的标准变量将数据传递到mapsplit_clients模块。

    例如,使用 geoip_city 指令的变量 $geoip_city_continent_code 和 map 模块,可以创建另一个变量,其值将成为基于大陆位置的最接近的服务器:

    #...
    map $geoip2_data_country_code $nearest_server {
        default default {};
        EU      eu;
        NA      na;
        AS      as;
        AF      af;
    #...

    然后,您可以根据$nearest_server变量传入的值选择一台 upstream 服务器:

    #...
    server {
        listen 12346;
        proxy_pass $nearest_server;
    }
     upstream eu {
        server eu1.example.com:12345;
        server eu2.example.com:12345;
    }
    upstream na {
        server na1.example.com:12345;
        server na2.example.com:12345;
    }
    #...

    如果大陆位置是欧洲,那么 $nearest_server 变量的值是 eu,连接将会通过 proxy_pass 指令传到 eu upstream

4. 完整示例

这个例子可以在 http 和 stream 上下文中实现:

# 可以同时在 "http {" 或者 "stream {" 段
    #...
    geoip2 GeoIP2/GeoLite2-Country.mmdb;
    geoip2 GeoIP2/GeoLite2-City.mmdb;
    map $geoip2_data_country_code $nearest_server {
        default default {};
        EU      eu;
        NA      na;
        AS      as;
        AF      af;
    server {
        listen 12346;
        proxy_pass $nearest_server;
    }
     upstream eu {
        server eu1.example.com:12345;
        server eu2.example.com:12345;
    }
    upstream na {
        server na1.example.com:12345;
        server na2.example.com:12345;
    }
}

在这个例子中,通过数据库 GeoLiteCity.dat 来检查 IP 地址,并将结果写入 $geoip_city_continent_code 变量。Nginx 将会用这个变量值匹配 map 指令中的值,并将自定义变量中的结果以白色表示( white the result in the custom variable,这个示例中的变量是 $nearest_server)。 根据 $nearest_server 的值,proxy_pass 指令将选择相应的 upstream 服务器。

(END)

本文翻译自Nginx官网:
https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-by-geoip/