internal 修饰符强制 location 仅响应 nginx 内部跳转,外部直接请求一律返回 404;必须置于非正则、具名的 location 块中,且仅通过 rewrite last、auth_request 或 x-accel-redirect 触发。

在 Nginx 中,internal 修饰符的作用是**强制切断客户端直连能力**:它让某个 location 只响应 Nginx 自身发起的内部跳转,任何浏览器、curl 或 Postman 的直接请求都会立即返回 404 Not Found。这不是隐藏路径,而是基于请求来源做硬隔离——只认“Nginx 内部工牌”,不验 Token、不看 Cookie、也不管 IP。
必须放在具名且非正则的 location 块中
internal 不是全局指令,不能写在 http 或 server 块顶层,也不能放在正则匹配或泛匹配块里。它只支持明确前缀的静态匹配方式:
- ✅ 正确:
location ^~ /_internal/ { internal; proxy_pass http://backend; } - ✅ 正确:
location = /auth { internal; proxy_pass http://auth-svc; } - ❌ 错误:
location ~ ^/_internal/ { internal; }(正则 location 不支持internal) - ❌ 错误:
location / { internal; }(整个根路径变 404,语义错误) - ❌ 错误:
internal;单独一行(语法报错,配置无法加载)
只有三类内部行为能触发访问
加了 internal 的 location 不会自动生效,必须通过 Nginx 原生内部机制跳转进来。外部请求哪怕带完整鉴权头,也会被直接拦截:
-
rewrite ... last;:例如rewrite ^/api/(.*)$ /_internal/$1 last;,注意必须是last,不是redirect(302 会跳出 Nginx 流程) -
auth_request成功后的隐式子请求:主请求经鉴权子服务返回 2xx 后,Nginx 自动以内部方式进入目标location -
X-Accel-Redirect响应头驱动:后端返回头如X-Accel-Redirect: /_internal/report.pdf,Nginx 自动内部跳转读取
必须配合外层入口才真正可用
单独加 internal 不等于安全,它只是守门员,不负责验身份。真实防护靠“两段式”结构:
- 外层普通
location(如/api/):做鉴权(auth_request)、限速、日志、参数校验 - 内层
internallocation(如/_internal/):只做转发或文件服务,不处理业务逻辑 - 两者之间用
rewrite last或auth_request衔接,绝不走 302、proxy_pass 直连或手动 curl
防绕过关键细节
攻击者常绕过主入口,直接打你的鉴权地址或资源路径。因此:
- 所有关键路径都要加
internal:包括鉴权子请求location = /auth、资源代理location ^~ /_files/ - 避免暴露重复路径:禁止同时存在
/_internal/(带 internal)和另一个/public-api/(proxy_pass 到同一后端),否则形同虚设 - proxy_pass URI 末尾斜杠要与 location 一致:若写
location /_proxy/,则proxy_pass http://svc/必须带尾部斜杠,否则可能重复拼接路径 - alias 提供静态文件时,
location和alias路径末尾斜杠需统一,否则文件路径错位











