Nginx Geoip2 处理不同国家 (或城市) 的访问 Nginx 发布于2020-06-02 / 更新于2021-01-02 07:04
前言 最近搞了一套AB站(不是acfun和bilibili,AB站:文中的AB站指的是同一个域名,可返回两种不同的资源),客户主要是做谷歌和FaceBook推广,A站是为了过审和过平台检查,B站是目标网站主要推广日本地区。 日本国家的用户访问 www.abc.com 看到的是B站,非日本国家的用户访问 www.abc.com 看到的是A站。
当时想了三个方案,最终决定使用Nginx+GeoIP2 √ Nginx+GeoIP2可以拿到请求IP的国家和城市信息 可以让开发者对于请求的IP进行各种个性化Nginx配置 可以将请求IP的地理位置通过php-fpm传递php程序 定时更新MaxMind免费数据库(GeoLite2-Country.mmdb + GeoLite2-City.mmdb)完成完美闭环 maxmind公司2002年成立至今,靠谱 × 使用IP识别接口:稳定的需要收费(也不能保证100%高可用:限频、响应时间、接口异常等因素),免费的无法保证稳定性,接口远远没有将GeoLite数据放在本地稳定 × DNS根据地域解析:cloudflare收费略贵,国内cloudxns已关闭免费服务(免费的东西说变就变,论planB的重要性) TIPS:
作者环境(2020.05.19) CentOS7.2 libmaxminddb 1.3.2 Nginx 1.14.2 安装GeoIP2 依赖 $ wget https://github.com/maxmind/libmaxminddb/releases/download/1.3.2/libmaxminddb-1.3.2.tar.gz
$ tar -zxvf libmaxminddb-1.3.2.tar.gz
$ cd libmaxminddb-1.3.2
$ ./configure && make && make install
$ echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
$ ldconfig
下载GeoIP数据 $ git clone https://github.com/ar414-com/nginx-geoip2
$ cd nginx-geoip2
$ tar -zxvf GeoLite2-City_20200519.tar.gz
$ mv ./GeoLite2-City_20200519/GeoLite2-City.mmdb /usr/share/GeoIP/
$ tar -zxvf GeoLite2-Country_20200519.tar.gz
$ mv ./GeoLite2-Country_20200519/GeoLite2-Country.mmdb /usr/share/GeoIP/
$ # /usr/share/GeoIP 目录不存在的话可自己创建,Tips:不一定要放在这 随便放在哪
$ # Nginx配置的时候才需要用到数据路径
将 GeoIP2 模块编译到 Nginx 中 下载GeoIP2模块 $ cd ~
$ git clone https://github.com/ar414-com/nginx-geoip2
编译到已安装的Nginx 1. 查看nginx安装目录nginx -V
> --prefix=/www/server/nginx
2. 原封不动带上之前的编译参数,再在后面添加Geoip2的模块参数
--add-module=/root/nginx-geoip2/ngx_http_geoip2_module
$ cd /www/server/nginx
$ ./configure --user=www --group=www \
--prefix=/www/server/nginx \
--with-openssl=/www/server/nginx/src/openssl \
--add-module=/www/server/nginx/src/ngx_devel_kit \
--add-module=/www/server/nginx/src/lua_nginx_module \
--add-module=/www/server/nginx/src/ngx_cache_purge \
--add-module=/www/server/nginx/src/nginx-sticky-module
--add-module=/www/server/nginx/src/nginx-http-concat \
--with-http_stub_status_module --with-http_ssl_module \
--with-http_v2_module --with-http_image_filter_module \
--with-http_gzip_static_module --with-http_gunzip_module \
--with-stream --with-stream_ssl_module --with-ipv6 \
--with-http_sub_module --with-http_flv_module \
--with-http_addition_module --with-http_realip_module \
--with-http_mp4_module --with-ld-opt=-Wl,-E --with-pcre=pcre-8.40 \
--with-ld-opt=-ljemalloc \
--add-module=/root/nginx-geoip2/ngx_http_geoip2_module
$ make
$ rm -f /www/server/nginx/sbin/nginx.old
$ mv /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx.old
$ cp ./objs/nginx /www/server/nginx/sbin/nginx
$ make upgrade
$ #检查是否安装成功
$ nginx -V
重新安装Nginx 简约安装,方便测试
$ wget https://nginx.org/download/nginx-1.14.2.tar.gz
$ tar zxvf nginx-1.14.2.tar.gz
$ cd nginx-1.14.2
$ ./configure --user=www --group=www \
--prefix=/www/server/nginx \
--add-module=/root/nginx-geoip2/ngx_http_geoip2_module
$ make && make install
使用 GeoIP2 http{
...
geoip2 /usr/local/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_country_code country iso_code;
}
map $geoip2_country_code $is_jp_country {
default no;
JP yes;
}
server {
listen 80;
server_name localhost;
#加上响应头方便调试
add_header country $geoip2_country_code;
location / {
set $rootpath html/a;
if ($is_jp_country = no) {
set $rootpath html/b;
}
add_header rootpath $rootpath;
add_header country $geoip2_country_code;
root $rootpath;
index index.html index.htm;
}
}
}
docker 体验 感兴趣又懒得弄的朋友可直接Pull作者上传的镜像进行体验
$ docker pull ar414/nginx-geoip2
运行 $ docker run -it -d -p 80:80 -p 443:443 --rm ar414/nginx-geoip2
测试 国内访问
日本访问
讨论