Nginx通过地理位置限制访问

Nginx通过地理位置限制访问

 

  • 介绍
  • 先决条件
  • 获取数据库
  • 了解数据库结构
  • 在NGINX Plus中配置GeoIP2
  • 方案:选择最近的服务器

 

介绍

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

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

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

地理位置限制适用于HTTP和TCP / UDP协议。

 

先决条件

  • NGINX Plus GeoIP2动态模块
  • MaxMind的GeoIP2或GeoLite2数据库
  • (可选)mmdblookup实用程序,用于在MaxMind数据库文件中查找IP地址

 

获取数据库

可以从MaxMind下载页面获得GeoIP2或GeoLite2数据库。在此示例中,使用了免费的GeoLite2可下载数据库。

要获取和解压缩GeoLite2国家数据库:

$ wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
$ gunzip GeoLite2-Country.mmdb.gz

要获取和解压缩GeoLite2 City数据库:

$ wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
$ gunzip GeoLite2-City.mmdb.gz

 

了解数据库结构

要查看可用的地理数据,可以使用mmdblookup实用程序查询GeoLite2-Country和GeoLite2-City数据库。地理数据表示为JSON树。

安装libmaxminddb数据库实用程序:

  • 对于Amazon Linux,CentOS,Oracle Linux和RHEL:

    $ yum install libmaxminddb-devel
  • 对于Debian和Ubuntu:

    $ apt-get install libmaxminddb-dev
  • 对于SLES:

    $ zypper install libmaxminddb-devel

对数据库的查询可以以下格式发送:

mmdblookup –file [FILE PATH] –ip [IP ADDRESS] [DATA PATH]

例如,要获取8.8.8.8IP地址的所有可用地理数据,请发送以下命令:

$ mmdblookup --file /usr/local/etc/geoip2/GeoLite2-Country.mmdb --ip 8.8.8.8

输出将是:

{
    "continent":
      {
        "code":
          "NA" 
        "geoname_id":
          6255149 
        "names":
          {
            "de":
              "Nordamerika" 
            "en":
              "North America" 
            "es":
              "Norteamérica" 
            "fr":
              "Amérique du Nord" 
            "ja":
              "北アメリカ" 
            "pt-BR":
              "América do Norte" 
            "ru":
              "Северная Америка" 
            "zh-CN":
              "北美洲" 
          }
      }
    "country":
      {
        "geoname_id":
          6252001 
        "iso_code":
          "US" 
        "names":
          {
            "de":
              "USA" 
            "en":
              "United States" 
            "es":
              "Estados Unidos" 
            "fr":
              "États-Unis" 
            "ja":
              "アメリカ合衆国" 
            "pt-BR":
              "Estados Unidos" 
            "ru":
              "США" 
            "zh-CN":
              "美国" 
          }
      }
    "registered_country":
      {
        "geoname_id":
          6252001 
        "iso_code":
          "US" 
        "names":
          {
            "de":
              "USA" 
            "en":
              "United States" 
            "es":
              "Estados Unidos" 
            "fr":
              "États-Unis" 
            "ja":
              "アメリカ合衆国" 
            "pt-BR":
              "Estados Unidos" 
            "ru":
              "США" 
            "zh-CN":
              "美国" 
          }
      }
  }

例如,要获取特定的地理数据,例如仅获取特定国家/地区的ISO代码,请在命令末尾添加参数:country iso_code

$ mmdblookup --file /usr/local/etc/geoip2/GeoLite2-Country.mmdb --ip 8.8.8.8 country iso_code

在用于NGINX的GeoIP2模块中创建变量时,也会使用这些参数。

 

