GeoIP介绍

  • GeoIP库可以根据IP地址(支持IPv4 和 IPv6), 定位该IP所在的 洲、经纬度、国家、省市、ASN 等信息。
  • GeoIP目前已经升级到GeoIP2,GeoIP2有两个版本,一个免费版(GeoLite2),一个收费版本(GeoIP2, 200$起步)。
  • 收费版本的准确率稍高一些,更新频率为每周二更新一次, 免费版是每月第一个周二更新一次。

    MaxMind

  • MaxMind提供了GeoLite2下载GeoLite2数据库
  • 登录 / 注册
  • 我们需要使用的二进制库文件格式,如下图所示,下载即可。
    image
    image
    image

    libmaxminddb

  • libmaxminddb(api库) 用于处理 MaxMind 数据库文件的库, libmaxminddb(api库)下载地址

    • 安装

        # centos7
        yum -y install wget gcc gcc-c++ make
        wget --no-check-certificate https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz
        cd libmaxminddb-1.7.1
        ./configure && make && make install
        echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf
        ldconfig
        unlink /usr/sbin/mmdblookup &&  ln -s /usr/local/bin/mmdblookup  /usr/sbin/mmdblookup
      • 测试libmaxminddb库地理位置api和数据库功能

          # 解压GeoLite2数据库
          tar -zxvf GeoLite2-ASN_20230411.tar.gz     # 用于产看IP地址的拥有者(7M左右),需要注意的是City和Country库中不含ASN信息
          tar -zxvf GeoLite2-City_20230411.tar.gz    #  精确到城市(大小70M左右)
          tar -zxvf GeoLite2-Country_20230411.tar.gz #  精确到国家(4M左右)
        
          # 格式  mmdblookup --file  GeoLite2数据库物理地址路径 --ip  你需要测试的IP地址
          mmdblookup --file /etc/nginx/geoip/resource/GeoLite2-ASN_20230411/GeoLite2-ASN.mmdb --ip 113.215.102.222
          mmdblookup --file /etc/nginx/geoip/resource/GeoLite2-City_20230411/GeoLite2-City.mmdb --ip 113.215.102.222
          mmdblookup --file /etc/nginx/geoip/resource/GeoLite2-Country_20230411/GeoLite2-Country.mmdb --ip 113.215.102.222
        • 返回

          [root@controller resource]# mmdblookup --file /etc/nginx/geoip/resource/GeoLite2-City_20230411/GeoLite2-City.mmdb --ip 114.217.102.222
          {
          "city": 
            {
              "geoname_id": 
                1886760 <uint32>
              "names": 
                {
                  "de": 
                    "Suzhou" <utf8_string>
                  "en": 
                    "Suzhou" <utf8_string>
                  "es": 
                    "Suzhou" <utf8_string>
                  "fr": 
                    "Suzhou" <utf8_string>
                  "ja": 
                    "蘇州市" <utf8_string>
                  "pt-BR": 
                    "Suzhou" <utf8_string>
                  "ru": 
                    "Сучжоу" <utf8_string>
                  "zh-CN": 
                    "苏州市" <utf8_string>
                }
            }
          "continent": 
            {
              "code": 
                "AS" <utf8_string>
              "geoname_id": 
                6255147 <uint32>
              "names": 
                {
                  "de": 
                    "Asien" <utf8_string>
                  "en": 
                    "Asia" <utf8_string>
                  "es": 
                    "Asia" <utf8_string>
                  "fr": 
                    "Asie" <utf8_string>
                  "ja": 
                    "アジア" <utf8_string>
                  "pt-BR": 
                    "Ásia" <utf8_string>
                  "ru": 
                    "Азия" <utf8_string>
                  "zh-CN": 
                    "亚洲" <utf8_string>
                }
            }
          "country": 
            {
              "geoname_id": 
                1814991 <uint32>
              "iso_code": 
                "CN" <utf8_string>
              "names": 
                {
                  "de": 
                    "China" <utf8_string>
                  "en": 
                    "China" <utf8_string>
                  "es": 
                    "China" <utf8_string>
                  "fr": 
                    "Chine" <utf8_string>
                  "ja": 
                    "中国" <utf8_string>
                  "pt-BR": 
                    "China" <utf8_string>
                  "ru": 
                    "Китай" <utf8_string>
                  "zh-CN": 
                    "中国" <utf8_string>
                }
            }
          "location": 
            {
              "accuracy_radius": 
                100 <uint16>
              "latitude": 
                31.309300 <double>
              "longitude": 
                120.602000 <double>
              "time_zone": 
                "Asia/Shanghai" <utf8_string>
            }
          "registered_country": 
            {
              "geoname_id": 
                1814991 <uint32>
              "iso_code": 
                "CN" <utf8_string>
              "names": 
                {
                  "de": 
                    "China" <utf8_string>
                  "en": 
                    "China" <utf8_string>
                  "es": 
                    "China" <utf8_string>
                  "fr": 
                    "Chine" <utf8_string>
                  "ja": 
                    "中国" <utf8_string>
                  "pt-BR": 
                    "China" <utf8_string>
                  "ru": 
                    "Китай" <utf8_string>
                  "zh-CN": 
                    "中国" <utf8_string>
                }
            }
          "subdivisions": 
            [
              {
                "geoname_id": 
                  1806260 <uint32>
                "iso_code": 
                  "JS" <utf8_string>
                "names": 
                  {
                    "en": 
                      "Jiangsu" <utf8_string>
                    "fr": 
                      "Province de Jiangsu" <utf8_string>
                    "zh-CN": 
                      "江苏省" <utf8_string>
                  }
              }
            ]
          }

