nginx中在location块内用allow/deny实现白名单,必须先写多条allow放行指定ip或网段,再以deny all;兜底拒绝其余所有请求;该规则仅在location块中生效,且顺序不可颠倒。

用 allow 和 deny 在 location 块里实现最小权限白名单,核心就一条:只放行明确列出的 IP,其余一律拒绝。关键不在多写规则,而在顺序精准、兜底可靠。
白名单必须写在 location 块内
不能放在 http 或 server 顶层块里——那里的 allow/deny 不生效。必须嵌入具体处理请求的位置,比如:
-
location /admin/ { ... }控制后台路径 -
location ~ \.php$ { ... }控制 PHP 脚本执行 -
location /api/v1/ { ... }控制特定 API 接口
顺序决定权限边界
规则从上到下逐条匹配,命中即停止。所以白名单逻辑必须是“先允许多个合法来源,最后统一拒绝其他所有”:
- 每条
allow写一行,支持单 IP(allow 192.168.5.10;)、IPv4 网段(allow 10.0.0.0/8;)、IPv6 地址或前缀(allow 2001:db8::/32;) - 允许多个来源?直接追加多行
allow即可 -
deny all;必须放在所有allow之后,且是该location中最后一条访问控制指令 - 漏掉
deny all;,未匹配的请求会默认放行,白名单就形同虚设
示例:严格限制管理接口
以下配置只允许公司内网和本地调试访问,其他全部拦截:
location /admin/ {
allow 172.16.0.0/12;
allow 127.0.0.1;
deny all;
}
注意:deny all; 后面不能再跟其他指令(如 return 403; 可选,但非必需;Nginx 默认返回 403,显式写上更清晰)。
提升可维护性的实用建议
硬编码 IP 容易出错、难同步。生产环境推荐两种方式:
-
用 include 外部文件:把白名单规则单独存为
/etc/nginx/conf.d/admin-whitelist.conf,内容为:allow 172.16.0.0/12; allow 192.168.100.0/24; deny all;
然后在location中引用:include /etc/nginx/conf.d/admin-whitelist.conf; -
用 geo + map 动态标记:适合多环境切换(如测试/生产 IP 段不同)。先在
http块定义:geo $allowed { default 0; 192.168.5.0/24 1; 10.0.0.0/8 1; }再用map转换,最后在location中判断:if ($allowed = 0) { return 403; }











