Nginx中referer模块的静态资源防盗链配置教学

 更新时间:2026年07月13日 08:50:02   作者:知远漫谈  
本文将带你深入 Nginx 的 referer 模块,系统性地掌握防盗链技术的底层原理、实战配置、边界场景处理、Java 后端协同策略,以及如何构建一个安全、高效、可扩展的静态资源防护体系

在当今互联网高速发展的时代,静态资源(如图片、视频、CSS、JS 文件)已成为网站性能优化的核心组成部分。它们承载着视觉表达、交互体验和用户留存的关键任务。然而,随着内容分发网络的普及与资源复用的便捷性,一个令人头疼的问题悄然浮现——静态资源被盗链

你是否曾见过这样的场景?一个小型博客网站,服务器带宽每月仅 50GB,却因为一张热门图片被多个大型论坛、公众号、甚至电商平台直接嵌入,导致月流量飙升至 500GB,服务器崩溃,账单暴增。这并非科幻小说,而是无数中小站长的真实噩梦。而这一切的根源,正是HTTP Referer 头的滥用

本文将带你深入 Nginx 的 referer 模块,系统性地掌握防盗链技术的底层原理、实战配置、边界场景处理、Java 后端协同策略,以及如何构建一个安全、高效、可扩展的静态资源防护体系。我们将通过真实代码示例、可视化流程图、多维度测试方案,让你不仅“会配置”,更能“懂原理”、“能优化”、“可扩展”。

什么是盗链?为什么它如此致命?

盗链(Hotlinking),又称“外链引用”或“带宽窃取”,是指第三方网站在未经许可的情况下,直接引用你服务器上的静态资源(如图片、音频、视频)到自己的网页中。

盗链的典型表现

假设你有一个图片资源:https://your-website.com/images/logo.png

某论坛的管理员在帖子中直接写入:<img src="https://your-website.com/images/logo.png" alt="Logo">

当用户访问该论坛时,浏览器会向你的服务器发起请求,加载这张图片。你的服务器承担了:

  • 带宽消耗(每访问一次,你就要传输 10KB 图片)
  • CPU 资源(处理 HTTP 请求、读取磁盘、发送响应)
  • 存储 I/O(频繁读取文件)
  • 甚至可能被搜索引擎误判为“重复内容”影响 SEO

而论坛主呢?他零成本获得了高质量视觉内容,提升了页面美观度,还可能因此获得更多点击与广告收入。

盗链的危害

危害类型说明
成本飙升带宽费用呈指数级增长,尤其在云服务商(如阿里云、腾讯云)按量计费下,月支出可能从 50 元暴涨至 5000 元
性能下降你的服务器资源被大量盗链请求占用,导致合法用户访问变慢,甚至超时
SEO 受损搜索引擎可能认为你的内容被大量复制,降低权重
安全风险某些盗链者会伪装 Referer,结合 XSS 或 CSRF 攻击,利用你的资源作为跳板

Nginx Referer 模块:防盗链的基石

Nginx 本身不直接提供“防盗链”功能,但其强大的 ngx_http_referer_module 模块,允许我们基于 HTTP 请求头中的 Referer 字段进行灵活的访问控制。

什么是 Referer?

Referer 是 HTTP 请求头中的一个字段,用于标识当前请求是从哪个页面跳转而来的。例如:

  • 用户从 https://baidu.com 点击链接进入你的网站 → Referer: https://baidu.com
  • 用户直接在浏览器地址栏输入你的 URL → Referer: (empty)
  • 用户从微信公众号文章点击图片 → Referer: https://mp.weixin.qq.com

注意:Referer 字段不是强制的,浏览器可以不发送,或被用户代理(如隐私模式、插件)屏蔽。但它在绝大多数正常场景下是可靠的。

Nginx 防盗链核心指令

指令说明
valid_referers定义合法的 Referer 来源,支持域名、IP、空值等
invalid_referer可选,用于标记非法 Referer(配合 set 使用)
return / rewrite配合 valid_referers 实现拒绝、重定向、返回占位图等策略

工作原理图解(Mermaid)

