Nginx 限制访问 - 通过地理位置限制访问

原文地址

1. 概述

Nginx 可以通过地理位置来区分用户。例如,对于不同国家可以显示不同的页面内容,也可以对指定国家或城市限制内容分发。
Nginx 使用第三方 MaxMind 数据库来匹配用户的 IP 地址及其位置。 只要地理位置已知,就可以在 map 或 split_clients 模块中使用基于 geoip 的变量。
HTTP 和 TCP/UDP 协议都支持基于地理位置的访问限制。

2. 先决条件 Prerequisites

  • 安装了 http geoip 或 stream geoip 模块的 NGINX Plus 或开源版本的 NGINX
  • MaxMind 的 Geolite Legacy 数据库

3. 配置 GeoIP

3.1 安装模块

3.1.1 对于 NGINX Plus

为 Nginx Plus 安装 GeoIP 动态模块:

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

通过在配置文件主上下文中添加 load_module 指令在 Nginx Plus 中开启 GeoIP 动态模块:

load_module modules/ngx_http_geoip_module.so;
load_module modules/ngx_stream_geoip_module.so;

3.1.2 对于 Nginx

确保开源版本的 Nginx 编译安装时开启 --with-http_geoip_module--with-stream_geoip_module 配置标志:

$ nginx -V 2>&1 | grep -- 'http_geoip_module'
$ nginx -V 2>&1 | grep -- 'stream_geoip_module'

或者确保这几个模块可以 动态链接。

3.2 下载 MaxMind 的地理位置数据库

从 MaxMind 下载页面 下载并解压缩 legacy Geo 国家和城市数据库:

$ wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
$ wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
$ gunzip GeoIP.dat.gz
$ gunzip GeoLiteCity.dat.gz

3.3 配置地理位置数据库的路径

通过 http 的 geoip_countrygeoip_city 指令,或 stream 的 geoip_countrygeoip_city 指令添加数据库路径到 Nginx 的配置文件:

http {
    ...
    geoip_country GeoIP/GeoIP.dat;
    geoip_city    GeoIP/GeoLiteCity.dat;
    ...
}

或:

stream {
    ...
    geoip_country GeoIP/GeoIP.dat;
    geoip_city    GeoIP/GeoLiteCity.dat;
    ...
}

3.4

使用 geoip_countrygeoip_city 指令的变量把数据传到 mapsplit_clients 模块。
例如,使用 geoip_city 指令的变量 $geoip_city_continent_codemap 模块,可以创建另一个变量,其值将成为基于大陆位置的最接近的服务器:

...
map $geoip_city_continent_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 上下文中实现:

 # can be either "http {" or "stream {"
    ...
    geoip_country GeoIP/GeoIP.dat;
    geoip_city    GeoIP/GeoLiteCity.dat;

    map $geoip_city_continent_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 服务器。

你可能感兴趣的:(Nginx)