ubuntu20下安装nginx插件geoip2查询ip信息

原创
07/29 09:20
阅读数 584

安装环境为:ubuntu 20.04 LTS 虚拟机,nginx 1.18

首先在本地windows测试一下nginx中参数的获取方法.

nginx中可直接使用$arg_+参数名来获取变量, 比如 http://localhost/geoip/city?ip=8.8.8.8 请求可直接使用$arg_ip来获取参数ip的值.

location /geoip/city {
    default_type application/json;
    return 200 '{"ip":"$arg_ip"}';
}

获取当前nginx的编译参数

root@ubuntu20:~# nginx -V

执行结果如下:

nginx version: nginx/1.18.0
built by gcc 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --group=www-data --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-KTLRnK/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=/home/nginx-http-concat-master

安装libmaxminddb依赖

官方地址: https://github.com/maxmind/libmaxminddb

cd /home

wget https://github.com/maxmind/libmaxminddb/releases/download/1.6.0/libmaxminddb-1.6.0.tar.gz

tar -xvf libmaxminddb-1.6.0.tar.gz

cd libmaxminddb-1.6.0

#配置安装路径为 /usr/lib/
./configure --prefix=/usr/

make && make check && make install

#更新动态链接库
ldconfig

下载插件

https://github.com/leev/ngx_http_geoip2_module

cd /home

wget -O ngx_http_geoip2_module-3.2.tar.gz https://github.com/chinagoldline/ngx_http_geoip2_module/archive/refs/tags/3.2.tar.gz

tar -xvf ngx_http_geoip2_module-3.2.tar.gz

重新编译nginx

移除nginx

sudo apt autoremove --purge nginx

编译

cd /home/nginx-1.18.0

./configure --group=www-data --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-KTLRnK/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=/home/nginx-http-concat-master --add-module=/home/ngx_http_geoip2_module-3.2 --with-stream

make && make install

注意: 因为插件中包含了stream, 所以配置中要添加--with-stream, 否则报错, 类似下面的错误信息:

#错误信息
-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC -ldl -lpthread -lpthread -lcrypt -lmaxminddb -lmaxminddb -l pcre -lssl -lcrypto -ldl -lpthread -lz \
-Wl,-E
/usr/bin/ld: objs/addon/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.o: in function `ngx_stream_geoip2_init':
/home/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.c:687: undefined reference to `ngx_stream_core_module'
/usr/bin/ld: objs/addon/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.o: in function `ngx_stream_geoip2_variable':
/home/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.c:136: undefined reference to `ngx_stream_complex_value'
/usr/bin/ld: objs/addon/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.o: in function `ngx_stream_geoip2_add_variable_geodata':
/home/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.c:550: undefined reference to `ngx_stream_compile_complex_value'
/usr/bin/ld: objs/addon/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.o: in function `ngx_stream_geoip2_add_variable_metadata':
/home/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.c:478: undefined reference to `ngx_stream_add_variable'
/usr/bin/ld: objs/addon/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.o: in function `ngx_stream_geoip2_add_variable_geodata':
/home/ngx_http_geoip2_module-3.2/ngx_stream_geoip2_module.c:566: undefined reference to `ngx_stream_add_variable'
collect2: error: ld returned 1 exit status
make[1]: *** [objs/Makefile:290: objs/nginx] Error 1
make[1]: Leaving directory '/home/nginx-1.18.0'
make: *** [Makefile:8: build] Error 2

find / -name nginx -type f搜索bin的目录, 结果是: /usr/share/nginx/sbin/nginx

创建启动软链接:

ln -s /usr/share/nginx/sbin/nginx /bin/nginx

添加到系统服务: 执行vim /lib/systemd/system/nginx.service, 写入:

[Unit]
Description=nginx - high performance web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/share/nginx/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/share/nginx/sbin/nginx -s reload
ExecStop=/usr/share/nginx/sbin/nginx -s stop
[Install]
WantedBy=multi-user.target

重新加载配置文件:

systemctl daemon-reload

启动nginx服务:

systemctl restart nginx

下载geoip数据库

注册 个人账号,邮箱验证后设置密码再登录进去,点击头像进入"My Account", 左边菜单"GeoIP2 / GeoLite2"下的"Download Files"链接点进去,然后分别点击"GeoLite2 City"和"GeoLite2 Country"后面的"Download GZIP"链接下载mmdb格式数据库的压缩包,解压后把.mmdb文件拷贝出来。

当然也可以使用后面的“Get Permalinks”永久链接。

这里提供aben个人账号的永久下载链接:

City: https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=hHuHwNYG7FL6uLg0&suffix=tar.gz

Country: https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=hHuHwNYG7FL6uLg0&suffix=tar.gz

这里将下载后的数据库文件放在/home/geoip2/目录下。

这里使用的都是免费版本(Lite)的数据库

nginx配置

参考 https://github.com/chinagoldline/ngx_http_geoip2_module

参数source必须配置, 否则使用默认的$remote_addr, 这里使用url中的参数ip来传值,在nginx通过$arg_ip即可获取

