NGINX Plus可以根据用户的地理位置来区分用户。例如,您可以为不同的国家/地区提供不同的网站内容,或者可以将内容分发限制为特定的国家或城市。
NGINX Plus使用第三方MaxMind数据库来匹配用户的IP地址及其位置。知道地理位置后,便可以在map
或split_clients
模块中使用基于Geoip的变量。
注意: MaxMind GeoLite传统数据库目前已 停产,应改用MaxMind GeoIP2或GeoLite2数据库和NGINX Plus GeoIP2模块。
地理位置限制适用于HTTP和TCP / UDP协议。
可以从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.8
IP地址的所有可用地理数据,请发送以下命令:
$ 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动态模块:
对于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
load_module
使用main
配置级别中指定的指令在NGINX Plus配置文件中启用GeoIP2动态模块:
load_module modules/ngx_http_geoip2_module.so;
load_module modules/ngx_stream_geoip2_module.so;
http {
# ...
}
路径的国家和城市数据库添加到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 { #... } }
根据GeoIP数据库结构,创建自定义变量,该变量将保留GeoIP2数据库中的数据,然后将数据传递给map
或split_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将请求传递给相应的上游服务器组。
对于IP地址无法与GeoIP数据库匹配的情况,请确保已为每个大陆(例如欧洲,北美)配置了服务器或上游服务器组:eu
na
all
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;
}
添加具有任何名称(例如)的变量的块,以获取GeoIP2数据库的洲代码:geoip2 {}
$geoip2_data_continent_code
geoip2 GeoIP2/GeoLite2-Country.mmdb { $geoip2_data_continent_code continent code; } #...
创建map
将创建$nearest_server
变量的块:
#...
map $geoip2_data_continent_code $nearest_server {
default all;
EU eu;
NA na;
AS as;
AF af;
}
#...
创建一个块,该块将根据变量中传递的值将请求传递给上游服务器组之一:server {}
$nearest_server
server {
listen 12346;
proxy_pass http://$nearest_server;
}
如果大陆是欧洲,则$nearest_server
will 的值将是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;
}
#...
此示例可以在http
和stream
上下文中应用。
# 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_server
,proxy_pass
伪指令将选择相应的上游服务器。