likes
comments
collection
share

Open-GeoIP:超简单的开源IP地址位置查询服务

作者站长头像
站长
· 阅读数 14

前言

在线查询 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 端口应该就可以看到服务。

Open-GeoIP:超简单的开源IP地址位置查询服务

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 中即可。

修改配置文件的这部分,开启 autoDownloadenbaled 选项,并配置好你的 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 文件。

感谢他们的开源精神。

原文链接:【xie.infoq.cn/article/302…】。

本文遵守【CC BY-SA】协议,转载请保留原文出处及本版权声明。