http {

    #geoip2的相关配置, 必须放在http节点下
    geoip2 /home/geoip2/GeoLite2-Country.mmdb {
        #自动重新加载数据库文件
        auto_reload 5m;
        $geoip2_metadata_country_build metadata build_epoch;
        $geoip2_data_country_name source=$arg_ip country names en;
        $geoip2_data_country_code source=$arg_ip country iso_code;
        $geoip2_data_country_continent source=$arg_ip continent names en;
    }
    geoip2 /home/geoip2/GeoLite2-City.mmdb {
        auto_reload 5m;
        $geoip2_data_province source=$arg_ip subdivisions 0 names en;
        $geoip2_data_province_code source=$arg_ip subdivisions 0 iso_code;
        $geoip2_data_city source=$arg_ip city names en;
        $geoip2_data_lat source=$arg_ip location latitude;
        $geoip2_data_lon source=$arg_ip location longitude;
        $geoip2_data_time_zone source=$arg_ip location time_zone;
        $geoip2_data_post_code source=$arg_ip postal code;
    }

}

server {
    location /geoip2/country {
        default_type application/json;
        return 200 '{"ip":"$arg_ip","continent":"$geoip2_data_country_continent","country":"$geoip2_data_country_name","country_code":"$geoip2_data_country_code"}';
    }
    location /geoip2/city {
        default_type application/json;
        return 200 '{"ip":"$arg_ip","continent":"$geoip2_data_country_continent","country":"$geoip2_data_country_name","country_code":"$geoip2_data_country_code","province":"$geoip2_data_province","province_code":"$geoip2_data_province_code","city":"$geoip2_data_city","lat":"$geoip2_data_lat","lon":"$geoip2_data_lon","time_zone":"$geoip2_data_time_zone","post_code":"$geoip2_data_post_code"}';
    }
}

查询城市: http://192.168.0.203/geoip2/city?ip=142.244.171.160

{"ip":"142.244.171.160","continent":"North America","country":"Canada","country_code":"CA","province":"Alberta","province_code":"AB","city":"Edmonton","lat":"53.46090","lon":"-113.37140","time_zone":"America/Edmonton","post_code":"T6T"}

查询国家: http://192.168.0.203/geoip2/country?ip=142.244.171.160

{"ip":"142.244.171.160","continent":"North America","country":"Canada","country_code":"CA"}

在jmeter下并发测试, 可以使用函数生成随机的ipv4地址,比如像下面这样,我把ip地址分成了四段:

http://192.168.0.203/geoip2/city?ip=${__Random(11,191,)}.${__Random(1,254,)}.${__Random(1,254,)}.${__Random(1,254,)}

附: 数据的获取, 参考命令行返回结果:

country:

root@ubuntu20:~# mmdblookup --file /home/geoip2/GeoLite2-Country.mmdb --ip 8.8.8.8

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

city:

mmdblookup --file /home/geoip2/GeoLite2-City.mmdb --ip 8.8.8.8                          
  {
    "continent":
      {
        "code":
          "NA" <utf8_string>
        "geoname_id":
          6255149 <uint32>
        "names":
          {
            "de":
              "Nordamerika" <utf8_string>
            "en":
              "North America" <utf8_string>
            "es":
              "Norteamérica" <utf8_string>
            "fr":
              "Amérique du Nord" <utf8_string>
            "ja":
              "北アメリカ" <utf8_string>
            "pt-BR":
              "América do Norte" <utf8_string>
            "ru":
              "Северная Америка" <utf8_string>
            "zh-CN":
              "北美洲" <utf8_string>
          }
      }
    "country":
      {
        "geoname_id":
          6252001 <uint32>
        "iso_code":
          "US" <utf8_string>
        "names":
          {
            "de":
              "Vereinigte Staaten" <utf8_string>
            "en":
              "United States" <utf8_string>
            "es":
              "Estados Unidos" <utf8_string>
            "fr":
              "États Unis" <utf8_string>
            "ja":
              "アメリカ" <utf8_string>
            "pt-BR":
              "EUA" <utf8_string>
            "ru":
              "США" <utf8_string>
            "zh-CN":
              "美国" <utf8_string>
          }
      }
    "location":
      {
        "accuracy_radius":
          1000 <uint16>
        "latitude":
          37.751000 <double>
        "longitude":
          -97.822000 <double>
        "time_zone":
          "America/Chicago" <utf8_string>
      }
    "registered_country":
      {
        "geoname_id":
          6252001 <uint32>
        "iso_code":
          "US" <utf8_string>
        "names":
          {
            "de":
              "Vereinigte Staaten" <utf8_string>
            "en":
              "United States" <utf8_string>
            "es":
              "Estados Unidos" <utf8_string>
            "fr":
              "États Unis" <utf8_string>
            "ja":
              "アメリカ" <utf8_string>
            "pt-BR":
              "EUA" <utf8_string>
            "ru":
              "США" <utf8_string>
            "zh-CN":
              "美国" <utf8_string>
          }
      }
  }

注意: 命令行下city返回的字段很少, 但是在nginx中又正常.

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部