企业级 PHP 高并发解决方案 0x01 Web资源防盗链

架构493 字

盗链是指通过技术手段获得他人服务器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。常见的是小站盗用大站的图片、音乐、视频、软件等资源。

通过盗链的方法可以减轻自己服务器的负担,因为真实的空间和流量均是来自别人的服务器。

防盗链的工作原理

在 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 .'">';
maksim
Maksim(一笑,吡罗),PHPer,Goper
OωO
开启隐私评论,您的评论仅作者和评论双方可见