假设建立了一个小的站点,是一个新站,里面没有内容,也没有什么相关的好看的图片,也没有视频,也没有mp3,也没有等等一些吸引人的静态资源文件。这时候看到别人的一些大站的一些资源相当的不错,此时就出现一个念头,把它直接链接过来,链接到网站中来,就可以了,这种行为就叫做盗链行为。当然有一部分人认为,盗链并不会对原服务器(即所盗链的那个服务器)产生影响,但是在这儿我们要说明一下,盗链本身不是一种很道德的行为,因为它会影响对方的服务器。
即不通过别人的页面来展示别人的资源,而是通过我们自己的页面来展示别人的资源,直接在自己的页面上向最终用户提供内容。这样对用户来说,他并不知道这个资源是谁的,他就认为理所当然就应该是你的,实际上,是从别人那 Copy 来的,这就叫做盗链。
如:我们建立一个图片的网站,我们看到百度里面有些图片是比较漂亮的,比较好的,我们可以把它拿过来,直接把那个链接复制过来即可;还有一种情况是,我们看到别人的站点里有一个mp3的音乐不错,我们可以把它放到我们的站点中来,当然也是通过链接的方式,包括视频,包括软件下载,都可以这样去做。
如:我们在盗用别人的站点的时候,很多人去盗用它的站点,突然有一天他觉得我的流量用完了,而且我的PV也不差,这个时候他会认为我的整体站是不是比较好,大家是不是都比较喜欢,但其实一看自己的访问量还是很差,在这儿其实是被别人盗链了。其实对于我们来说也是,如果有一天我们发现我们的流量慢慢地在消失,但是我们PV统计,IP统计很少,这个时候我们就应该去考虑是不是被别人防盗链了。
注:虽然能减轻自己服务器的负担,但是增加了别人服务器的负担,因此这是一种不道德的行为。
将别人网站的链接地址拿过来用。新建一个 demo.php,写入如下代码:
<img src="https://www.imooc.com/static/img/index/logo.png">
运行效果:
Referer
或者 签名
,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址;referer:判断 referer 是否与原网站的 referer 一致,不一致则禁止访问;
签名:通过签名的方式去防止,即在访问我们的资源的时候,在网址后面带一个参数,这个参数是我们彼此约定好的签名,这个签名的计算方式是我们彼此约定好的,我们把签名带上,服务器在显示该签名的时候,去判断该签名是否正确,相当于配了一把钥匙去开锁,如果没有问题,就显示图片。签名通常情况下设置要相当对复杂一点,不能让别人轻易猜到。如果我们设置了签名,当我们去访问该图片的时候,不知道签名的方式,此时就没有办法去请求该图片。
ngx_http_referer_module
用于阻挡来源非法的域名请求;valid_referers
,全局变量 $invalid_referer
;
valid_referes
none | blocked | server_names | string … 的用法如下:
none
:“Referer” 来源头部为空的情况;blocked
:“Referer” 来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以 http:// 或者 https:// 开头;
server_names
:“Referer” 来源头部包含当前的 server_names;
valid_referers none // 代表 referer 为空时也合法【有 none】
valid_referers // 代表 referer 为空不合法【没有 none】
valid_referers blocked // 通过代理或者防火墙对 referer 进行了删除
valid_referers server_names // 信任地址(如:imooc.com; *.imooc.com等)
打开配置
/usr/local/nginx/conf/nginx.conf
// 防盗链的实现方法
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
valid_referers none blocked imooc.com *.imooc.com;
if ($invalid_referer) {
# return 403;
rewrite ^/http://www.imooc.com/403.jpg;
}
}
// 防盗链的实现方法
location /images/
{
valid_referers none blocked imooc.com *.imooc.com;
if ($invalid_referer)
{
# return 403;
rewrite ^/http://www.imooc.com/403.jpg;
}
}
传统防盗链遇到的问题:通过伪造Referer来实现盗链,可以使用加密签名解决该问题。
HttpAccessKeyModule
实现 Nginx防盗链;
accesskey
on|off 模块开关;accesskey_hashmethod md5
|sha-1
签名加密方式;accesskey_arg
GET参数名称;accesskey_signature
加密规则(在PHP与Nginx中签名的加密规则要一致,这样才能通过,从而进行访问,否则无法进行访问);
// 防盗链的实现方法
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$
{
accesskey on;
accesskey_hashmethod md5;
accesskey_arg "key";
accesskey_signature "mypass$remote_addr"; // $remote_addr 客户端IP
}
对于整个签名来说,代表 我们去拿一个字符串去拼接客户端IP,通过 md5 加密得到签名,在PHP端也要这么做,去生成一个签名,去请求图片的时候,nginx 就会去判断签名,将签名进行 md5 加密,然后判断两个值是否一致,如果一致,显示图片;否则显示 403。
例子:
① 配置 /usr/local/nginx/conf/nginx.conf
;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
accesskey on;
accesskey_hashmethod md5;
accesskey_arg sign;
accesskey_signature "jason$remote_addr"; // 表示 "jason"字符串 + 客户端IP 通过md5加密得到签名
}
② 新建 demo2.php
// 客户端IP 进行md5 加密
$sign = mg5('jason', $_SERVER['REMOTE_ADDR']);
echo '
.$sign.'">'; // 该图片是本地存在的图片
注:该方法防盗链的效果是十分有效的,但是每次访问的时候,都要拼接一个 sign
,比较繁琐。因此,以上两种方法,各有利弊。