Nginx的internal指令是路径隐身机制而非鉴权工具,需通过对外入口(如/download/)校验权限后,经auth_request、rewrite last或X-Accel-Redirect触发内部跳转至隐藏location(如/_private/),且alias路径必须严格对齐。

Nginx 的 internal 指令不是鉴权工具,而是“路径隐身机制”——它让某个 location 对外部请求彻底不可见,只响应 Nginx 自身发起的内部跳转。保护内部静态文件的关键,不在于加一行 internal,而在于构建“对外入口 + 对内透传”的两段式链路。
必须用两段 location 分离职责
不能把 internal 单独配在对外路径上,也不能让它和业务逻辑混在一起。正确结构是:
- 一个对外可见的入口(如
/download/),负责接收请求、校验权限、提取参数 - 一个对内隐藏的透传块(如
/_private/),只含internal和alias或root,不做任何判断
三种可靠触发方式,选一种即可
外部请求要抵达 internal location,必须经过以下任一内部流程:
-
auth_request /auth:由后端返回 2xx 后,Nginx 自动将主请求转入 internal 区域 -
rewrite ... last:入口 location 中重写 URL,并用last触发重新匹配,命中 internal 块 -
X-Accel-Redirect响应头:后端返回X-Accel-Redirect: /_private/file.pdf,Nginx 自动内部跳转并读取文件
alias 路径必须严格对齐
这是最常出错的地方:
- 若
location /_private/ { internal; alias /data/files/; },则请求/_private/report.pdf会映射到/data/files/report.pdf - 如果漏掉
location末尾的/,或alias末尾少/,路径拼接就会错位,可能读到错误文件甚至越界
禁止这些写法
- 把
internal放在server或http块里 → 不生效 - 在
internallocation 中配置proxy_pass到不可信服务 → 可能被绕过 - 用
rewrite ... redirect(302)代替last→ 浏览器重发请求,变成外部直连 - 对
internallocation 使用root时没考虑拼接逻辑 →/_private/a.pdf会去找/data/_private/a.pdf,而非预期位置
额外加固建议
-
/auth子请求 location 也必须加internal,防止攻击者跳过主入口直调鉴权接口 - 下载链接加入时间戳 + HMAC 签名,服务端校验时效与完整性
- 配合
limit_except限制 HTTP 方法,例如只允许GET和HEAD
不复杂但容易忽略。


















