GeoIP,是一套含IP数据库的软件工具。

Geo根据来访者的IP, 定位该IP所在经纬度、国家/地区、省市、和街道等位置信息。

GeoIP有两个版本,一个免费版,一个收费版本。

收费版本的准确率高一些,更新频率也更频繁。

因为GeoIP读取的是本地的二进制IP数据库,所以效率很高,比从APNIC读取再转换高很多。

PHP支持通过扩展方式读取GeoIP数据。

本文介绍CentOS和Ubuntu系统的安装和使用方法。

1 安装GeoIP

命令方式安装:

yum install geoip geoip-devel # CentOS

apt-get install php5-geoip php5-dev libgeoip-dev # Ubuntu

或者通过源码方式安装,两者选择其一:

GeoIP安装完成后,IP库文件会安装在这个目录下:/usr/share/GeoIP。

2 安装geoip扩展

编译成动态库:

$ wget https://pecl.php.net/get/geoip-1.1.1.tgz
$ cd geoip-1.1.1
$ phpize
$ ./configure
$ make
$ sudo make install
安装完成后,在/usr/lib64/php/modules/目录下(64位系统)生成geoip.so链接库。
打开php.ini文件,在最后加上:
extension=geoip.so
重启PHP-FPM就可以用了。
3 PHP中使用
示例:
$data = geoip_record_by_name('php.net');
print_r($data);
输出:
Array
(
[continent_code] => NA
[country_code] => US
[country_code3] => USA
[country_name] => United States
[region] => CA
[city] => Milpitas
[postal_code] => 95035
[latitude] => 37.440399169922
[longitude] => -121.87049865723
[dma_code] => 807
[area_code] => 408
)
4 更新IP库
GeoIP默认使用Maxmind提供的IP库,这可以用geoip_database_info()方法看到。
例如我的显示:
GEO-106FREE 20170404 Build 1 Copyright (c) 2017 MaxMind Inc All Rights Reserved
Maxmind提供的IP库会在每个月的第一个星期二更新一次,所以我们在此时间后一天执行更新就能拿到最新的APNIC的IP库了。
首先查看是否有文件:/etc/GeoIP.conf。
如果没有,就创建一个,内容:
# The following UserId and LicenseKey are required placeholders:
UserId 999999
LicenseKey 000000000000
# Include one or more of the following ProductIds:
# * GeoLite2-City - GeoLite 2 City
# * GeoLite2-Country - GeoLite2 Country
# * GeoLite-Legacy-IPv6-City - GeoLite Legacy IPv6 City
# * GeoLite-Legacy-IPv6-Country - GeoLite Legacy IPv6 Country
# * 506 - GeoLite Legacy Country
# * 517 - GeoLite Legacy ASN
# * 533 - GeoLite Legacy City
ProductIds GeoLite2-City GeoLite2-Country GeoLite-Legacy-IPv6-City GeoLite-Legacy-IPv6-Country 506 517 533
然后在Linux下手动执行一遍更新命令:
geoipupdate -v
如果没有出错,就完成更新GeoIP库了。
4.1 crontab自动更新IP库
我们可以使用Linux crontab可以实现自动更新IP库。
使用如下命令打开当前用户的crontab文件:
crontab -e
添加一行:
30 2 * * 3#1 /usr/bin/geoipupdate
这一段的功能是,在每个月第一个星期三自动执行 geoipupdate 命令,执行时间在凌晨2点30分。
因为Maxmind是每月的第一个星期二更新IP库,所以我们选择延迟一点,避免时差引起误差。
然后重启 crond:
/sbin/service crond restart
如果有防火墙,geoipupdate需要 DNS 和HTTPS(443)端口打开。
4.2 手动更新IP库
如果用PHP更新,让PHP执行SHELL命令执行更新:
echo shell_exec('geoipupdate -v');

执行完成会打印出更新的相关信息。

如果不需要输出信息可以去掉-v参数。