internal 的作用是创建仅限 Nginx 内部跳转的单向访问通道,不参与鉴权,只响应 rewrite last、auth_request、X-Accel-Redirect 或 error_page 触发的内部请求;外部直接访问返回 404。

用 internal 指令构建安全的静态资源分发通道,核心不是“隐藏路径”,而是切断外部直连能力——它让某个 location 成为只对 Nginx 自身内部流转开放的“单向闸门”。只要配置得当,用户哪怕知道真实文件名和完整 URL,直接访问也会返回 404;只有经过鉴权逻辑确认后、由 Nginx 主动发起的内部跳转,才能穿透这道门。
明确 internal 的作用边界
internal 不做鉴权,只做通行许可。它不检查 token、不验证签名、不读 cookie,唯一判断依据是:这个请求是不是由 rewrite last、auth_request 子请求、X-Accel-Redirect 响应头或 error_page 触发的内部流转。浏览器地址栏敲 /_protected/report.pdf?404。后端 PHP 返回 X-Accel-Redirect: /_protected/report.pdf?Nginx 立即查磁盘并流式响应。
常见误区:
- 把
internal单独配在 proxy_pass location 里 → 必然 404,因为没有前置子请求或重定向触发机制 - 在 public location 里写
rewrite ^/dl$ /_protected/file.pdf last,但/_protected没加internal→ 外部仍可拼出 /_protected/file.pdf 直接下载 - alias 路径末尾多写一个斜杠(如
alias /data/;)→ 可能导致路径拼接错误,引发目录穿越风险
推荐组合:auth_request + internal + X-Accel-Redirect
这是生产环境最可控、扩展性最强的模式,前后端职责清晰:
- 前端或客户端请求
/api/download?file=2024q2.pdf - Nginx 先发子请求到
/auth,由后端服务校验权限、时效、用户归属等 - 后端校验通过后,响应头中带上
X-Accel-Redirect: /_protected/2024q2.pdf - Nginx 收到该 header,自动内部跳转至
location ^~ /_protected/,该块必须含internal; alias /var/www/protected/;
关键点:
-
/authlocation 必须也加internal,防止攻击者绕过主入口直打鉴权接口 -
/_protected/的 alias 后不带斜杠(alias /var/www/protected;),否则/_protected/a.pdf会映射成/var/www/protecteda.pdf - 后端响应体可为空,但必须返回 2xx 状态码,且 header 中
X-Accel-Redirect值需以/_protected/开头
补充加固措施不能少
仅靠 internal 是必要但不充分条件。实际部署中需叠加以下防护:
- 对下载链接加入 HMAC 签名,防止 token 被篡改;时间戳必须服务端校验,禁用客户端传入的 expires
- 用
limit_req限制单 IP 单位时间请求数,避免有效链接被暴力刷取 - 启用
real_ip模块并正确设置set_real_ip_from,确保 CDN 场景下限流与日志基于真实客户端 IP - 在 internal location 中添加安全响应头:
add_header X-Content-Type-Options nosniff;、add_header Content-Disposition "attachment; filename=$1";(配合正则捕获文件名)
替代方案:rewrite last + internal(适合轻量场景)
若暂无后端鉴权服务,可用 Nginx 原生能力做简单校验:
- 在公开 location 中用
if提取并验证 query 参数(如$arg_token和$arg_expires) - 校验通过后,用
rewrite ^/download$ /_protected/2024q2.pdf last;跳转 - 目标
/_protected/location 含internal; alias /data/;
注意:Nginx 的 if 性能低、易出错,仅建议用于测试或参数极简的场景;复杂签名、数据库查询等必须交由后端完成。

















