网站上的一些静态资源文件,比如图片、pdf、压缩文件、m3u8等视频文件,经常会被盗链,之前我都是用referrer来防盗链,但是referrer太容易伪造了。后来nginx的secure_link可以很好的解决这个问题。
该模块有三个指令,分别为:secure_link、secure_link_md5、secure_link_secret,使用方法有两种:
- secure_link + secure_link_secret(v0.7.18以后);
- secure_link + secure_link_md5(v0.8.5以后,其实就是用来替代第一种的)。
后面的部署过程我们都是采用方法2。
secure_link + secure_link_md5基本原理
- 把一些参数以及过期时间按你想要的顺序拼成一个字符串,然后对它做md5计算,然后把这个md5和过期时间以参数的方式附加到链接后面。
- 在nginx中我们配置同样的参数串顺序,nginx会按我们给出的参数串计算出它的md5值,然后把它计算得到的md5值与链接中传过来的md5值作对比,如果两个值不相同,则会把变量$secure_link设置为空字符串。
- 如果md5值相同,nginx还会继续对比过期时间,如果链接已经过期(其实就是当前时间戳大于链接中传过来的时间戳),那么它会把$secure_link的值置为”0″,否则为”1″。
- 综上,我们只需要用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