internal 指令用于限制 location 仅响应 nginx 内部跳转(如 error_page、rewrite last、try_files),拒绝外部直接访问并返回 404;它不参与防盗链校验,但可配合 error_page 或 secure_link 实现隐藏资源保护,需避免误用于主静态资源或错误语法位置。

internal 指令在 Nginx 中用于限制某个 location 只能被服务器内部请求访问(如 error_page、rewrite ... last、try_files 或 post_action 触发的跳转),外部客户端直接 GET/POST 访问会返回 404。它本身不参与防盗链逻辑,但可与防盗链配合,实现“隐藏式资源保护”——比如把防盗链拦截后的默认图、重定向跳转目标或鉴权后置资源设为 internal,防止这些辅助资源被绕过或滥用。
以下是实际可用的配置逻辑和关键要点:
internal 必须搭配明确的内部触发机制才生效
它不是独立开关,而是“守门员”:只放行由 Nginx 自身发起的内部跳转,拒绝所有原始 HTTP 请求。常见合法触发方式包括:
-
error_page 403 =200 /forbidden.png;→ 此时/forbidden.png若设为internal,仅该 error_page 跳转能访问,用户直连https://site.com/forbidden.png会 404 -
rewrite ^/img/(.*)$ /internal/$1 last;→ 后续location /internal/ { internal; ... }仅响应 rewrite 跳转,不响应浏览器直接访问 -
try_files $uri @fallback;+location @fallback { internal; ... }
防盗链场景中 internal 的典型用法
✅ 推荐:保护默认提示图,防二次盗用
当用 error_page 403 =200 /static/forbidden.png; 返回占位图时,应确保该图不被外部直接引用:
location = /static/forbidden.png {
internal;
alias /var/www/html/static/forbidden.png;
}
这样:
- 盗链请求
Referer: evil.com→ 触发error_page 403→ 内部跳转到/static/forbidden.png→ 成功返回图片 - 黑客尝试直连
https://yoursite.com/static/forbidden.png→ 返回 404,无法批量抓取或嵌入他站
✅ 可选:隔离鉴权后置资源(需配合 secure_link)
若使用 secure_link 做真防盗链,常将解密后重写到内部路径:
location /protected/ {
secure_link $arg_st,$arg_e;
secure_link_md5 "secret$uri$arg_e";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
# 成功后重写到内部 location
rewrite ^/protected/(.*)$ /internal/$1 break;
}
location /internal/ {
internal;
alias /data/protected/;
}
外部永远无法直接访问 /internal/xxx,只能通过带有效 token 的 /protected/xxx?st=...&e=... 进入。
⚠️ 注意事项:internal 不等于防盗链,也不能替代 referer 校验
- 它不检查
Referer、不验证来源、不加密链接——只是“路径访问控制” - 单独对图片 location 加
internal会导致所有正常访问失败(因为 HTML 页面加载<img>是外部请求) -
internal和valid_referers是互补关系:前者管“谁能进这个门”,后者管“谁有资格敲这扇门”
❌ 常见误用(导致服务异常)
- 在主静态资源 location 中加
internal:location ~* \.(jpg|png)$ { internal; # 错!用户浏览器请求图片就是外部请求,全部 404 valid_referers none blocked example.com; if ($invalid_referer) { return 403; } } - 把
internal放在if块里或server级:语法错误,Nginx 启动失败 - 用
rewrite ... redirect触发internallocation:redirect 是 302 跳转,属于外部新请求,internal不放行
不复杂但容易忽略











