盗链是指通过技术手段获得他人服务器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。常见的是小站盗用大站的图片、音乐、视频、软件等资源。
通过盗链的方法可以减轻自己服务器的负担,因为真实的空间和流量均是来自别人的服务器。
防盗链的工作原理
在 http 协议中,我们的每一次请求在 header 中都会包含 Referer
字段,用来表示这个请求的来源,我们就可以通过这个字段来做一个白名单,只有 Referer
来源在我的白名单列表中才允许请求访问资源,如果不允许,我们可以拒绝请求,甚至是返回一张我们自定义的图片来告诉用户,这个图片在哪台服务器上。
Nginx防盗链的实现
Nginx Referer
Nginx 模块 ngx_http_referer_module 用于阻挡来源非法的域名请求。
Nginx 指令 valid_referers,全局变量$invalid_referer。
valid_referers none | blocked | server_names| string ...;
none: "Referer" 来源头部为空的情况
blocked: "Referer"来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都以 http://或者 https://开头。
server_names: "Referer" 来源头不包含当前的 server_names
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$ {
valid_referers none blocked maksim.website *.maksim.website;
if ($invalid_referer)
{
#return 403;
rewrite ^/http://www.maksim.website/403.jpg;
}
}
针对目录
location /images/ {
valid_referers none blocked maksim.website *.maksim.website;
if ($invalid_referer)
{
#return 403;
rewrite ^/http://www.maksim.website/403.jpg;
}
}
但是这种方法存在一个问题,那就是 Referer
是可以伪造的,只要对方在每一次请求的时候设置 Referer
那么就可以完全绕考这个限制,直接访问我们的资源。
Nginx HTTPAccessKeyModule 加密签名
请求图片的时候带签名过去,当返回图片的时候判断签名是否正确,也就是暗号。
加密签名的时候需要使用第三方模块HttpAccessKeyModule,因为在服务端php里需要显示图片的时候跟一个签名,交给Nginx的时候,Nginx需要做一个判断,判断前面是否正确,Nginx在判断的时候就需要这个模块了。
accesskey on | off
accesskey_hashmethod md5 | sha-1
accesskey_arg GET参数名称
accesskey_signatrue 加密规则
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
accesskey on
accesskey_hashmethod md5
accesskey_arg "key"
accesskey_signatrue "maksim$remote_addr"
}
<?php
//md5(maksim.ip)
$sign = md5('maksim'.$_SERVER['REMOTE_ADDR']);
echo '<img src="./image/maksim.png?sign='. $sign .'">';