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; }