防盗链的原理其实很简单,目前比较流行的做法就是通过Referer来进行判断和限制,Referer的解释说明如下:
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
简单来说,假如我博客域名是 a.com ,我在nginx中设置,只允许Referer为 *.a.com 的来源请求图片,其它网站来的一律禁止。这里我们需要用到ngx_http_referer_module 模块和 $invalid_referer 变量,请看下面进一步解释。
ngx_http_referer_module 模块用于阻止对“Referer”头字段中具有无效值的请求访问站点。应该记住,使用适当的“Referer”字段值来构造请求非常容易,因此本模块的预期目的不是要彻底阻止此类请求,而是阻止常规浏览器发送的请求的大量流量。还应该考虑到,即使对于有效请求,常规浏览器也可能不发送“Referer”字段。
语法:valid_referers none | blocked | server_names | string ...;
可用于:server,location
可以看到valid_referers指令中存在一些参数,比如none|blocked,含义如下:
我们设置 valid_referers 指令后,会将其结果传递给一个变量 $invalid_referer ,其值为0或1,可以使用这个指令来实现防盗链功能,如果 valid_referers 列表中没有包含Referer头的值,$invalid_referer将被设置为1。
白名单就是只允许白名单内的域名访问,其余一律禁止。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico|webp)$ {
valid_referers none blocked *.xiaoz.me *.xiaoz.top;
if ($invalid_referer) {
return 403;
}
}
上面的配置含义是先用 location 匹配出需要的格式(图片和视频),然后用valid_referers指令设置允许的域名,其它域名没有包含在 valid_referers 列表中,$invalid_referer 变量返回的值为1,最终返回403,禁止访问。
除了如上所示返回403外,还可以返回一张默认的图片,配置如下:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
valid_referers none blocked *.wangmaolin.net wangmaolin.net;
if ($invalid_referer) { # 注意这个地方写法,if后{前必须有空格,否则报错
rewrite ^/ https://cdn.jsdelivr.net/gh/shenkongbian/img1@main/images/2021/12/19/image-b1d771863db6a89e2898a67e82d19b91.png;
}
expires 30d;
}
要注意返回的图片不要出现在防盗链连接中
以上就是防盗链白名单的设置。
黑名单与白名单正好相反,就是只禁止黑名单中的域名请求,其余一律放行,相比白名单,黑名单的限制更加宽松。网上大部分教程只提到了防盗链白名单的设置,了解原理后黑名单的设置方法也差不多。
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,禁止百度的域名来访问。
以上就是Nginx防盗链(黑白名单)的设置,了解原理后其实非常简单,但由于Referer可以任意伪造,上述方法无法拦截伪造的Referer请求,不过大部分常见的场景还是有作用的。如果您服务器带宽和流量本身就比较小,建议加上防盗链设置。