geo模块是轻量级ip段映射工具,仅支持cidr/单ip/范围匹配,需置于http块中,配合map实现语义化策略,并依赖real_ip模块获取真实ip;不适用于国家/城市级地理定位。

geo 模块不识别真实地理位置,只做 IP 段映射。它本质是轻量、高性能的静态 IP 分类工具,适合做内网/外网区分、测试环境隔离、简单地域分流等场景,但不能替代 GeoIP2 实现国家/城市级控制。
基础配置必须放在 http 块中
geo 指令只能在 http 上下文中声明,不能写在 server 或 location 里。它通过匹配客户端 IP(默认取 $remote_addr)来为变量赋值:
- 支持 CIDR 表示法(如
192.168.1.0/24)、单 IP(127.0.0.1)、IP 范围(需加ranges参数) - 用
default设定未匹配时的值,比如default "ZZ" - 匹配遵循最长前缀优先原则,例如
192.168.1.100同时命中192.168.0.0/16和192.168.1.0/24,会选后者 - 可通过
include引入外部文件管理大量规则,便于维护
配合 map 实现语义化策略
geo 输出的是字符串值,直接用于逻辑判断易出错。推荐用 map 做二次转换:
- 把国家简码转成布尔标志:
map $country_code $is_allowed { default 0; "CN" 1; "JP" 1; } - 把区域映射为 upstream 名称:
map $country_code $backend { default backend_global; "CN" backend_cn; "US" backend_us; } - 避免在
location中滥用if,更稳妥的方式是透传变量给后端鉴权,或用auth_request
注意真实 IP 的获取与可信代理设置
如果 Nginx 前有 CDN、负载均衡器或反向代理,$remote_addr 就是它们的 IP,不是用户真实 IP。此时需配合 real_ip 模块:
- 用
set_real_ip_from声明可信代理地址段 - 用
real_ip_header X-Forwarded-For指定头字段 - 开启
real_ip_recursive on可递归提取最外层非代理 IP - geo 块中也可加
proxy和proxy_recursive参数,效果类似
适用场景与局限提醒
geo 模块适合这些需求:
- 区分内网请求(
10.0.0.0/8、192.168.0.0/16)和公网流量 - 按运营商段做简单分流(如电信/联通 IP 段指向不同节点)
- 灰度发布时限制某批测试 IP 访问新接口
- 日志中记录请求来源区域标识,辅助分析
但它不适合需要精确国家、省份、城市识别的场景——这类需求必须用 ngx_http_geoip2_module 加载 MaxMind 数据库实现。