Nginx安装GeoIp2模块

  • 下载ngx_http_geoip2_module模块

    wget https://github.com/leev/ngx_http_geoip2_module/archive/refs/tags/3.4.tar.gz
    tar -zxvf 3.4.tar.gz
    cd ngx_http_geoip2_module-3.4/
    # pwd查看模块路径,等编译nginx的时候需要加上
    pwd
    
    /www/software/ngx_http_geoip2_module-3.4
  • 如果你nginx是yum或者apt安装的,查看nginx版本情况以及扩展模块情况,去官方nginx下载 下载对应版本的nginx源码
  • 如果你nginx是源码编译安装的,直接进入源码目录即可
nginx -V
# 输出信息
nginx version: nginx/1.22.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-http_realip_module
# nginx是yum或者apt安装的,我这里是v1.22.1
wget https://nginx.org/download/nginx-1.22.1.tar.gz
tar -zxvf nginx-1.22.1.tar.gz
# nginx是源码编译安装直接进入源码目录即可
cd nginx-1.22.1/
# 编译时加上 ./configure --add-dynamic-module=/path/to/ngx_http_geoip2_module,/path/to/ngx_http_geoip2_module 是你ngx_http_geoip2_module模块目录路径,我的ngx_http_geoip2_module解压到了/www/software/ngx_http_geoip2_module-3.4,所以就是 --add-dynamic-module=/www/software/ngx_http_geoip2_module-3.4
./configure  --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-http_realip_module --add-dynamic-module=/www/software/ngx_http_geoip2_module-3.4
make && make install 
# 再此查看扩展模块情况已经加载了ngx_http_geoip2_module
nginx -V
# 输出信息
nginx version: nginx/1.22.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --with-http_realip_module --add-dynamic-module=/www/software/ngx_http_geoip2_module-3.4

nginx使用GeoIp2模块

user  www www;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


load_module modules/ngx_http_geoip2_module.so;

events {
    worker_connections  1024;
}



