internal指令不鉴权,仅允许Nginx内部跳转访问;必须与对外入口location配合使用,通过auth_request、rewrite last或X-Accel-Redirect三种方式衔接,且internal location须用alias(注意末尾斜杠)或root,禁放server/http块。

internal 指令本身不鉴权、不校验身份,它的作用是让某个 location 只响应 Nginx 自身发起的内部跳转(如 rewrite last、auth_request 子请求、X-Accel-Redirect 响应头),对所有客户端直连请求一律返回 404。它不是“加个 internal 就安全了”,而是作为一道语义级闸门,确保真实资源路径永不暴露在公网地址栏中。
必须采用两段式结构:对外入口 + 对内透传
真正起作用的配置永远由两个分离的 location 组成:
- 一个对外可见的入口 location(如
/download/或/secure-file/),负责接收用户请求,并执行鉴权、参数校验、签名验证等逻辑 - 一个对内隐藏的透传 location(如
/_protected/),仅含internal;和alias(推荐)或root,不做任何业务判断,只专注读取文件 - 二者之间必须通过 Nginx 内部机制衔接——不能用 302 跳转,也不能靠外部 curl 或浏览器直接访问 internal location
三种可靠衔接方式及适用场景
external 请求要抵达 internal location,必须经过以下任一内部流程:
-
auth_request + 子请求鉴权:最推荐。外层 location 配置
auth_request /auth,由后端服务返回 2xx 才允许继续;/auth本身也要加internal,防止被绕过直调 -
rewrite last + 简单校验:适合轻量场景。例如在入口 location 中用
if提取时间戳和 HMAC 签名,校验通过后rewrite ^/dl/(.+)$ /_protected/$1 last; -
X-Accel-Redirect 响应头驱动:后端动态决定资源路径。例如 PHP/Python 返回
X-Accel-Redirect: /_protected/user123/report.pdf,Nginx 自动内部跳转并读取对应文件
关键配置细节与常见踩坑点
很多配置看似正确却失效,问题往往出在细节上:
-
alias路径末尾斜杠必须与 location 末尾一致:若写location /_protected/ { internal; alias /data/files/; },则请求/_protected/a.pdf会映射到/data/files/a.pdf;若漏掉斜杠,路径拼接将出错 - 不要在 internal location 中配置
proxy_pass到不可信后端;它应直接读磁盘,或只代理到可信的内部静态服务 - 用
root时路径是拼接关系:root /data;+ 请求/_protected/x.pdf→ 实际读/data/_protected/x.pdf;alias是前缀替换,更可控 - 禁止把
internal放在 server 或 http 块里,必须置于具名location块内;也不可与rewrite ... redirect混用,否则跳转会跳出 Nginx 内部流程
配合后端实现完整闭环
internal 是纯 Nginx 层防护,需后端协同才能形成可用链路:
- 若用 X-Accel-Redirect,后端需校验用户权限、生成合法路径,并设置响应头:
header("X-Accel-Redirect: /_protected/xxx.pdf"); - 若用 auth_request,后端鉴权接口必须返回标准 HTTP 状态码(200 表示通过,401/403 拦截),且该接口 location 本身也要加
internal - 建议对下载链接增加时效性(如
expires=1715817600)和签名(HMAC-SHA256),由后端统一校验,避免客户端伪造参数










