Nginx Geoip2 处理不同国家 (或城市) 的访问

ar414-nginx-geoip2

:two_men_holding_hands:前言

最近搞了一套AB站(不是acfun和bilibili,AB站:文中的AB站指的是同一个域名,可返回两种不同的资源),客户主要是做谷歌和FaceBook推广,A站是为了过审和过平台检查,B站是目标网站主要推广日本地区。
日本国家的用户访问 www.abc.com 看到的是B站,非日本国家的用户访问 www.abc.com 看到的是A站。
ar414-nginx-geoip2-1

当时想了三个方案,最终决定使用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:

  • 网上大部分都是GeoIP老版本的 已经不适用了,GeoIP依赖MaxMind的IP数据,需要频繁更新(自动化脚本定时更新)
  • 感兴趣又懒的部署的朋友可直接跳到最后有docker体验
  • Geoip2资源 Github整合
  • Dockerfile

:computer:作者环境(2020.05.19)

  • CentOS7.2
  • libmaxminddb 1.3.2
  • Nginx 1.14.2

:wrench:安装GeoIP2 依赖

  • 官方GitHub
  • 官方下载地址
    $ 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

:inbox_tray:下载GeoIP数据

  • 官方下载地址
  • github下载地址
    $ 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配置的时候才需要用到数据路径 

:calling:将 GeoIP2 模块编译到 Nginx 中

下载GeoIP2模块

$ cd ~
$ git clone https://github.com/ar414-com/nginx-geoip2

编译到已安装的Nginx

1. 查看nginx安装目录nginx -V > --prefix=/www/server/nginx
ar414-nginx-geoip2-2

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 

ar414

重新安装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

:checkered_flag:使用 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

测试

国内访问

ar414-nginx-geoip2-3
ar414-nginx-geoip2-4

日本访问

ar414-nginx-geoip2-5
ar414-nginx-geoip2-6

Support Author

coffee alipay wechat

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
AR414
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 6

不错,感谢分享,收藏备用 :grin:

3年前 评论

🎤采访大佬求经验

3年前 评论

很好,收藏了

3年前 评论

github.com/ar414-com/nginx-geoip2 为什么这里要下载两次??

3年前 评论
AR414 (楼主) 3年前

一直提示 Can't open auto/feature

3年前 评论
AR414 (楼主) 3年前
sunny123456 (作者) 3年前
AR414 (楼主) 3年前
sunny123456 (作者) 3年前
AR414 (楼主) 3年前
sunny123456 (作者) 3年前

请问所有步骤完成后,nginx -t 是 ok 的,但是 start 就报错

Starting nginx... nginx: [emerg] unknown directive "geoip2" in /www/server/nginx/conf/nginx.conf:72
 failed

可能是哪里出错了呀

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!