安全暴露nginx状态页需启用stub_status模块并严格白名单限制:先确认模块存在,再在location中开启stub_status、关闭access_log,按顺序配置allow(含127.0.0.1和::1)与deny all;https需在对应server块重复配置;代理场景需用set_real_ip_from还原真实ip;大规模环境推荐geo模块统一管理白名单。

要安全暴露 Nginx 的状态监控页面(如 /nginx_status 或 /status),不能只开个接口就完事——必须同时启用状态模块并严格限制访问来源,否则服务器运行指标会直接暴露给任何人。
确认 stub_status 模块已启用
Nginx 需内置 `ngx_http_stub_status_module` 才能提供状态数据。多数官方发行版默认包含,验证方式: ```bash nginx -V 2>&1 | grep -o with-http_stub_status_module ``` 若无输出,需重新编译安装。确认可用后,在 `location` 块中启用: - `stub_status on;` —— 开启状态页 - `access_log off;` —— 关闭日志,避免监控请求污染日志路径可自定义,例如:
location /nginx_status {
stub_status on;
access_log off;
}
白名单配置:顺序和兜底缺一不可
Nginx 按指令从上到下匹配,遇到第一条匹配规则即终止。因此: - 必须先写 `allow` 规则(支持 IPv4、IPv6、CIDR,如 `allow 192.168.10.50;` 或 `allow 2001:db8::/32;`) - 必须显式允许本地回环:`allow 127.0.0.1;` 和 `allow ::1;` - 最后必须加 `deny all;` —— 没有它,未匹配的 IP 默认放行典型配置示例:
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
allow 192.168.10.50;
allow 10.0.100.0/24;
deny all;
}
HTTPS 场景下别漏配 server 块
HTTP 和 HTTPS 的 `server` 块完全独立。如果站点监听 443 端口,上述 `location` 必须**在对应的 HTTPS server 块内重复声明**,否则 HTTPS 请求会绕过白名单直通状态页。若前端有 CDN 或反向代理(如 Nginx Ingress、Cloudflare),$remote_addr 会变成代理 IP。此时需还原真实客户端 IP:
- 在
http或server块顶部添加:set_real_ip_from 192.168.0.0/16; set_real_ip_from 10.0.0.0/8; real_ip_header X-Forwarded-For;
再基于
$realip_remote_addr做 allow/deny 判断。
大规模或动态环境建议用 geo 模块管理
当白名单 IP 较多、需频繁更新,或跨多个 `server` 复用时,推荐用 `geo` 模块统一维护: ```nginx geo $is_trusted { default 0; 192.168.1.0/24 1; 10.10.10.10 1; 203.0.113.5 1; } ``` 然后在 `location` 中: ```nginx location /nginx_status { stub_status on; access_log off; if ($is_trusted = 0) { return 403; } } ``` 这种方式更易读、易维护,也便于后续对接自动化工具或配置中心。不复杂但容易忽略