http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    #真实ip获取
    set_real_ip_from 192.168.56.2;
    set_real_ip_from 192.168.56.3;
    set_real_ip_from 192.168.56.5;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    map $http_x_forwarded_for $realip {
       # ~ 大小写敏感,~* 大小写不敏感
       ~^(\d+\.\d+\.\d+\.\d+) $realip;
       default $remote_addr;
    }
    # geoIp2 config
    geoip2 /etc/nginx/geoip/database/GeoLite2-Country.mmdb {
        #国家编码
        $geoip2_country_code source=$realip country iso_code;
        #国家英文名
        $geoip2_country_name_en source=$realip country names en;
        #国家中文名
        $geoip2_country_name_cn source=$realip country names zh-CN;
    }

    geoip2 /etc/nginx/geoip/database/GeoLite2-City.mmdb {
        # 城市编码
        $geoip2_city_code source=$realip city geoname_id;
        # 城市英文名,大多是拼音,有重复情况
        $geoip2_city_name_en source=$realip city names en;
        # 城市中文名,部分城市没有中文名
        $geoip2_city_name_cn source=$realip city names zh-CN;
        # 经度,longitude
        $geoip2_longitude source=$realip location longitude;
        # 维度,latitude
        $geoip2_latitude source=$realip location latitude;
    }

    include /etc/nginx/conf.d/*.conf;
}

server {
    listen       80;
    server_name  localhost;

    access_log  /var/log/nginx/host.access.log  main;
    # 输出IP信息
    location ^~ /proxy1/ {
      charset utf-8;
      default_type application/json;
      set $resp_json '{"ip": $realip,"countryCode": $geoip2_country_code,"countryNameEn": $geoip2_country_name_en,"countryNameCn": $geoip2_country_name_cn,"cityCode": $geoip2_city_code,"cityNameEn": $geoip2_city_name_en,"cityNameCn": $geoip2_city_name_cn,"longitude": $geoip2_longitude,"latitude": $geoip2_latitude}';
      return 200 $resp_json;
    }

    location / {
        root   /usr/share/nginx/html;
        index   index.php index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root /usr/share/nginx/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

测试浏览器 http://192.168.56.2/proxy1/

{"ip": 180.103.200.225,"countryCode": CN,"countryNameEn": China,"countryNameCn": 中国,"cityCode": ,"cityNameEn": ,"cityNameCn": ,"longitude": 113.72200,"latitude": 34.77320}

GeoIP数据的自动更新

wget https://github.com/maxmind/geoipupdate/releases/download/v4.11.1/geoipupdate_4.11.1_linux_386.tar.gz
tar -zxvf geoipupdate_4.11.1_linux_386.tar.gz
cd geoipupdate_4.11.1_linux_386/
cp ./geoipupdate /usr/sbin/
cd /etc/nginx/geoip/
# 创建geoipupdate配置文件
vim GeoIP.conf
  • GeoIP.conf
    image
# GeoIP.conf file for `geoipupdate` program, for versions >= 3.1.1.
# Used to update GeoIP databases from https://www.maxmind.com.
# For more information about this config file, visit the docs at
# https://dev.maxmind.com/geoip/updating-databases?lang=en.

# `AccountID` is from your MaxMind account.
AccountID 你的UID

# Replace YOUR_LICENSE_KEY_HERE with an active license key associated
# with your MaxMind account.
LicenseKey 你的key

# `EditionIDs` is from your MaxMind account.
EditionIDs GeoLite2-ASN GeoLite2-City GeoLite2-Country
### 查看版本
geoipupdate -v

# 输出信息 这是默认GeoIP.conf 配置目录和数据库目录/usr/local/share/GeoIP
geoipupdate version 4.11.1
Using config file /usr/local/etc/GeoIP.conf
Using database directory /usr/local/share/GeoIP
error retrieving updates: error creating database writer for GeoLite2-ASN: database directory is not available: stat /usr/local/share/GeoIP: no such file or directory

### 查看帮助
geoipupdate -h

# 输出信息 可以用-f 指定自定义配置文件路径,使用-d 指定自定义数据库目录
 -f, --config-file string          Configuration file (default "/usr/local/etc/GeoIP.conf")
  -d, --database-directory string   Store databases in this directory (uses config if not specified)
  -h, --help                        Display help and exit
      --stack-trace                 Show a stack trace along with any error message.
  -v, --verbose                     Use verbose output
  -V, --version                     Display the version and exit

### 更新命令
geoipupdate -f /etc/nginx/geoip/GeoIP.conf -d /etc/nginx/geoip/datebase/

# crontab保持更新
crontab -e
### 指定自定义配置文件路径和指定自定义数据库目录
2 8 * * 6,4 /usr/local/bin/geoipupdate -f /etc/nginx/geoip/GeoIP.conf -d /etc/nginx/geoip/datebase/

### 默认配置文件/usr/local/etc/GeoIP.conf 和 默认数据库目录 /usr/local/share/GeoIP
2 8 * * 6,4 /usr/local/bin/geoipupdate
Last modification:April 18, 2023
如果觉得我的文章对你有用,请随意赞赏