根据IP进行国家省份和城市的定位实现

发布时间 2023-08-22 16:06:04作者: 网无忌

一. 需求背景

 
这种功能在很多社交软件上很早就已经实现了,比如虎扑上发的贴子都会显示发帖人的所在地,一般是精确到省份。
对于我目前正在写的WAF来说,如果能在拦截日志中显示IP所在地的话,就更直观了,还可以针对某个国家或地区的IP进行拦截,后期还可以按照地区生成大屏统计图表。
 

二. IP库的选型

 
其实问题的核心就是选择到合适的IP库,从我的需求角度,有以下几方面的考虑指标:

1. 是否开源或免费;

2. 是否同时支持IPv4和IPv6;

3. 查找效率、准确率和精度;

4. 更新频率和效率;

 
根据上面的指标,对目前的几种IP库进行了横向的对比:
 

1. MaxMind - GeoLite2(免费,每周更新两次,支持IPv6)

官网:https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
评价:老牌IP库,效率较低,精度较低
 

2. IP2Location - IP2Location LITE(免费,每月更新一次,支持IPv6)

官网:https://lite.ip2location.com/ip2location-lite
评价:现阶段性价比最高的了
 

3. 狮子的魂 - ip2region(开源,免费,不定时更新,不支持IPv6)

官网:https://gitee.com/lionsoul/ip2region
评价:不支持IPv6,且未来也没有考虑
 

4. IPIP(试用版免费,不定时更新,试用版不支持IPv6)

官网:https://www.ipip.net/product/ip.html
评价:国内最专业的IP服务商,价格不贵,未来可以考虑
 

5. 纯真IP(社区版免费,每周更新,不支持IPv6)

官网:https://www.cz88.net
评价:社区版的离线IP库不支持IPv6,离线API支持v6,但价格承受不起,每年好几个W
 
最终还是选择了各方面更均衡的IP2Location LITE,等以后有更高要求了再升级到IPIP。
 

三. 史上最简单的安装过程

 

1. 注册账号

IP2Location LITE是完全免费的,只需要注册个账号就可以下载IP库了。
官网地址:https://lite.ip2location.com/ip2location-lite
这里要备注两个小问题:
1、在国内直接访问ip2location的官网速度很快,但在注册账号页面如果不FQ就显示不出来人机验证,也就没办法注册,所以还是需要FQ;
2、免费版的IP2Location LITE账号和收费版的IP2Location账号是不通用的;
 

2. 下载IP库

登录成功后,点击个人头像就可以进入到下载页面:

我使用的是 IP-COUNTRY-REGION-CITY > IPv6 的BIN版本,同时包含了IPv4的数据,精确到城市,大小是86MB,带经纬度的没有必要,文件也太大了。
下载之后将BIN文件移动到服务器任意位置,比如:/home/my/iplib/IP2LOCATION-LITE-DB3.IPV6.BIN
备注:
1、IP2Location在每个月的第一天更新IP2Location数据库;
2、下载连接是有次数限制的,好像是每个月3次,下载次数过多账号有被冻结的风险;
 

3. 安装 OpenResty 的 IP2Location 组件

官网文档:https://www.ip2location.com/development-libraries/ip2location/openresty
其实就一行代码:

opm get ip2location/ip2location-resty

利用 OpenResty 的包管理器(opm)一键安装完成。
 
如果在安装过程中出现以下错误:

Can't locate Digest/MD5.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/local/openresty/bin/opm line 16.
BEGIN failed--compilation aborted at /usr/local/openresty/bin/opm line 16.

原因是缺少 perl-Digest-MD5,使用yum安装即可:

yum -y install perl-Digest-MD5

 

4. 体验

在 nginx.conf 中,随便找个 server,在下面添加一个新的 location:

location /ip {
    default_type text/html;
    content_by_lua_block {
        local ip2location = require('ip2location')
        local ip2loc = ip2location:new('/home/my/iplib/IP2LOCATION-LITE-DB3.IPV6.BIN')
        local result = ip2loc:get_all('8.8.8.8')
        ngx.say("<p>国家缩写: " .. result.country_short .. "</p>")
        ngx.say("<p>国家全称: " .. result.country_long .. "</p>")
        ngx.say("<p>区域: " .. result.region .. "</p>")
        ngx.say("<p>城市: " .. result.city .. "</p>")
        ip2loc:close()
    }
}

页面显示:

国家缩写: CN
国家全称: China
区域: Liaoning
城市: Liaoyang

稍微有点遗憾的是查询结果显示的是英文和拼音,不过也不影响实际使用。
 

5. IP库的更新

登录 IP2Location LITE 官网以后,在 数据库 下载页面,每个账号都会生成一个单独的下载链接,后期可以利用 wget 等工具从服务器上直接通过这个链接下载更新IP库即可,注意的是不要频率太高,容易被封号。