chaihongjun.me

Geoip2在nginx服务器上的应用

Geoip2结合nginx可以有多种功能实现,比如给网站的访问日志增加访客的物理位置,或者真对某一物理位置的访客设置针对性的访问规则。这里使用的是lite版本也就是免费版本,它的数据来足够大部分非精确需求的使用了,这篇记录一下从注册服务到后期配置使用的整个过程。

注册maxmind账户

前往 https://www.maxmind.com/en/geolite2/signup 进行注册,注册的邮箱作为登录账户名,邮箱会收到一封邮件提醒设置账户密码(密码可重置)

获取License

前往 https://www.maxmind.com/en/account/login  登录

登录之后,点击左侧位于【Account】下的的Manage License Keys,然后再点击右侧的Generate new license key,根据提示操作生成license,和这里的【Account/User ID】后续配置数据库升级会用到

下载数据并上传到服务器

依然是点击后台的Download Files,分别下载GeoLite2 City和GeoLite2 Country这两份数据,下载并解压完之后得到GeoLite2-City.mmdb和GeoLite-Country.mmdb这两个数据文件。

将这两个数据文件上传到服务器目录,比如/alidata1/GeoDatabases。

给nginx安装ngx_http_geoip2_module

这里使用静态方式安装这个模块,前往 https://github.com/leev/ngx_http_geoip2_module/release 下载最新版本

安装模块:

./configure {默认参数} --add-module=/path/to/ngx_http_geoip2_module
make
# 后续平滑升级部分

安装maxmind支持库

前往 https://github.com/maxmind/libmaxminddb/release  下载最新版,然后安装配置:

# 进入源码包后
./configure
make
make check
make install
ldconfig

配置生效

创建IP地址库解析映射的配置文件/usr/local/nginx/conf/Geoip2.conf:

#IP地址库解析映射
geoip2 /alidata1/GeoDatabases/GeoLite2-Country.mmdb {
    auto_reload 5 m;
    $geoip2_metadata_country_build metadata build_epoch;
    $geoip2_country_code country iso_code;
    $geoip2_country_name country names en;
}
geoip2 /alidata1/GeoDatabases/GeoLite2-City.mmdb {
    $geoip2_metadata_city_build metadata build_epoch;
    $geoip2_data_city_name city names en;
    $geoip2_data_continent_code continent code;
    $geoip2_data_continent_name continent names en;
    $geoip2_data_country_code country iso_code;
    $geoip2_data_country_name country names en;
    $geoip2_data_region_iso subdivisions 0 iso_code;
    $geoip2_data_region_name subdivisions 0 names en;
}

以上配置,后期nginx的日志中午地名会以拼音形式显示,如果仍然希望是中文显示,则使用如下:

#IP地址库解析映射
geoip2 /alidata1/GeoDatabases/GeoLite2-Country.mmdb {
    auto_reload 5 m;
    $geoip2_metadata_country_build metadata build_epoch;
    $geoip2_country_code country iso_code;
    $geoip2_country_name country names zh-CN;
}
geoip2 /alidata1/GeoDatabases/GeoLite2-City.mmdb {
    $geoip2_metadata_city_build metadata build_epoch;
    $geoip2_data_city_name city names zh-CN;
    $geoip2_data_continent_code continent code;
    $geoip2_data_continent_name continent names zh-CN;
    $geoip2_data_country_code country iso_code;
    $geoip2_data_country_name country names zh-CN;
    $geoip2_data_region_iso subdivisions 0 iso_code;
    $geoip2_data_region_name subdivisions 0 names zh-CN;
}

以上二选一。

修改fastcgi.conf:

# 在文件末尾添加如下
# Geoip2
 fastcgi_param GEOIP2_CITY_BUILD_DATE $geoip2_metadata_city_build;
 fastcgi_param GEOIP2_CITY $geoip2_data_city_name;
 fastcgi_param GEOIP2_CONTINENT_CODE $geoip2_data_continent_code;
 fastcgi_param GEOIP2_CONTINENT_NAME $geoip2_data_continent_name;
 fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_data_country_code;
 fastcgi_param GEOIP2_COUNTRY_NAME $geoip2_data_country_name;
 fastcgi_param GEOIP2_REGION $geoip2_data_region_iso;
 fastcgi_param GEOIP2_REGION_NAME $geoip2_data_region_name;

至此,配置部分完成。以上配置方便在nginx的配置文件中使用自定义的变量,比如:$geoip2_data_county_name。

数据文件升级

前面下载的数据文件无法自动更新,需要使用官方的geoipupdate帮助数据保持跟新。前往 https://github.com/maxmind/geoipupdate/releases 下载更新工具,放入/usr/local/bin目录。

然后配置数据文件升级脚本,这个就涉及到最先开始注册后得到的license和UserID。创建文件/usr/local/etc/GeoIP.conf(建议保持这个路径和文件名,geoip模块默认读取):

# The following AccountID and LicenseKey are required placeholders.
# For geoipupdate versions earlier than 2.5.0, use UserId here instead of AccountID.
# 下面两项可以在 Manage License Keys 获取
AccountID 这里写你的ID
LicenseKey 这里写你的Licensekey
     
# Include one or more of the following edition IDs:
# * GeoLite2-City - GeoLite 2 City
# * GeoLite2-Country - GeoLite2 Country
# For geoipupdate versions earlier than 2.5.0, use ProductIds here instead of EditionIDs.
EditionIDs GeoLite2-City GeoLite2-Country
  
# 自定义的数据库目录,这里是前面放两个mmdb数据文件的目录
DatabaseDirectory /alidata1/GeoDatabases

设置定时升级IP数据库

32 6 * * 3 /usr/local/bin/geoipupdate

实际应用举例

首先,在nginx主配置文件中引入geoip:

# nginx.conf
include /usr/loca/nginx/conf/Geoip2.conf;

再修改nginx日志格式:

log_format main escape=json
[$remote_addr]-[$time_local]-[$request]-[$status]-[$http_user_agent]-[$uri]-[$geoip2_data_country_name]-[$geoip2_data_reigon_name]-[$geoip2_data_city_name];

上面的配置会在访问日志的最后显示访客的“国家-省份-城市”。

另外,针对特定地区的访问控制,可以这样做:

# 禁止河北访问
if($geoip2_data_region_name ~* Hebei){
    return 444;
}
# 禁止广州访问
if($geoip2_data_city_name ~* Guangzhou){
    return 444;
}


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»