在NGINX Plus中配置GeoIP2

  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使用main配置级别中指定的指令在NGINX Plus配置文件中启用GeoIP2动态模块:

    load_module modules/ngx_http_geoip2_module.so;
    load_module modules/ngx_stream_geoip2_module.so;
    
    http {
        # ...
    }
  3. 路径的国家和城市数据库添加到NGINX配置与块,或两者:geoip2 {}http {}stream {}

     
    http { #... geoip2 GeoIP2/GeoLite2-Country.mmdb { #... } geoip2 GeoIP2/GeoLite2-City.mmdb { #... } } stream { #... geoip2 GeoIP2/GeoLite2-Country.mmdb { #... } geoip2 GeoIP2/GeoLite2-City.mmdb { #... } } 
  4. 根据GeoIP数据库结构,创建自定义变量,该变量将保留GeoIP2数据库中的数据,然后将数据传递给mapsplit_clients指令(可以在和上下文中应用):http {}stream {}

geoip2 GeoIP2/GeoLite2-City.mmdb {
    $geoip2_data_city_name   city names en;
    $geoip2_data_postal_code postal code;
    $geoip2_data_latitude    location latitude;
    $geoip2_data_longitude   location longitude;
    $geoip2_data_state_name  subdivisions 0 names en;
    $geoip2_data_state_code  subdivisions 0 iso_code;
}

geoip2 GeoIP2/GeoLite2-Country.mmdb {
    $geoip2_data_continent_code   continent code;
    $geoip2_data_country_iso_code country iso_code;
}

#...

 

方案:选择最近的服务器

使用来自创建的变量的地理位置数据,可以将客户端连接重定向到最近的服务器,从而减少网络延迟并提高连接速度。

这可以通过在变量中使用来自GeoIP2数据库的大洲代码和map将创建另一个变量的模块来实现,该变量的值将是基于大洲位置的最接近的服务器。基于此值,NGINX将请求传递给相应的上游服务器组。

  1. 对于IP地址无法与GeoIP数据库匹配的情况,请确保已为每个大陆(例如欧洲,北美)配置了服务器或上游服务器组:eunaall

    upstream all {
        server all1.example.com:12345;
        server all2.example.com:12345;
    }
    
    upstream eu {
        server eu1.example.com:12345;
        server eu2.example.com:12345;
    }
    
    upstream na {
        server na1.example.com:12345;
        server na2.example.com:12345;
    }
  2. 添加具有任何名称(例如)的变量的块,以获取GeoIP2数据库的洲代码:geoip2 {}$geoip2_data_continent_code

      
    geoip2 GeoIP2/GeoLite2-Country.mmdb { $geoip2_data_continent_code continent code; } #... 
  3. 创建map将创建$nearest_server变量的块:

    #...
    map $geoip2_data_continent_code $nearest_server {
        default all;
        EU      eu;
        NA      na;
        AS      as;
        AF      af;
    }
    #...
  4. 创建一个块,该块将根据变量中传递的值将请求传递给上游服务器组之一:server {}$nearest_server

    server {
        listen 12346;
        proxy_pass http://$nearest_server;
    }

如果大陆是欧洲,则$nearest_serverwill 的值将是eu,并且连接将eu通过proxy_pass伪指令传递给上游:

#...
server {
    listen 12346;
    proxy_pass http://$nearest_server;
}

upstream all {
    server all1.example.com:12345;
    server all2.example.com:12345;

upstream eu {
    server eu1.example.com:12345;
    server eu2.example.com:12345;
}
upstream na {
    server na1.example.com:12345;
    server na2.example.com:12345;
}
#...

 

此示例可以在httpstream上下文中应用。

# can be either "http {}" or "stream {}"
#...
geoip2 GeoIP2/GeoLite2-Country.mmdb {
    $geoip2_data_continent_code continent code;
}

map $geoip2_data_continent_code $nearest_server {
    default all;
    EU      eu;
    NA      na;
    AS      as;
    AF      af;
}

server {
    listen 12346;
    proxy_pass http://$nearest_server;
    }

upstream all {
    server all1.example.com:12345;
    server all2.example.com:12345;
}

upstream eu {
    server eu1.example.com:12345;
    server eu2.example.com:12345;
}

upstream na {
    server na1.example.com:12345;
    server na2.example.com:12345;
}

在此示例中,将在GeoLite2-Country.mmdb数据库中检查IP地址,结果将被写入$geoip2_data_continent_code变量。map在我们的示例中,NGINX Plus会将变量的值与指令中的值进行匹配,并将结果写入自定义变量中$nearest_server。根据的值$nearest_serverproxy_pass伪指令将选择相应的上游服务器。

 

更多信息

  • GeoIP2动态模块安装说明
  • MaxMind GeoIP2数据库
  • MaxMind Geolite2免费可下载数据库
 

你可能感兴趣的:(Nginx通过地理位置限制访问)