Nginx http_secure_link_module 实现下载防盗链

 secure_link 模块


下载服务器上有众多的软件资源, 可是很多来源不是本站,是迅雷、 flashget, 源源不断的带宽,防盗链绝对是当务之急. 使用来源判断根本不靠谱,只能防止一些小白站点的盗链,迅雷之类的下载工具完全无效,如果你是nginx 的话,使用 secure link 完美解决这个问题,远离迅雷.本文仅用于下载服务器,不适用于图片防盗链。

该模块主要实现下面两个功能:

(1)指定并允许检查请求的链接的真实性以及保护资源免遭未经授权的访问
(2)限制链接生效周期

默认情况下 nginx 不会安装 secure_link 模块,需要手动指定,配置参数如下:
# ./configure --with-http_secure_link_module \
--prefix=/usr/local/nginx-1.4.2 --with-http_stub_status_module

 

secure link 指令


secure_link
语法: secure_link md5_hash[,expiration_time]
默认: none
配置段: location
variables: yes
这个指令由 uri 中的 MD5 哈希值和过期时间组成. md5 哈希必须由 base64 加密的,过期时间为 unix 时间.如果不加过期时间,那么这个连接永远都不会过期.


secure_link_md5
语法: secure_link_md5 secret_token_concatenated_with_protected_uri
默认: none
配置段: location
variables: yes
md5 值对比结果,使用上面提供的 uri、密钥、过期时间生成 md5 哈希值.如果它生成的 md5 哈希值与用户提交过来的哈希值一致,那么这个变量的值为 1,否则为 0


secure_link_secret
语法: secure_link_secret word
默认:
配置段: location
Reference: secure_link_secret
nginx 0.8.50 之后的版本已经使用 secure_link_md5 取代,不再多说.

 

验证原理


用户在客户端点击下载按钮,服务器收到请求后生成一个下载地址返回给客户端。客户端在用这个生成的下载地址去请求资源,此时nginx去做校验,校验链接地址真伪和链接地址是否过期。如果链接地址是真的并且链接地址没有过期,就给客户端返回下载资源。(nginx验证和服务器生成密钥规则要一致,否则不会通过的)


 

配置nginx


 server {
        listen       80;
        server_name  www.test.com;
        charset utf-8;
        root /usr/local/nginx/html/;

       location /{
       secure_link $arg_md5,$arg_expires; 
       #secure_link:取参数md5,expires的值
       
       secure_link_md5 "$secure_link_expires$uri test"; #test为自定义的加密串
       #secure_link_md5验证参数md5,expires是否和服务端生成验证的一致

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

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

    }

}

 

使用shell脚本生成下载的链接(生产环境由开发在代码中实现)


[root@www]# cat md5url.sh 
#!/bin/bash
#生成一个测试链接脚本
servername="192.168.179.99"  #服务器的IP或者域名
download_file="/nginx.png"  #测试下载文件的uri路径,该环境nginx.png放在/usr/local/nginx/html下面
time_num=$(date -d "+300 seconds" +%s)  #定义过期时间为300秒
secret_num="test"   #自定义的加密串,和nginx的配置文件中加密串相同

res=$(echo -n "${time_num}${download_file} ${secret_num}"|openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)  #生成MD5值
echo "http://${servername}${download_file}?md5=${res}&expires=${time_num}"  #打印下载链接


[root@www]# ./md5url.sh 
http://192.168.179.99/nginx.png?md5=rNISU5RF0H45cvo8Ym5dpA&expires=1588909599

 

模拟Tomcat等后端产生一个下载链接


使用Shell脚本生成,内容如下:

[root@www app]# ./md5url.sh   ----注意!!!每时每刻该shell脚本产生的expires值都在发生变化
http://192.168.179.99/nginx.png?md5=FsGJgGZ9gko7obkPZDEHRw&expires=1588911183
[root@www app]# ./md5url.sh 
http://192.168.179.99/nginx.png?md5=1fJiz1qHBM9m4kmf5y2Jnw&expires=1588911184
[root@www app]# ./md5url.sh 
http://192.168.179.99/nginx.png?md5=Sucvv1ddt8FOzwFskb5K8g&expires=1588911186

#此处是模拟后台生成的一个下载链接,这些操作其实都是在服务器后台执行的,只有后台才知道加密串"test"和过期时间(expires)等。


 

测试


复制该链接,浏览器可以进行下载,此处是模拟后台生成的一个下载链接,这些操作其实都是在服务器后台执行的,只有后台才知道加密串"test"和过期时间(expires)等。

[root@www app]# wget `bash md5url.sh`   --测试下载nginx.png图片
--2020-05-08 12:00:32--  http://192.168.179.99/nginx.png?md5=h7Mwc0S7sdglbuC8i5UsrQ&expires=1588910732
Connecting to 192.168.179.99:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 848 [image/png]
Saving to: ‘nginx.png?md5=h7Mwc0S7sdglbuC8i5UsrQ&expires=1588910732’

100%[===============================================================================================>] 848         --.-K/s   in 0s      

2020-05-08 12:00:32 (161 MB/s) - ‘nginx.png?md5=h7Mwc0S7sdglbuC8i5UsrQ&expires=1588910732’ saved [848/848]

[root@www app]# ls
md5url.sh  nginx.png?md5=h7Mwc0S7sdglbuC8i5UsrQ&expires=1588910732
[root@www sbin]# cmp /usr/local/nginx/html/nginx.png  /opt/app/nginx.png\?md5\=h7Mwc0S7sdglbuC8i5UsrQ\&expires\=1588910732  -l   
#可以看到下载的和源图片内容是一样的
[root@www app]#     #可以看到下载成功




[root@www app]# wget http://192.168.179.99/nginx.png?md5=Hry5OCxz-thoBxGr5vz5tA&expires=1588911074
[1] 83766
[root@www app]# --2020-05-08 12:06:25--  http://192.168.179.99/nginx.png?md5=Hry5OCxz-thoBxGr5vz5tA
Connecting to 192.168.179.99:80... connected.
HTTP request sent, awaiting response... 403 Forbidden  ##资源不存在或哈希比对失败,这里是哈希对比失败
2020-05-08 12:06:25 ERROR 403: Forbidden.


[1]+  Exit 8                  wget http://192.168.179.99/nginx.png?md5=Hry5OCxz-thoBxGr5vz5tA

将后面的时间戳随便改写如expires=1588911074,回车,发现网页变为403

 

注意事项


1 密钥防止泄露、以及经常更新密钥
2 下载服务器和链接生成的服务器上的时间不能相差太大,否则容易出现文件一直都是过期状态.
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值