运维日志您现在的位置是:首页 > 博客日志 > 运维日志

nginx 实现图片防盗链功能

<a href='mailto:'>微wx笑</a>的头像微wx笑 2022-09-15运维日志 2 0关键字: nginx  防盗链  

在搜索浏览网页的时候,发现一篇文章是从我的个人网站转载的,但是没有注明出处,文章中的图片也没有本地化处理,还是从我的服务器请求,这就无形中增加了我的服务器的开销,于是有了设置防盗链功能这一想法。

在搜索浏览网页的时候,发现一篇文章是从我的个人网站转载的,但是没有注明出处,文章中的图片也没有本地化处理,还是从我的服务器请求,这就无形中增加了我的服务器的开销,于是有了设置防盗链功能这一想法。dBU无知

想干就干,开工!dBU无知

防盗链原理

防盗链的原理其实很简单,目前比较流行的做法就是通过Referer来进行判断和限制。
dBU无知


dBU无知

什么是 Referer

Referer 首部包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 首部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。dBU无知

通俗来说,假如我通过 Google 搜索去搜索referer,然后搜索引擎给出了一堆链接,这个时候,我点击链接,那么 http 头就会带上 referer 字段信息,并且值就是 Google 搜索的 url 地址https://www.google.com;因此,假设从 A 网址到 B 网址,那么这个 referer 字段就告诉 B网址该请求是从 A 网址发起的。dBU无知

这里我们需要用到ngx_http_referer_module模块和$invalid_referer变量,请看下面进一步解释。
dBU无知

ngx_http_referer_module模块

ngx_http_referer_module模块用于阻止对“Referer”头字段中具有无效值的请求访问站点。应该记住,使用适当的“Referer”字段值来构造请求非常容易,因此本模块的预期目的不是要彻底阻止此类请求,而是阻止常规浏览器发送的请求的大量流量。还应该考虑到,即使对于有效请求,常规浏览器也可能不发送“Referer”字段。dBU无知

语法:valid_referers none | blocked | server_names | string ...;
可用于:server,location
可以看到valid_referers指令中存在一些参数,比如none|blocked,含义如下:dBU无知

none:请求标头中缺少“Referer”字段,也就是说Referer为空,浏览器直接访问的时候Referer一般为空。
blocked: Referer”字段出现在请求标头中,但其值已被防火墙或代理服务器删除; 这些值是不以“http://” 或 “https://” 开头的字符串;
server_names: 服务器名称,也就是域名列表。
$invalid_referer变量
我们设置valid_referers 指令后,会将其结果传递给一个变量$invalid_referer,其值为0或1,可以使用这个指令来实现防盗链功能,如果valid_referers列表中没有包含Referer头的值,$invalid_referer将被设置为1。dBU无知

设置防盗链白名单
白名单就是只允许白名单内的域名访问,其余一律禁止。

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|webp)$ {
    valid_referers none blocked *.devler.cn;
    if ($invalid_referer) {
        return 403;
    }
}

上面的配置含义是先用location匹配出需要的格式(图片和视频),然后用valid_referers指令设置允许的域名,其它域名没有包含在valid_referers列表中,$invalid_referer变量返回的值为1,最终返回403,禁止访问。以上就是防盗链白名单的设置。dBU无知


dBU无知

防盗链黑名单

黑名单与白名单正好相反,就是只禁止黑名单中的域名请求,其余一律放行,相比白名单,黑名单的限制更加宽松。网上大部分教程只提到了防盗链白名单的设置,了解原理后黑名单的设置方法也差不多。dBU无知

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|webp)$ {
    valid_referers *.baidu.com;
    if ($invalid_referer = 0) {
        return 403;
    }
}

上面的配置中我们用valid_referers指令设置黑名单域名*.baidu.com,获取到指定的Referer头之后,$invalid_referer返回值为0,最终返回403,禁止百度的域名来访问。dBU无知


dBU无知

我的具体做法

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico|avif|webp|mp4)$
    {
        valid_referers none blocked *.ivu4e.com ivu4e.com;
        set $flag "0";
	if ($invalid_referer) {
          #return 403;
          set $flag "1";
        }
        if ($request_uri = "/403img.png") {
          set $flag "0";
        }
        if ($flag = "1") {
          #return 403;
          return 302 https://ivu4e.com/403img.png;
        }
        expires      30d;
        error_log off;
        access_log off;
    }

对所有的图片视频设置白名单功能,dBU无知

但是,不在白名单中的话,我不会返回403,dBU无知

而是返回302,然后转向到一张指定的图片;dBU无知

效果:

image.pngdBU无知


dBU无知

本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/service/2022-09-15/1380.html

很赞哦! () 有话说 ()