Nginx secure_link模块给网站添加防盗链

网站上的一些静态资源文件,比如图片、pdf、压缩文件、m3u8等视频文件,经常会被盗链,之前我都是用referrer来防盗链,但是referrer太容易伪造了。后来nginx的secure_link可以很好的解决这个问题。

该模块有三个指令,分别为:secure_link、secure_link_md5、secure_link_secret,使用方法有两种:

  1. secure_link + secure_link_secret(v0.7.18以后);
  2. secure_link + secure_link_md5(v0.8.5以后,其实就是用来替代第一种的)。

后面的部署过程我们都是采用方法2。

secure_link + secure_link_md5基本原理

  1. 把一些参数以及过期时间按你想要的顺序拼成一个字符串,然后对它做md5计算,然后把这个md5和过期时间以参数的方式附加到链接后面。
  2. 在nginx中我们配置同样的参数串顺序,nginx会按我们给出的参数串计算出它的md5值,然后把它计算得到的md5值与链接中传过来的md5值作对比,如果两个值不相同,则会把变量$secure_link设置为空字符串。
  3. 如果md5值相同,nginx还会继续对比过期时间,如果链接已经过期(其实就是当前时间戳大于链接中传过来的时间戳),那么它会把$secure_link的值置为”0″,否则为”1″。
  4. 综上,我们只需要用if检测$secure_link的值,如果为空,则说明这个链接不是合法链接,如果不为空,则继续用if检测它的值是否为”0″,,只要为空或为0,那么我们就可以判断它不是合法请求,就可以用return 403或者rewrite的方式去处理这种不合法请求;

以下记录整个过程。

1、编译secure_link模块

我用的是宝塔,默认是没有编译secure_link,通过查看nginx -V确认下:

/www/server/nginx/sbin/nginx -V
cd /www/server/nginx/src/

在最后面添加–with-http_secure_link_module,编译:

./configure  --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --with-http_secure_link_module
make

备份nginx:

cp /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx.bak

停止nginx:

nginx -s stop

继续:

cp /www/server/nginx/src/objs/nginx /www/server/nginx/sbin/nginx

然后启动nginx

systemctl restart nginx

查看nginx -V是否成功编译secure_link模块:

/www/server/nginx/sbin/nginx -V

2、Nginx配置

location /yourpath/ {
    secure_link $arg_md5,$arg_expires; #这里配置了2个参数一个是arg_md5,一个是arg_expires
    secure_link_md5 "123456$uri$arg_expires"; #123456为自定义的加密串(这里的md5加密顺序要和程序生成的加密顺序保持一致)   

    if ($secure_link = "") {
        return 403; #资源不存在或哈希比对失败
    }

    if ($secure_link = "0") {
        return 410; #时间戳过期 
    }
}

3、配置网站PHP

<?php
$secret = '123456';

####下载文件,切记路径带上/
$path = "/file/168itw.zip";

####下载到期时间,time是当前时间,$validtime表示有效期,也就是说从现在到300秒之内文件不过期
$validtime = 300;
$expire = time() + $validtime;

####用文件路径、密钥、过期时间生成加密串(注意这里的md5加密顺序要和nginx配置文件中的顺序保持一致)
$md5 = base64_encode(md5($secret . $path . $expire, true));
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);

####加密后的下载地址
$uri = $path . '?md5=' . $md5 . '&expires=' . $expire;

####安全下载链接可以直接echo输出
$uri = "https://www.168itw.com" . $uri;
?>

输出上述文件链接:

<?php echo $uri; ?>

如果使用的是wordpress,需要在文章post中添加防盗链文件,可以安装Insert PHP Code Snippet插件,这样就可以在任意文章中任何位置插入PHP代码。

参考文章:https://www.xiebruce.top/1799.html