这个流程图清晰展示了 Nginx 如何基于 Referer 做出决策。每一个判断点都是可配置的,灵活性极高。

防盗链实战配置:从基础到高阶

我们以一个典型电商网站为例,域名:shop.example.com,静态资源部署在 /static/ 路径下,包含图片、CSS、JS、字体等。

基础配置:仅允许本站访问

server {
    listen 80;
    server_name shop.example.com;

    location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
        valid_referers none blocked shop.example.com www.shop.example.com;
        
        if ($invalid_referer) {
            return 403;
        }

        root /var/www/html;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

配置详解:

valid_referers none blocked shop.example.com www.shop.example.com;

  • none:允许空 Referer(如用户直接访问图片链接)
  • blocked:允许 Referer 被防火墙或代理屏蔽(值为空或格式异常)
  • shop.example.comwww.shop.example.com:允许这两个域名引用资源

if ($invalid_referer)valid_referers 会自动设置 $invalid_referer 变量,若 Referer 不合法,则值为 1

return 403;:直接拒绝访问,返回 HTTP 403 Forbidden

重要提示valid_referers 不支持通配符(如 *.example.com),如需泛域名支持,需使用正则表达式(见下文)。

高阶配置:支持泛域名 + 第三方合作站

假设你的品牌授权了 3 家合作伙伴网站:

  • partner1.com
  • partner2.net
  • mall.example.org

你希望允许这些站点引用你的图片,但拒绝其他所有来源。

location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
    valid_referers none blocked server_names
                   *.partner1.com
                   *.partner2.net
                   mall.example.org;

    if ($invalid_referer) {
        return 403;
    }

    root /var/www/html;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

解析:

  • server_names:允许当前 server_name 中的所有域名(即 shop.example.comwww.shop.example.com
  • *.partner1.com:支持子域名泛匹配(如 a.partner1.com, b.partner1.com
  • 不支持*.comexample.* —— Nginx 不支持通配符在域名中间或结尾

如果你需要更复杂的匹配(如多个顶级域名),请使用正则表达式。

正则表达式:灵活匹配多域名

假设你希望允许:

  • partner1.com
  • partner2.com
  • cdn.partner3.org
  • 任何以 mybrand- 开头的子域名(如 mybrand-shop.com
location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
    valid_referers none blocked server_names
                   ~^https?://(www\.)?(partner1|partner2)\.com(/.*)?$
                   ~^https?://cdn\.partner3\.org(/.*)?$
                   ~^https?://mybrand-[^/]+\.com(/.*)?$;

    if ($invalid_referer) {
        return 403;
    }

    root /var/www/html;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

正则说明:

表达式说明
^https?://匹配 http:// 或 https://
(www\.)?可选的 www 子域名
`(partner1partner2).com`
(/.*)?可选路径(避免因路径不同导致匹配失败)
cdn\.partner3\.org精确匹配,注意转义点
mybrand-[^/]+\.com匹配 mybrand- 开头 + 任意非斜杠字符 + .com

正则表达式是 Nginx 防盗链的终极武器,但需注意性能开销。建议仅在必要时使用。

替代方案:返回占位图 vs 重定向 vs 444 关闭连接

方案一:返回 403 Forbidden(最严格)

if ($invalid_referer) {
    return 403;
}
  • 优点:明确拒绝,符合 HTTP 标准
  •  缺点:盗链者可能看到“403”,反而知道你做了防护,可能升级攻击

方案二:返回占位图(推荐!)

location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
    valid_referers none blocked server_names
                   ~^https?://(www\.)?(partner1|partner2)\.com(/.*)?$;

    if ($invalid_referer) {
        rewrite ^/(.*)$ /static/hotlink-blocked.png last;
    }

    root /var/www/html;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

需提前准备一张占位图:/var/www/html/static/hotlink-blocked.png

优势

  • 对普通用户友好:看到的是“被禁止引用”的提示图
  • 对盗链者形成心理威慑:他们无法“偷”你的图,只能看到尴尬的提示
  • 可嵌入品牌信息:“本图由 shop.example.com 提供,未经授权禁止引用”

方案三:重定向到首页(温和策略)

if ($invalid_referer) {
    return 302 https://shop.example.com;
}
  • 适合希望“教育”盗链者,引导其合法合作的场景
  • 但可能被搜索引擎收录为“重定向链”,影响 SEO

方案四:返回 444(最隐蔽)

if ($invalid_referer) {
    return 444;
}
  • 444 是 Nginx 特有状态码,表示“无响应”,直接关闭 TCP 连接
  • 盗链者完全无法感知,请求被静默丢弃
  • 适用于高安全等级、无用户交互的 API 服务

注意:444 会导致浏览器控制台报错 “ERR_EMPTY_RESPONSE”,调试时需谨慎。

防盗链测试:如何验证你的配置是否生效?

方法一:使用 curl 模拟盗链请求

# 正常访问(无 Referer)
curl -I https://shop.example.com/images/logo.png

# 模拟来自百度的盗链
curl -H "Referer: https://www.baidu.com" -I https://shop.example.com/images/logo.png

# 模拟来自自家网站
curl -H "Referer: https://shop.example.com/page.html" -I https://shop.example.com/images/logo.png

观察响应头:

  • 若返回 HTTP/2 403 → 防盗链生效 
  • 若返回 HTTP/2 200 → 配置失败

方法二:使用 Postman / Thunder Client(VSCode 插件)

  1. 创建 GET 请求:https://shop.example.com/images/logo.png
  2. 在 Headers 中添加:
    • Key: Referer,Value: https://evil-site.com
  3. 发送请求,观察状态码

方法三:浏览器开发者工具

  1. 打开 Chrome DevTools → Network
  2. 刷新页面,找到一张图片请求
  3. 右键 → “Copy as cURL”
  4. 在终端中执行,观察响应

方法四:构造 HTML 测试页(本地)

创建一个本地 HTML 文件 test.html

<!DOCTYPE html>
<html>
<head>
    <title>盗链测试页</title>
</head>
<body>
    <h1>测试是否被防盗链</h1>
    <img src="https://shop.example.com/images/logo.png" alt="测试图" width="300">
</body>
</html>

用浏览器打开此文件,观察图片是否加载成功。

建议:将此测试页部署在你的测试域名(如 test.yourdomain.com)上,模拟真实盗链场景。

Java 后端协同:动态生成 Referer 白名单

虽然 Nginx 防盗链强大,但静态配置无法应对动态合作方变更。比如:

  • 你接入了 100 个小程序、10 个 H5 平台,每天新增 2~3 个合作方
  • 每次修改 Nginx 配置 → 重启服务 → 业务中断

解决方案:Java + Redis + Nginx 动态白名单

我们采用以下架构:

[Java 服务] ←→ [Redis] ←→ [Nginx]
    ↑              ↑
  动态配置       Nginx 读取白名单

Step 1:Java 服务管理白名单(Spring Boot 示例)

@RestController
@RequestMapping("/api/referer")
public class RefererWhitelistController {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    // 添加合法域名
    @PostMapping("/add")
    public ResponseEntity<String> addReferer(@RequestBody String domain) {
        if (domain == null || domain.trim().isEmpty()) {
            return ResponseEntity.badRequest().body("域名不能为空");
        }
        // 去除协议头和路径,只保留域名
        String cleanDomain = domain.replaceAll("^(https?://)?(www\\.)?", "").split("/")[0];
        redisTemplate.opsForSet().add("referer_whitelist", cleanDomain);
        return ResponseEntity.ok("已添加: " + cleanDomain);
    }
    // 获取所有白名单
    @GetMapping("/list")
    public ResponseEntity<List<String>> getWhitelist() {
        Set<String> domains = redisTemplate.opsForSet().members("referer_whitelist");
        return ResponseEntity.ok(new ArrayList<>(domains));
    }
    // 删除域名
    @DeleteMapping("/remove")
    public ResponseEntity<String> removeReferer(@RequestBody String domain) {
        String cleanDomain = domain.replaceAll("^(https?://)?(www\\.)?", "").split("/")[0];
        Long removed = redisTemplate.opsForSet().remove("referer_whitelist", cleanDomain);
        if (removed > 0) {
            return ResponseEntity.ok("已移除: " + cleanDomain);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

Step 2:Nginx 读取 Redis 白名单(需安装 ngx_http_lua_module)

此方案需要 Nginx 编译时启用 lua 模块(如 OpenResty),非标准 Nginx 默认支持。

# nginx.conf

http {
    lua_package_path "/usr/local/openresty/lualib/?.lua;;";

    init_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeouts(1000, 1000, 1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.log(ngx.ERR, "failed to connect to redis: ", err)
        end
        -- 预加载白名单
        local whitelist, err = red:smembers("referer_whitelist")
        if whitelist then
            ngx.var.referer_whitelist = table.concat(whitelist, " ")
        end
    }

    server {
        listen 80;
        server_name shop.example.com;

        location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
            # 动态从 Lua 变量读取白名单
            set $valid_referers_list "none blocked server_names $referer_whitelist";
            
            # 由于 Nginx 不支持变量在 valid_referers 中,需使用更高级的 lua 实现
            access_by_lua_block {
                local referer = ngx.var.http_referer
                local whitelist = ngx.var.referer_whitelist

                if not referer then
                    return  -- 允许空 Referer
                end

                -- 解析域名
                local domain = string.match(referer, "^[^/]+//([^/]+)")
                if not domain then
                    ngx.exit(403)
                end

                -- 检查是否在白名单中
                local found = false
                for d in string.gmatch(whitelist, "[^%s]+") do
                    if domain == d or string.match(domain, "^%." .. d .. "$") then
                        found = true
                        break
                    end
                end

                if not found then
                    ngx.log(ngx.WARN, "Blocked hotlink from: ", domain)
                    ngx.exit(403)
                end
            }

            root /var/www/html;
            expires 30d;
            add_header Cache-Control "public, immutable";
        }
    }
}
  • 优势:无需重启 Nginx,Java 服务更新 Redis,Nginx 实时生效
  • 缺点:依赖 OpenResty,运维复杂度上升

适用场景对比表

方案适用场景是否需重启 Nginx维护成本推荐指数
静态配置合作方固定(<5 个)⭐⭐⭐⭐
正则表达式多域名、子域名⭐⭐⭐⭐
占位图 + 静态通用网站、电商⭐⭐⭐⭐⭐
Redis + Lua动态合作、SaaS 平台⭐⭐⭐⭐

防盗链 + CDN 混合部署:最佳实践

大多数企业都会使用 CDN(如阿里云 CDN、Cloudflare)加速静态资源。但 CDN 会改变 Referer 的来源!

错误做法

valid_referers shop.example.com;  # 仅允许本站

当你把图片托管在 CDN(如 https://cdn.shop.example.com)时,用户从 shop.example.com 访问,请求的 Referer 是 shop.example.com,但CDN 回源时的 Referer 是 CDN 的域名

结果:CDN 回源失败 → 图片无法加载!

正确做法:CDN 防盗链 + 源站双重防护

方案:源站只允许 CDN 回源,CDN 层做用户访问控制

用户 → CDN → (回源) → Nginx 源站

Nginx 源站配置(仅允许 CDN IP):

# 限制仅允许 CDN 回源访问
location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
    # 仅允许阿里云 CDN IP 段(示例)
    allow 101.226.0.0/16;
    allow 101.227.0.0/16;
    deny all;

    # 不检查 Referer,因为回源是 CDN 发起的
    root /var/www/html;
    expires 30d;
}

CDN 防盗链配置(以阿里云 CDN 为例):

  • 登录控制台 → CDN → 选择域名 → 防盗链
  • 选择“黑白名单模式”
  • 白名单填:https://shop.example.com/*
  • 启用“忽略查询参数”(避免 ?v=123 被拦截)
  • 启用“Referer 空值允许”

这样,只有从你官网跳转的请求才能通过 CDN 加载图片,而 CDN 回源不受限制。

实际 CDN 防盗链配置示例(阿里云)

项目配置值
防盗链类型白名单
白名单内容https://shop.example.com/*
是否允许空 Referer✅ 是
是否忽略查询参数✅ 是
是否开启 Referer 优先级✅ 是

重要:CDN 防盗链规则比 Nginx 更高效,因为它在边缘节点就拦截,节省了回源带宽!

特殊场景处理:微信、抖音、App 内嵌浏览器

微信公众号、抖音、快手、微博等 App 内嵌浏览器,默认不发送 Referer,或发送 https://mp.weixin.qq.com

问题:你的防盗链配置阻止了微信公众号中的图片显示!

valid_referers shop.example.com www.shop.example.com;

微信公众号访问你的图片 → Referer: https://mp.weixin.qq.com → 被拦截 → 图片空白!

解决方案:

location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg)$ {
    valid_referers none blocked
                   shop.example.com www.shop.example.com
                   mp.weixin.qq.com
                   douyin.com
                   kuaishou.com
                   weibo.com;

    if ($invalid_referer) {
        return 403;
    }

    root /var/www/html;
    expires 30d;
    add_header Cache-Control "public, immutable";
}

微信公众号的 Referer 是 https://mp.weixin.qq.com,不是 mp.weixin.qq.com,请确保包含协议头!

更安全的做法:使用正则匹配微信域名

valid_referers none blocked server_names
               ~^https?://(www\.)?(shop\.example\.com|mp\.weixin\.qq\.com|douyin\.com|kuaishou\.com|weibo\.com)(/|$);

小贴士:如何获取真实 Referer?

在微信公众号文章中插入一张图片,然后:

  1. 手机微信 → 长按图片 → “在浏览器中打开”
  2. 打开开发者工具 → Network → 查看图片请求的 Referer
  3. 将其加入白名单

防盗链的边界与陷阱

陷阱一:误封搜索引擎爬虫

百度、Google 爬虫抓取你的图片用于图片搜索,它们的 Referer 是空的或伪装的。

valid_referers none blocked server_names;

正确做法:允许空 Referer (none),这是搜索引擎的默认行为。

陷阱二:移动端 App 无 Referer

许多原生 App(如 iOS/Android)使用 URLConnectionOkHttp 请求图片,默认不带 Referer

解决方案:

  • 为 App 设置自定义 Header(如 X-App-Version),后端校验
  • 或者:对 App 资源单独部署路径,如 /app-images/,不启用防盗链
location ~* ^/app-images/ {
    # 不做防盗链,由 App 通过 Token 鉴权
    root /var/www/html;
    expires 30d;
}

location ~* \.(jpg|jpeg|png|gif|webp)$ {
    # 仅对网站图片启用防盗链
    valid_referers none blocked server_names;
    if ($invalid_referer) { return 403; }
    root /var/www/html;
    expires 30d;
}

陷阱三:HTTPS 跨域 Referer 丢失

当你的网站是 https://shop.example.com,而引用者是 http://blog.com(HTTP),浏览器出于安全策略,不会发送 Referer

解决方案:

  • 所有合作方必须使用 HTTPS
  • 使用 Referrer-Policy 控制 Referer 发送策略(在 HTML <head> 中):
<meta name="referrer" content="strict-origin-when-cross-origin">

推荐策略:strict-origin-when-cross-origin,在跨域时只发送协议+域名,不暴露路径

性能与安全权衡:防盗链的代价

性能影响分析

配置方式CPU 开销内存开销响应延迟
静态域名极低0ms
正则表达式1~5ms
Lua + Redis5~20ms
CDN 防盗链极低0ms(边缘节点)

推荐组合CDN 防盗链(主) + Nginx 静态白名单(辅) + 占位图兜底

安全性对比

方案抗伪造能力抗绕过能力推荐度
静态域名⭐⭐⭐
正则表达式⭐⭐⭐⭐
Lua + Redis极高⭐⭐⭐⭐⭐
444 关闭极高极高⭐⭐⭐⭐

防盗链不是万能的:恶意用户可通过代理、伪造 Referer(如使用 curl -H "Referer: shop.example.com")、使用爬虫工具(如 Puppeteer)绕过。
真正的安全应是:防盗链 + Token 鉴权 + IP 限速 + 日志监控

监控与日志:如何发现盗链行为?

Nginx 日志增强

修改 nginx.conflog_format

log_format hotlink '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                   '$invalid_referer';

access_log /var/log/nginx/access.log hotlink;

日志分析脚本(Python)

import re
from collections import Counter
with open('/var/log/nginx/access.log') as f:
    lines = f.readlines()
hotlink_count = Counter()
for line in lines:
    if '"-" ' in line or ' 403 ' in line:
        match = re.search(r'(\S+) - - \[.*\] "GET .*" 403 (\d+) "([^"]+)"', line)
        if match:
            referer = match.group(3)
            if referer != '-' and not referer.startswith('https://shop.example.com'):
                hotlink_count[referer] += 1
print("Top 10盗链来源:")
for ref, count in hotlink_count.most_common(10):
    print(f"{count:4d} 次 | {ref}")

输出示例:

Top 10盗链来源:
  2845 次 | https://evil-site.com
  1987 次 | https://forum.example.org
   892 次 | https://t.me
   345 次 | https://twitter.com

每周运行一次,发现异常来源,及时加入黑名单!

防盗链之外:更高级的资源保护方案

方案一:Token 鉴权(适用于敏感资源)

location ~* ^/private/ {
    # 生成临时 token,有效期 5 分钟
    set $token $arg_token;
    if ($token = "") {
        return 403;
    }
    # 校验 token 是否合法(可结合 Lua + Redis)
    access_by_lua_file /etc/nginx/check_token.lua;
    root /var/www/html;
}

Java 生成 Token:

@GetMapping("/image/{id}/token")
public ResponseEntity<String> generateImageToken(@PathVariable String id) {
    String token = UUID.randomUUID().toString().replace("-", "");
    redisTemplate.opsForValue().set("token:" + token, id, Duration.ofMinutes(5));
    return ResponseEntity.ok("https://shop.example.com/private/" + id + "?token=" + token);
}

方案二:签名 URL(类似阿里云 OSS)

https://shop.example.com/images/photo.jpg?Expires=1728000000&Signature=abc123&OSSAccessKeyId=key123

Java 签名逻辑(伪代码):

String sign = HMACSHA256(secretKey, "GET&/images/photo.jpg&Expires=1728000000");

Nginx 验证签名(需 Lua):

-- 检查 Expires 是否过期
-- 检查 Signature 是否匹配
-- 检查 OSSAccessKeyId 是否合法

方案三:WebP + 自适应格式 + 懒加载

  • 将 JPG 转为 WebP(体积减少 30%~50%)
  • 使用 <picture> 标签,浏览器自动选择格式
  • 图片懒加载,减少初始请求数
<picture>
  <source srcset="/images/photo.webp" type="image/webp">
  <source srcset="/images/photo.jpg" type="image/jpeg">
  <img src="/images/photo.jpg" alt="Photo" loading="lazy">
</picture>

既能提升体验,又能减少盗链价值(盗链者拿到的是 WebP,兼容性差)

最佳实践总结

  • HTTPS 站点必须要求合作方也使用 HTTPS,否则 Referer 会被浏览器屏蔽
  • 优先使用 CDN 防盗链,Nginx 仅做兜底
  • 白名单必须包含 noneblocked,避免搜索引擎和 App 无法访问
  • 微信、抖音、微博等平台 Referer 必须显式加入白名单
  • 避免使用正则表达式,除非必须;静态域名性能更高
  • 使用占位图而非 403,提升用户体验
  • 对 App 资源使用独立路径,不启用防盗链
  • 日志监控 + 每周分析盗链来源,动态更新白名单
  • 禁止使用 valid_referers 匹配 *.com,Nginx 不支持
  • 防盗链 ≠ 安全,敏感资源需结合 Token、签名、限速

最终推荐配置模板(开箱即用)

server {
    listen 80;
    server_name shop.example.com;

    # 静态资源防盗链配置
    location ~* \.(jpg|jpeg|png|gif|webp|ico|bmp|svg|css|js|woff|woff2|ttf|eot)$ {
        valid_referers none blocked server_names
                       shop.example.com www.shop.example.com
                       mp.weixin.qq.com douyin.com kuaishou.com weibo.com;

        if ($invalid_referer) {
            rewrite ^/ /static/hotlink-blocked.png last;
        }

        root /var/www/html;
        expires 365d;
        add_header Cache-Control "public, immutable";
        add_header Vary Accept-Encoding;
    }

    # 占位图单独放行(避免循环重定向)
    location = /static/hotlink-blocked.png {
        root /var/www/html;
        expires 7d;
        add_header Content-Type image/png;
    }

    # 其他静态资源
    location / {
        root /var/www/html;
        try_files $uri $uri/ =404;
    }
}
  • hotlink-blocked.png 放入 /var/www/html/static/,并确保其权限可读
  • 重启 Nginx:sudo nginx -t && sudo nginx -s reload

附录:防盗链配置自查清单

检查项是否完成
已允许空 Referer (none)☑️
已允许被屏蔽 Referer (blocked)☑️
已包含自有域名☑️
已包含微信、抖音等平台域名☑️
已测试本地 HTML 引用☑️
已测试 curl 模拟盗链☑️
已配置占位图而非 403☑️
已启用缓存头 expiresCache-Control☑️
已排除 App 资源路径☑️
已部署日志监控脚本☑️

到此这篇关于Nginx中referer模块的静态资源防盗链配置教学的文章就介绍到这了,更多相关Nginx referer静态资源防盗链内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文带你快速上手Nginx中启动、停止、重启的常用命令

    一文带你快速上手Nginx中启动、停止、重启的常用命令

    本文将带你从零开始,系统掌握 Nginx 的核心操作命令——启动、停止、重启、重载配置,并深入理解其背后的运行机制,感兴趣的小伙伴可以跟随小编一起学习一下
    2026-07-07
  • Nginx 负载均衡算法及故障转移解析

    Nginx 负载均衡算法及故障转移解析

    这篇文章主要介绍了Nginx 负载均衡算法及故障转移解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 详解CentOS配置Nginx官方的Yum源

    详解CentOS配置Nginx官方的Yum源

    这篇文章主要介绍了详解CentOS配置Nginx官方的Yum源,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤

    Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤

    本文主要介绍了Nginx搭建支持WebDAV协议的私有云存储网关的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-04-04
  • 如何使用Nginx解决跨域问题详解

    如何使用Nginx解决跨域问题详解

    本地运行一个项目,但是要访问外域的api接口,存在跨域问题,下面这篇文章主要给大家介绍了关于如何使用Nginx解决跨域问题的相关资料,文中介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • 详细聊聊K8s容器内nginx带变量的域名解析

    详细聊聊K8s容器内nginx带变量的域名解析

    这篇文章主要给大家介绍了关于K8s容器内nginx带变量域名的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-01-01
  • ELK收集Nginx日志的项目实战

    ELK收集Nginx日志的项目实战

    本文主要介绍了ELK收集Nginx日志的项目实战,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Nginx出现403 Forbidden问题的常见原因与解决

    Nginx出现403 Forbidden问题的常见原因与解决

    Nginx 返回 403 Forbidden 错误通常表示客户端没有权限访问请求的资源,这种错误有许多可能的原因,本文将为大家介绍一下常见的原因和对应的解决方法,希望对大家有所帮助
    2025-03-03
  • Nginx中使用gzip_http_version解决CDN只支持http 1.0问题

    Nginx中使用gzip_http_version解决CDN只支持http 1.0问题

    这篇文章主要介绍了Nginx中使用gzip_http_version解决CDN只支持http 1.0问题,问题原因是在Header信息中看到Transfer-Encoding: chunked,使用本文方法就可以解决这个问题,需要的朋友可以参考下
    2014-09-09
  • Nginx正反向代理及负载均衡等功能实现配置代码实例

    Nginx正反向代理及负载均衡等功能实现配置代码实例

    这篇文章主要介绍了Nginx正反向代理及负载均衡等功能实现配置代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11

最新评论