原文地址
Nginx 可以通过地理位置来区分用户。例如,对于不同国家可以显示不同的页面内容,也可以对指定国家或城市限制内容分发。
Nginx 使用第三方 MaxMind 数据库来匹配用户的 IP 地址及其位置。 只要地理位置已知,就可以在 map 或 split_clients 模块中使用基于 geoip 的变量。
HTTP 和 TCP/UDP 协议都支持基于地理位置的访问限制。
为 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;
确保开源版本的 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'
或者确保这几个模块可以 动态链接。
从 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
通过 http 的 geoip_country
和 geoip_city
指令,或 stream 的 geoip_country
和 geoip_city
指令添加数据库路径到 Nginx 的配置文件:
http {
...
geoip_country GeoIP/GeoIP.dat;
geoip_city GeoIP/GeoLiteCity.dat;
...
}
或:
stream {
...
geoip_country GeoIP/GeoIP.dat;
geoip_city GeoIP/GeoLiteCity.dat;
...
}
使用 geoip_country
和 geoip_city
指令的变量把数据传到 map
或 split_clients
模块。
例如,使用 geoip_city
指令的变量 $geoip_city_continent_code
和 map
模块,可以创建另一个变量,其值将成为基于大陆位置的最接近的服务器:
...
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。
这个例子可以在 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 服务器。