Nginx 配置允许指定 IP 段访问
一、需求与结论
假设你要在 Nginx 中只允许:
text
192.168.1.1 ~ 192.168.1.124
访问某个站点或目录。
Nginx 的 allow / deny 指令只支持:
- 单个 IP,例如
192.168.1.10 - CIDR 网段,例如
192.168.1.0/24
它不支持这种写法:
nginx
allow 192.168.1.1-192.168.1.124; # 错误
所以必须把 IP 范围拆成多个 CIDR 段,再按顺序配置。
二、精确覆盖 192.168.1.1 ~ 192.168.1.124
如果要求精确覆盖 .1 到 .124,可以这样拆:
nginx
server {
listen 80;
server_name example.com;
location / {
allow 192.168.1.1/32; # 1
allow 192.168.1.2/31; # 2-3
allow 192.168.1.4/30; # 4-7
allow 192.168.1.8/29; # 8-15
allow 192.168.1.16/28; # 16-31
allow 192.168.1.32/27; # 32-63
allow 192.168.1.64/27; # 64-95
allow 192.168.1.96/28; # 96-111
allow 192.168.1.112/29; # 112-119
allow 192.168.1.120/30; # 120-123
allow 192.168.1.124/32; # 124
deny all;
root /var/www/html;
index index.html;
}
}
注意:deny all; 必须放在最后。Nginx 按顺序匹配,命中第一条 allow 或 deny 就生效。
三、简化写法
如果 .0、.125、.126、.127 这些地址实际不会使用,可以简化为:
nginx
allow 192.168.1.0/25; # 覆盖 192.168.1.0 ~ 192.168.1.127
deny all;
这样写更简单,但范围会比 .1 ~ .124 略宽,会额外允许 .0 和 .125 ~ .127。
如果只是想允许整个 192.168.1.x 网段,则可以用 /24:
nginx
allow 192.168.1.0/24;
deny all;
四、/24 是多少?
/24 是 CIDR 表示法,表示子网掩码:
text
255.255.255.0
以 192.168.1.0/24 为例:
| 项目 | 值 |
|---|---|
| 子网掩码 | 255.255.255.0 |
| 网络前缀 | 24 位 |
| 主机位 | 8 位 |
| 总 IP 数 | 256 个 |
| IP 范围 | 192.168.1.0 ~ 192.168.1.255 |
| 传统可用主机 | 254 个,通常 .0 是网络地址,.255 是广播地址 |
在 Nginx 中:
nginx
allow 192.168.1.0/24;
deny all;
表示允许整个 192.168.1.0 ~ 192.168.1.255 访问。Nginx 层面会匹配这 256 个地址。
五、只限制某个路径
如果只想保护后台或管理目录:
nginx
location /admin/ {
allow 192.168.1.0/25;
deny all;
proxy_pass http://127.0.0.1:8080;
}
这样只有指定 IP 段能访问 /admin/,其他 IP 返回 403。
六、全局限制
也可以放在 http、server 或 location 块中:
nginx
http {
allow 192.168.1.0/25;
deny all;
}
一般建议放在 server 或 location 中,避免影响所有站点。
七、反向代理后如何拿到真实 IP
如果 Nginx 前面还有负载均衡、CDN 或反向代理,$remote_addr 拿到的可能是代理 IP,而不是客户端真实 IP。
这时需要配置真实 IP 模块:
nginx
set_real_ip_from 10.0.0.0/8; # 你信任的代理网段
real_ip_header X-Forwarded-For;
real_ip_recursive on;
配置后,allow / deny 才会按客户端真实 IP 生效。
八、常见坑
-
Nginx 不支持 IP 范围写法
192.168.1.1-192.168.1.124必须拆成 CIDR。 -
deny all;要放最后Nginx 按顺序匹配,放错位置会导致规则不符合预期。
-
403 Forbidden
通常是被
deny all;拦截,检查 CIDR 是否写错。 -
反向代理下 IP 不生效
检查是否配置了
set_real_ip_from、real_ip_header。 -
修改后验证并重载
bashnginx -t && nginx -s reload
九、CIDR 速查表
| CIDR | 可用地址数 | 子网掩码 |
|---|---|---|
| /24 | 256 | 255.255.255.0 |
| /25 | 128 | 255.255.255.128 |
| /26 | 64 | 255.255.255.192 |
| /27 | 32 | 255.255.255.224 |
| /28 | 16 | 255.255.255.240 |
| /29 | 8 | 255.255.255.248 |
| /30 | 4 | 255.255.255.252 |
| /31 | 2 | 255.255.255.254 |
| /32 | 1 | 255.255.255.255 |
十、总结
- Nginx 用
allow/deny做 IP 访问控制。 - 不支持
192.168.1.1-192.168.1.124,必须拆成 CIDR。 - 精确覆盖
.1 ~ .124可以用多个 CIDR 段。 - 如果允许整个
192.168.1.x,直接写192.168.1.0/24。 /24表示255.255.255.0,范围是192.168.1.0 ~ 192.168.1.255。- 前面有代理时,要配置真实 IP,否则
allow/deny可能失效。
参考:https://www.ecjson.com/article/206.html