Open-GeoIP:超简单的开源IP地址位置查询服务
前言
在线查询 IP 地址的网站好像到处都有,在线网络测速的网站也非常的多。然而如果考虑开源版本的话,网络测速有 librespeed/speedtest ,IP 地址查询似乎并没有对应的项目,是没有这个需求吗?
至少我们有这个需求,大概在2012年开始,我们就在学校内部提供在线的IP地址查询服务,主要满足这几个方面:
- 面向用户的互联网 IP 地址查询 —— 查询界面
- 面向用户的 myip 地址查询,也就是看自己的IP —— 查询界面
- 学校范畴的IP地址区分,也就是通过IP查询服务器区分“内网”,“外网”。学校有好多公网IP的。
- 面向物联网终端的 myip 地址查询 —— myip 的接口
- 面向第三方应用的 IP 地址查询 —— ip 查询接口
- 要支持 IPv6
10年后,我们把这块的业务代码进行了重构,并且开源了 —— ECNU/open-geoip 。
快速体验
体验 Open-GeoIP 非常简单,下载我们打包好的 Releases ,解压直接运行即可
tar -zxvf open-geoip-0.1.0-linux-amd64.tar.gz
cd open-geoip/
./control start
此时访问服务器的 80 端口应该就可以看到服务。
Release 中使用了内置的数据库文件来自于 ipdb-go 所提供的 city.free.ipdb
。它仅供测试,不能保障数据的准确性。如果想要尝试最新的 ipdb
试用数据,可以在www.ipip.net/product/cli… 下载更新的试用版,但注意不可以用于正式商业用途。
生产环境
考虑生产环境,我们需要一个可以持续更新的 IP 地理信息数据库。Open-GeoIP 可以支持 maxmind 的 GeoLite2 数据库并且支持自动更新,因此我们只需要在注册一个 maxmind
的账号,获得一个 LicenseKey ,并将他配置到 cfg.json
中的 AutoDownload.MaxmindLicenseKey
中,或者配置到系统环境变量 MAXMIND_LICENSE_KEY
中即可。
修改配置文件的这部分,开启 autoDownload
的 enbaled
选项,并配置好你的 licenseKey
。将数据源替换为 maxmind
。由于我们采取自动更新获取 maxmind
的数据库,因此 db
部分不需要配置了。
"db": {
"maxmind": "",
"qqzengip": "",
"ipdb":""
},
"source": {
"ipv4": "maxmind",
"ipv6": "maxmind"
},
"autoDownload":{
"enabled":true,
"MaxmindLicenseKey":"your-license-key",
"targetFilePath":"",
"timeout":3,
"interval":24
},
重启服务,此时应该会自动下载 GeoLite2-City.mmdb
并每 24 小时检查一次更新。
./control restart
systemctl 托管
在生产环境中,我们最好使用 systemctl
来托管服务,项目仓库内已经写好了一个参考的配置文件。假定项目部署在 /opt/open-geoip
目录下,如果部署在其他目录修改 open-geoip.service
中的 WorkingDirectory
和 ExecStart
两个字段即可。
cp open-geoip.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable open-geoip
systemctl start open-geoip
更多数据库支持
maxmind 的数据库虽然很好而且免费,然而它在大陆地区的精度确实不敢恭维,最大的优势可能就是支持 ipv6 了。如果我们采购了商业的 IP 地址库资源,例如 www.ipip.net
或者 https://www.qqzeng.com
,那么可以将对应的 source
源修改为 ipdb
或者 qqzengip
,并在 db
内配置对应的数据库文件路径。Open-GeoIP 就会将对应的请求通过该数据库来查询。
更多数据库的支持,欢迎在 [Feature]更多数据源支持 · Issue #7 中反馈。
API 接口
除了直接面向用户的界面查询之外,Open-GeoIP 设计了一系列的接口来更好为各类物联网终端,第三方应用提供支持。
myip
myip 的接口用于返回请求者的 IP 地址,对于一些无浏览器的终端,可以使用这个接口方便的获取自身的IP地址信息(特别是 nat 后的)。
它也可以被配置了 CORS 的网站通过前端调用, 提供了简单字符串与 json 格式化两种风格接口。
# curl http://localhost/myip
# 192.168.0.100
# curl http://localhost/myip/format
# {"errCode":0,"errMsg":"success","requestId":"0f40823e-04ce-4def-9af2-71e7e1403ec8","data":{"ip":"192.168.0.100"}}
openapi
openapi 接口面向第三方应用,提供了一个 IP 地址的查询接口,通过 X-API-KEY 进行授权校验。
在我们的实际环境李,我们通过 API 网关做进一步的代理封装,从而授权分发给不同的租户。
- request
curl -H "X-API-KEY: this-is-key" http://localhost/api/v1/network/ip?ip=2001:da8:8005:a405:250:56ff:feaf:8c28
- response
{
"errCode": 0,
"errMsg": "success",
"requestId": "7ead62f7-3f15-4822-ad1e-cf7915a8299f",
"data": {
"ip": "2001:da8:8005:a405:250:56ff:feaf:8c28",
"continent": "亚洲",
"country": "中国",
"province": "上海",
"city": "上海",
"district": "",
"isp": "",
"areaCode": "",
"countryEnglish": "China",
"countryCode": "CN",
"longitude": "121.458100",
"latitude": "31.222200"
}
}
benchmark
基于 maxmind
数据库进行的 web
服务性能测试
# go test -bench=. -benchmem
goos: linux
goarch: amd64
pkg: github.com/ECNU/open-geoip
cpu: Intel(R) Xeon(R) Platinum 8369B CPU @ 2.70GHz
BenchmarkIndex-2 244190 4271 ns/op 10000 B/op 15 allocs/op
BenchmarkSeachAPIForIPv4-2 782768 1741 ns/op 1904 B/op 15 allocs/op
BenchmarkSeachAPIForIPv6-2 818250 1744 ns/op 1904 B/op 15 allocs/op
BenchmarkOpenAPIForIPv4-2 394813 3383 ns/op 2592 B/op 23 allocs/op
BenchmarkOpenAPIForIPv6-2 391868 3378 ns/op 2592 B/op 23 allocs/op
PASS
ok github.com/ECNU/open-geoip 7.044s
鸣谢
本项目的一些主要功能使用了以下开源项目,更多的依赖详见 ``open-geoip/go.mod 文件。
感谢他们的开源精神。
web
服务 —— ginmaxmind
解析 —— geoip2-golangmaxming
自动更新 —— go-geoipipdb
解析 —— ipdb-goqqzengip
解析 —— qqzeng-ip
原文链接:【xie.infoq.cn/article/302…】。
本文遵守【CC BY-SA】协议,转载请保留原文出处及本版权声明。
转载自:https://juejin.cn/post/7215207897520980005