
[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ]
📢 大家好,我是 WeiyiGeek,一名深耕安全运维开发(SecOpsDev)领域的技术从业者,致力于探索DevOps与安全的融合(DevSecOps),自动化运维工具开发与实践,企业网络安全防护,欢迎各位道友一起学习交流、一起进步 🚀,若此文对你有帮助,一定记得倒点个关注⭐与小红星❤️,收藏学习不迷路 😋 。
使用 geoip 库解析客户端地址实现获取地理位置 geoip 模块实践
描述:nginx 的 ngx_http_geoip_module 模块允许使用 MaxMind GeoIP 以.dat结尾的二进制数据库文件,来确定客户端 IP 地址的地理位置信息,例如,国家、城市、乃至 IP 地址的经纬度(大致区域) 等。这对于实现基于地理位置的内容分发或访问控制非常有用。此外,此模块需要MaxMind GeoIP库,默认情况下 nginx 不会构建此模块,应使用 --with-http_geoip_module 配置参数启用此模块。
温馨提示:若文章代码块中存在乱码,请通过文末的阅读原文链接,在知识星球中阅读,或者直接访问原文链接:https://articles.zsxq.com/id_rx229kjix356.html
温馨提示:目前,MaxMind 官方已经不再提供早期的 dat 格式数据库下载链接,但仍然可以登录注册免费获取 GeoLite2 数据库,但是需要使用 geoip2 模块,而非 geoip,作者在后续小节中也会简单介绍和演示。
作者也在 Google 上找到了一个 GeoIP.dat 数据库其它下载源(支持 Maxmind & DB-IP),也是在持续更新的,地址 https://www.miyuru.lk/geoiplegacy。
模块指令
# 指定用于根据客户端IP地址确定国家/地区的数据库文件。
Syntax: geoip_country file;
Default: —
Context: http
# 相关变量
$geoip_country_code :两个字母的国家代码,例如“RU”、“US”。
$geoip_country_code3 :三个字母的国家代码,例如“罗斯”、“美国”。
$geoip_country_name :国名,例如“俄罗斯联邦”、“美国”。
# 指定用于根据客户端IP地址确定国家、地区和城市的数据库。
Syntax: geoip_city file;
Default: —
Context: http
# 相关变量,除了与 geoip_country 重叠的三个
$geoip_area_code :电话区号(仅限美国)
$geoip_city_continent_code :两个字母的洲代码,例如“EU”、“NA”。
$geoip_dma_code :美国的DMA区域代码(也称为“地铁代码”),根据Google AdWords API中的地理定位。
$geoip_latitude :纬度,南北纬(0-90°)
$geoip_longitude :经度,东西经(0-180°)
$geoip_region:两个符号的国家地区代码(地区、领土、州、省、联邦土地等),例如“48”、“DC”。
$geoip_region_name :国家地区名称(地区、领土、州、省、联邦土地等)
$geoip_city :城市名称
$geoip_postal_code :邮政编码(仅限美国)
# 指定用于根据客户端IP地址确定组织的数据库。
Syntax: geoip_org file;
Default: —
Context: http
# 相关变量
$geoip_org :组织名称
# 定义受信任的地址,当请求来自可信地址时,将使用“X-Forwarded-For”请求报头字段中的地址。
Syntax: geoip_proxy address | CIDR;
Default: —
Context: http
# 如果禁用、启用递归搜索,用于确定客户端IP地址。
Syntax: geoip_proxy_recursive on | off;
Default: geoip_proxy_recursive off;
Context: http
温馨提示:确保可信代理列表正确,请务必在 geoip_proxy 指令中列出所有你内部的、可信的代理服务器或负载均衡器的 IP 段。如果漏掉,这些 IP 会被当作客户端 IP 处理,导致 GeoIP 信息错误。
知识扩展:指令 geoip_proxy_recursive 禁用、启用递归搜索不同配置下的结果,现在,我们模拟一个请求,它经过了两个代理:192.168.100.100 (你的可信代理) 和 10.0.1.5 (一个上游代理或 CDN 节点)。请求到达 Nginx 时,X-Forwarded-For 头是这样的:X-Forwarded-For: 203.0.113.50, 10.0.1.5, 192.168.100.100
Nginx 看到的直接连接 IP ($remote_addr) 是 192.168.100.100。
|
|
|
|
|---|---|---|
geoip_proxy_recursive off; |
10.0.1.5 |
192.168.100.100 是可信代理,于是简单地使用它左边的一个 IP(即 10.0.1.5)作为客户端 IP。这显然不是真实的用户 IP。
|
geoip_proxy_recursive on; |
203.0.113.50 |
递归地跳过所有在可信列表中的 IP。它跳过了 192.168.100.100,继续检查 10.0.1.5 不在可信列表,于是停止查找,并使用 203.0.113.50 这个真实的客户端 IP。
|
温馨提示:如今的服务通常部署在负载均衡器、CDN 或云平台之后,网络路径比较复杂。建议将 geoip_proxy_recursive on; 作为默认配置,这样更有可能准确获取到真实的终端用户 IP。
示例演示
步骤 01.首先安装 MaxMind GeoIP 依赖库,然后重新编译 Nginx 源码,使之启用 GeoIP 模块。
# 安装 GeoIP 依赖库
# Redhat 系
sudo yum install GeoIP GeoIP-devel
# Debian 系
# sudo apt-get update
# sudo apt-get install libgeoip-dev
# 安装 Nginx
cd /usr/local/src/nginx-1.29.0
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --error-log-path=/var/log/nginx/logs/error.log --http-log-path=/var/log/nginx/logs/access.log --lock-path=/var/run/nginx.lock --modules-path=/usr/local/nginx/modules --with-http_stub_status_module --with-http_sub_module --with-http_addition_module --with-http_secure_link_module --with-http_geoip_module
make && make install
步骤 02.访问 GeoIP Legacy Databases (DAT) 页面分别下载 Maxmind - City 和 DB-IP - Country 数据库文件,并上传到 nginx 的配置目录下。
# Maxmind - City IPv6/IPv4 (19.46M) - 城市(测试:大致准确)
wget https://dl.miyuru.lk/geoip/maxmind/city/maxmind.dat.gz
# DB-IP - Country IPv6/IPv4 (3.29M) - 国家 (推荐使用)
wget https://dl.miyuru.lk/geoip/dbip/country/dbip.dat.gz -O dbip.dat.gz
# DB-IP - City IPv6/IPv4 (50.90M) - 城市(测试:有的缺少省会)
wget https://dl.miyuru.lk/geoip/dbip/city/dbip.dat.gz -O dbip-city.dat.gz
# 解压文件 & 移动到 nginx 配置目录下
gunzip -k maxmind.dat.gz
gunzip -k dbip.dat.gz
gunzip -k dbip-city.dat.gz
mv maxmind.dat dbip.dat dbip-city.dat /usr/local/nginx/conf/
步骤 03.在 nginx 配置文件中,使用 geoip_country 与geoip_city 指令分别指定 dbip.dat 、maxmind.dat 文件来组合使用,演示起相关指令的使用,并输出地址位置变量。
http {
# 指定用于根据客户端IP地址确定国家/地区的数据库文件。
geoip_country /usr/local/nginx/conf/dbip.dat;
geoip_city /usr/local/nginx/conf/dbip-city.dat;
geoip_proxy 10.20.172.214; # 指定可信代理的 IP, 即 remote_addr 不会取器值作为访问IP地址。
geoip_proxy_recursive on;
server {
listen 80;
server_name test.weiyigeek.top;
default_type application/octet-stream;
location /geoip {
return 200 'geoip_country_code: $geoip_country_code
geoip_country_code3: $geoip_country_code3
geoip_country_name: $geoip_country_name
geoip_area_code:$geoip_area_code
geoip_city_continent_code:$geoip_city_continent_code
geoip_dma_code:$geoip_dma_code
geoip_latitude:$geoip_latitude
geoip_longitude:$geoip_longitude
geoip_region:$geoip_region
geoip_region_name:$geoip_region_name
geoip_city:$geoip_city
geoip_postal_code:$geoip_postal_code
';
}
在百度上搜索免费 HTTP 代理 IP ,找到几个地址做测试,可以发现精简了一些变量,例如:geoip_country, geoip_country_name 等。
# 223.215.176.236 8089 高匿 HTTP 0.02 秒 安徽省马鞍山市 电信
curl -H "X-Forwarded-For: 127.0.0.1,223.215.176.236" http://test.weiyigeek.top/geoip
# 82.156.18.253 北京腾讯云
curl -H "X-Forwarded-For: 127.0.0.1,61.128.128.68,82.156.18.253" http://test.weiyigeek.top/geoip
# 62.210.215.36 法国巴黎
curl -H "X-Forwarded-For: 127.0.0.1,62.210.215.36" http://test.weiyigeek.top/geoip
官方文档:https://nginx.org/en/docs/http/ngx_http_geoip_module.html
加入:作者【全栈工程师修炼指南】知识星球
『 全栈工程师修炼指南』星球,主要涉及全栈工程师(Full Stack Development)实践文章,包括但不限于企业SecDevOps和网络安全等保合规、安全渗透测试、编程开发、云原生(Cloud Native)、物联网工业控制(IOT)、人工智能Ai,从业书籍笔记,人生职场认识等方面资料或文章。
Q: 加入作者【全栈工程师修炼指南】星球后有啥好处?
✅ 将获得作者最新工作学习实践文章以及网盘资源。
✅ 将获得作者珍藏多年的全栈学习笔记(需连续两年及以上老星球友,也可单次购买)
✅ 将获得作者专门答疑学习交流群,解决在工作学习中的问题。
✅ 将获得作者远程支持(在作者能力范围内且合规)。

获取:作者工作学习全栈笔记
作者整理了10年的工作学习笔记(涉及网络、安全、运维、开发),需要学习实践笔记的看友,可添加作者微信或者回复【工作学习实践笔记】,当前价格¥299,除了获得从业笔记的同时还可进行问题答疑以及每月远程技术支持,希望大家多多支持,收获定大于付出!

知识推荐 往期文章
若文章对你有帮助,请将它转发给更多的看友,若有疑问的小伙伴,可在评论区留言你想法哟 💬!


