使用python结合nginx下的secure_link实现防盗链

背景 公司最近开发的项目涉及到相关文件服务器资源的权限问题,为了处理防盗链,研究了 一下如何利用nginx来进行防盗链处理;
目前了解到利用nginx实现防盗链有三种方式:
1:利用referer指令实现防盗链配置;(一般只适用与图片的防盗链处理,,因为referer信息可以伪造,不能达到完全防盗链的目的)
2:利用nginx-accesskey防盗链模块
3:还有一种就是今天实践尝试的:secure_link防盗链模块,nginx 自带的模块
环境 使用nginx配置一个静态页面web服务,在一个测试用的页面下然后利用反向代理,代理指定的访问的路径转发都其他python web服务(使用bottle运行的另一个web服务U)
相关的配置:

1:静态页面的web配置web.conf
server { listen 80; server_name 192.168.74.128; root /data/app/html/; location / { indexIndex.html index.html; #proxy_pass http://192.168.182.155:8089; }location ~* ^/(upload)/{proxy_redirect off; proxy_set_header Host$host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://192.168.74.128:8089; #alias /data/app/html2/static/$1; //文件可以放到别的目录 #error_page 404 =200 @backend; // 如果访问出现404转发到后台服务器} }

1:静态页面的index.html
protect - 锐客网protect使用python结合nginx下的secure_link实现防盗链
文章图片
image.png 其他示例:配合来路IP
Example:location /s/ { secure_link $arg_md5,$arg_expires; secure_link_md5 "$secure_link_expires$uri$remote_addr secret"; if ($secure_link = "") { return 403; }if ($secure_link = "0") { return 410; }... } The “/s/link?md5=_e4Nc3iduzkWRm01TBBNYw&expires=2147483647” link restricts access to “/s/link” for the client with the IP address 127.0.0.1. The link also has the limited lifetime until January 19, 2038 (GMT).On UNIX, the md5 request argument value can be obtained as:echo -n '2147483647/s/link127.0.0.1 secret' | \ openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

PS:上面的secure_link定义了控制权限的两个参数(分别是st, e)
其中e就是上述的过期时间,建议e = 当前时间 + 有效期限(5分钟)
3:然后使用python代码生成对应的 secure_link_md5信息,用于在nginx进行相关鉴权处理
生成相关URL地址示例:
#!/usr/bin/evn python # coding=utf-8 # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + + #┏┓┏┓+ + #┏┛┻━━━┛┻┓ + + #┃┃ #┃━┃ ++ + + + #████━████ ┃+ #┃┃ + #┃┻┃ #┃┃ + + #┗━┓┏━┛ #┃┃ #┃┃ + + + + #┃┃Codes are far away from bugs with the animal protecting #┃┃ +神兽保佑,代码无bug #┃┃ #┃┃+ #┃┗━━━┓ + + #┃┣┓ #┃┏┛ #┗┓┓┏━┳┓┏┛ + + + + #┃┫┫ ┃┫┫ #┗┻┛ ┗┻┛+ + + + # + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +""" """ Author = zyx @Create_Time: 2018/2/1 13:21 @version: v1.0.0 @Contact: 308711822@qq.com @File: creat.py @文件功能描述: """ import base64 import hashlib import timedef md5(text, isBackByte=False): """md5加密函数""" md5 = hashlib.md5() if isinstance(text, bytes): md5.update(text) else: md5.update(text.encode('utf-8'))if isBackByte: # 返回二进制的加密结果 return md5.digest()# 返回十六进制的机密结果 return md5.hexdigest()def base64_encode(text, isBytes=False): """进行base64编码处理""" if isBytes: return base64.b64encode(text) return base64.b64encode(bytes(text, encoding="utf-8"))def get_timestamp10(): """获取当前时间长度为10位长度的时间戳""" return int(time.time())secret = 'xiaozhong.com'; # 密钥--对应#st的哈希格式为 secret+url+e,e为时间戳单位s,url为请求地址secure_link_md5 xiaozhong.com$uri$arg_e; path = '/upload/1.mp4'# 下载文件 # 下载到期时间,time是当前时间,300表示300秒,也就是说从现在到300秒之内文件不过期 expire = get_timestamp10() + 5; res = md5(str(secret) + str(path) + str(expire), True) print(res) md5 = str(base64_encode(res, True)) print(md5) print('expire', get_timestamp10()) print('md5', md5) md5 = md5.replace('b\'', '').replace('\'', '').replace('+', '-').replace('/', '_').replace('=', '')print('生成代相关认证签名的地址:','http://192.168.74.128/upload/1.mp4?' + 'st=' + str(md5) + '&e=' + str(expire))

4:测试访问对应的地址:
生成代相关认证签名的地址:
http://192.168.74.128/upload/1.mp4?st=x-N1ZsycbvlHvvDQNXMDLQ&e=1517758167
测试1:去除后面的参数,返回会返回403:
测试2:超时了时间戳有效期之后再访问具体,返回410
还可以添加其他的参数进行校验:
比如来源IP,UA信息等
注意事项PS: 部分的请求,如果直接不经过nginx访问的时候,可以直接进行处理,一个解决的方案就是设置防火墙,在linux中防火墙限制其端口,只能使用nginx进行访问,不能直接访问tomcat
加在自启动中
vim /etc/init.d/rc.local
设置如下
iptables -A INPUT -s 127.0.0.1 -p tcp -m tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 8080 -j DROP
–A 参数就看成是添加一条规则
–p 指定是什么协议,我们常用的tcp 协议,当然也有udp,例如53端口的DNS
–dport 就是目标端口,当数据从外部进入服务器为目标端口
–sport 数据从服务器出去,则为数据源端口使用
【使用python结合nginx下的secure_link实现防盗链】–j 就是指定是 ACCEPT -接收 或者 DROP 不接收

    推荐阅读