使用 geo 模块实现客户端访问地域访问限制
描述:ngx_http_geo_module 模块用于根据客户端的 IPV4/IPV6 地址范围,创建不同内网、外网的变量值(通常命名为 $country 或者 $location),进而将流量分配到不同的服务器或配置上。这对于实现地理位置限制、分流、负载均衡等场景非常有用。其默认编译进行 nginx 当中,可以通过 --without-http_geo_module 参数禁用。
温馨提示:若文章代码块中存在乱码,请通过文末的阅读原文链接,在知识星球中阅读,或者直接访问原文链接:https://articles.zsxq.com/id_rx229kjix356.html
指令参数
# 描述指定变量的值对客户端IP地址的依赖关系。
Syntax: geo [$address] $variable { ... }
Default: —
Context: http
# 还支持以下特殊参数:
delete 删除指定的网络
default 设置默认值,若客户端地址与任何指定的地址都不匹配,则为变量设置一个值。
proxy 定义可信地址,当请求来自可信地址时,将使用“X-Forwarded-For”请求报头字段中的地址。
proxy_recursive 启用递归地址搜索,如果禁用递归搜索,则将使用“X-Forwarded-For”中发送的最后一个地址,而不是与某个受信任地址匹配的原始客户端地址。
range 表示地址被指定为范围
include 包括具有地址和值的文件。
温馨提示:geo 模块中的匹配优先级是优先最长匹配原则,即先匹配到最长范围的地址。
官方文档:https://nginx.org/en/docs/http/ngx_http_geo_module.html
示例演示
例 1.默认情况下,地址取自$remote_addr变量,但也可以取自另一个变量,例如自定义 $http_real_ip 头。
geo $geo {
default 0;
127.0.0.1 2;
192.168.1.0/24 1;
10.1.0.0/16 1;
::1 2;
2001:0db8::/32 1;
}
# 自定义
geo $http_real_ip$geo {
default EXTERNAL;
127.0.0.1 LOCAL;
192.168.0.0/24 INTERNAL;
172.16.0.0/12 INTERNAL;
10.0.0.0/8 INTERNAL;
}
例 2.使用内网地址模拟区域访问限制,例如,禁止美国 IP 访问。
http {
geo $country {
default ZZ;
# 此外为了演示则为 nginx 本机地址,实际生产中,通常会是CDN、负载均衡器或者反向代理服务器的 IP。
proxy 10.20.172.214; # 指定可信代理的 IP, 即 remote_addr 不会取器值作为访问IP地址。
proxy_recursive;
include geo.conf; # 包含额外的地址和值,生产环境中,通常会将这部分内容单独维护。
127.0.0.0/24 LOCAL;
192.168.0.0/24 CN;
172.16.0.0/12 RU;
10.0.0.0/8 US;
}
server {
listen 80;
server_name test.weiyigeek.top;
default_type application/octet-stream;
location / {
# 假设,禁止美国 IP 访问,其他国家正常访问。
if ($country = "US") {
return 403;
}
add_header X-Country $country always;
add_header X-Real-IP $http_x_forwarded_for always;
return 200 "OK, Your country is: $country, X-Forwarded-For is : $http_x_forwarded_for\n";
}
}
}
另外,在生成用于测试的 geo.conf 文件时,可以使用以下命令:
cd /usr/local/nginx/conf
# 中国
echo "61.128.127.0/24 CN;" > geo.conf
# 俄罗斯
echo "193.238.44.0/24 RU;" >> geo.conf
同样,在 214 主机上使用 curl 命令与 X-Forwarded-For 头模拟不同的客户端 IP 访问测试,可以看到不同网段中的 country 值是不同的,执行返回结果如下所示:
# 匹配的 country 值为 US ,返回 403
curl -H "X-Forwarded-For: 61.128.128.200,10.0.0.1" http://test.weiyigeek.top/
# 匹配的 country 值为 RU, 返回正常页面
curl -H "X-Forwarded-For: 193.238.44.1" http://test.weiyigeek.top/
# 匹配的 country 值为 LOCAL, 返回正常页面
curl -H "X-Forwarded-For: 127.0.0.1" http://test.weiyigeek.top/
# 匹配的 country 值为 CN, 返回正常页面
curl -H "X-Forwarded-For: 127.0.0.1,10.0.0.1,61.128.127.66" http://test.weiyigeek.top/
# 匹配的 country 值为 RU, 返回正常页面
curl -H "X-Forwarded-For: 127.0.0.1,172.16.0.33" http://test.weiyigeek.top/
# 匹配的 country 值为 ZZ, 返回正常页面
curl -H "X-Forwarded-For: 127.0.0.1,223.6.6.6" http://test.weiyigeek.top/
weiyigeek.top-模拟不同客户端IP地址国家访问限制图温馨提示:使用手动指定规则通常应用于小范围的 IP 地址,对于大规模的 IP 段划分,建议使用 geoip 或者 geoip2 等模块。
阅读原文:原文链接
该文章在 2025/10/29 18:57:26 编辑过