Nginx防盗链配置

1. 什么是盗链?

盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。

盗链在如今的互联网世界无处不在,盗图,盗视频、盗文章等等,都是通过获取正规网站的图片、视频、文章等的 url 地址,直接放到自己网站上使用而未经授权。 盗资源是黑产界以最小成本获取最高利益的一个常用手段。比如笔者最近考虑买房,在贝壳网上有房源的真是户型图以及VR。某些房产中介直接会盗用贝壳网上的真实户型图来骗取点击。因此,对于任何一个大型网站而言,做好防盗措施,避免自身利益受损是至关重要的。Nginx 在代理这类静态资源(图片、视频、文章等)时,可以通过配置实现防盗连的功能。

2. 如何防盗链?

盗链是直接使用正规网站保存图片、视频等的 URL 以获取相应的资源。最简单的防盗想法就是根据客户端请求资源时所携带的一些关键信息来验证请求的合法性,比如客户端 IP、请求 URL 中携带的 referer,如果不合法则直接拒绝请求。此外,由于这些基础信息都可以伪造,因此这样的基础手段也不一定安全。此外,还有登录认证、使用 cookie 等其他防盗连手段。另外,针对特定场景,比如流媒体直播中还有更为高级的防盗手段包括时间戳防盗链、swf 防盗链、回源鉴权防盗链等。

3. Nginx中防盗链配置

3.1 refer模块防盗

Nginx 用于实现防盗链功能的模块为 refer 模块,其依据的原理是: 如果网站盗用了你的图片,那么用户在点击或者查看这个盗链内容时,发送 http 请求的头部中的 referer 字段将为该盗版网站的 url。这样我们通过获取这个头部信息,知道 http 发起请求的页面,然后判断这个地址是否是我们的合法页面,不是则判断为盗链。Nginx 的 referer 模块中有3个指令,用法分别如下:

Syntax:	referer_hash_bucket_size size;
Default: referer_hash_bucket_size 64;
Context: server, locationSyntax:	referer_hash_max_size size;
Default: referer_hash_max_size 2048;
Context: server, locationSyntax:	valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location

最重要的是 valid_referers 指令,它后面可以带上多个参数,表示多个 referer 头都是有效的。它的参数形式有:

n

one: 允许缺失 referer 头部的请求访问
blocked: 有 referer 这个字段,但是其值被防火墙或者是代理给删除了
server_names: 若 referer 中的站点域名和 server_names 中的某个域名匹配,则允许访问
任意字符或者正则表达式

Nginx 会通过查看 referer 字段和 valid_referers 后面的 referer 列表进行匹配,如果匹配到了就将内置的变量$invalid_referer值设置为0,否则设置该值为1

Nginx 防盗链配置如下:

...location / {valid_referers none blocked *.domain.pub www.domain.com/nginx server_names ~\.baidu\.;if ($invalid_referer) {return 403;}return 200 "valid\n";}...

3.2 secure_link模块防盗

referer 头部值的防盗链方法过于脆弱,盗用者很容易通过伪造 referer 的值轻而易举跳过防盗措施。在 Nginx 中有一种更为高级的防盗方式,即基于 secure_link 模块,该模块能够检查请求链接的权限以及是否过期,多用于下载服务器防盗链。这个模块默认未编译进 Nginx,需要在源码编译时候使用 --with-secure_link_module 添加。

该模块的通过验证 URL 中的哈希值的方式防盗链。它的防盗过程如下:

由服务器或者 Nginx 生成安全的加密后的 URL, 返回给客户端;
客户端使用安全的 URL 访问 Nginx,获取图片等资源,由 Nginx 的 secure_link 变量判断是否验证通过;

secure_link 模块中总共有3个指令,其格式和说明分别如下:

Syntax:	secure_link expression;
Default: —
Context: http, server, locationSyntax:	secure_link_md5 expression;
Default: —
Context: http, server, locationSyntax:	secure_link_secret word;
Default: —
Context: location

通过配置 secure_link, secure_link_md5 指令,可实现对链接进行权限以及过期检查判断的功能。

和 referer 模块中的 $invalid_referer 变量一样,secure_link 模块也是通过内置变量 KaTeX parse error: Expected ‘EOF’, got ‘判’ at position 14: secure_link 判̲断验证是否通过。secure_link 的值有如下三种情况:

空字符串: 验证不通过
0: URL 过期
1: 验证通过

通常使用这个模块进行 URL 校验,我们需要考虑的是如何生成合法的 URL ?另外,需要在 Nginx 中做怎样的配置才可以校验这个 URL?

生成合法的 URL 和 指令 secure_link_md5 有关。例如:

secure_link_md5 "$secure_link_expires$uri$remote_addr secret";

如果 Nginx 中secure_link_md5 是上述配置,那么生成合法 url 的命令如下:

# 2020-02-05 21:00:00 转换成时间戳为1580907600
echo -n '1580907600/test.png127.0.0.1 secret' | \openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =

通过上述命令,我们得到了一个 md5 值:cPnjBG9bAZvY_jbPOj13mA,这个非常重要。接下来,构造合的 URL 和指令 secure_link 相关。如果 secure_link 指令的配置如下:

secure_link $arg_md5,$arg_expires;

那么我们的请求的 url 中必须带上 md5 和 expires 参数,例如:

http://180.76.152.113:9008/test.png?md5=cPnjBG9bAZvY_jbPOj13mA&expires=1580907600

对于 Nginx 中的校验配置示例如下:

location ~* .(gif|jpg|png|swf|flv|mp4)$  {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 "URL过期,请重新生成";}root /root/test;
}

在 Nginx 的配置中,除了前面提到的 secure_link 和 secure_link_md5 指令外,我们对通过校验和校验失败的情况进行了处理。接下来请看实验部分。

4. 案例实战

4.1 refer 模块防盗链测试

在 nginx.conf 中加入如下防盗配置:

...http {...server {listen 9008;location / {valid_referers none blocked *.domain.pub www.domain.com/nginx server_names ~\.baidu\.;if ($invalid_referer) {return 403;}return 200 "valid\n";}}...
}...

重新加载或者启动 Nginx 后,我们进行如下操作:

[shen@shen Desktop]$ curl -H 'referer: http://www.domain.com/test' http://180.76.152.113:9008 
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.6</center>
</body>
</html>
[shen@shen Desktop]$ curl -H 'referer: http://www.domain.com/nginx' http://180.76.152.113:9008 
valid
[shen@shen Desktop]$ curl -H 'referer: ' http://180.76.152.113:9008 
valid
[shen@shen Desktop]$ curl http://180.76.152.113:9008 
valid
[shen@shen Desktop]$ curl -H 'referer: http://www.domain.pub/test' http://180.76.152.113:9008 
valid

http 请求 referer 的值存在,但是没有匹配后面的域名,所以返回403。其余的请求中 referer 值要么不存在,要么没有这个头部,要么匹配了后面的域名正则表达,都通过了 referer 校验,所以都返回 “valid” 字符串。我们通过构造不同的 referer 头部字段成功的绕过了 Nginx 的referer 模块校验,也说明了这种防盗的方式极不靠谱。

4.2 secure_link 防盗链测试

准备一个静态图片, 名为 test.png,放到搭建了 Nginx 的服务器上,全路径为 /root/test/test.png。
准备 Nginx 配置如下:

...http {...server {listen  8000;location / {# return 200 "$remote_addr";root /root/test;}}server {listen 8001;location ~* .(jpg|png|flv|mp4)$  {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;}# 校验通过,访问对的静态资源root /root/test;}}}...

首先,在浏览器上访问8000端口我们可以获取对应的 $remote_addr 变量值(打开 return 的注释配置),结果为103.46.244.69, 这是客户端请求时的对外 IP。访问浏览器上访问8000端口,URI=/test.png, 可以看到这个静态图片。
在这里插入图片描述

接下来,我们在访问8001端口,URI=/test.png时,可以发现返回403页面,说明安全模块生效。

在这里插入图片描述

当前时间为2020年02月05日晚上9点半,我们找一个过期时间晚上10点,得到相应的时间戳为1580911200。按照 secure_link_md5 指令格式,使用如下 shell 命令生成 md5 值:

[shen@shen Desktop]$ echo -n '1580911200/test.png103.46.244.69 secret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
KnJx3J6fN_0Qc1W5TqEVXw

这样可以得到我们的安全访问 URL 为:

# 访问静态资源test.png的安全URL为:
http://180.76.152.113:8001/test.png?md5=KnJx3J6fN_0Qc1W5TqEVXw&expires=1580911200

再次到浏览器上访问时候,我就可以看到静态图片了。
在这里插入图片描述

测试过期后的结果。在过期之后再用这个 URL 访问时无法查看图片,而且返回的是 410 的状态码,这说明 Nginx 成功检测到这个密钥值已经过期。

5. 小结

防盗链的知识,然后开始介绍 Nginx 中的防盗链配置。一般的 Nginx 防盗链手段都是通过 referer 字段来判断请求的来源地,由此去判定请求是否合法。但是该字段容易伪造,所以很少用该方法实现防盗功能。而Nginx 的 secure_link 模块主要是使用 hash 算法加密方式,一般用于图片、视频下载,生成下载 URL,安全性高。此外,我们也可以使用一些第三方的模块增强 Nginx 的防盗链功能,比如常用的第三放模块ngx_http_accesskey_module 可用于实现文件下载的防盗功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/2394.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

DAY53|| 42. 接雨水|84.柱状图中最大的矩形

42. 接雨水(超经典款&#xff09; 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2…

字节跳动(抖音)软件测试月薪23K岗、技术二面面试题最新出炉

测试人员在测试中的任务是什么&#xff1f; ① 尽可能早地找出系统中的bug&#xff1b; ② 避免软件开发过程中缺陷的出现&#xff1b; ③ 协助开发定位bug.以及后续bug跟踪 ④ 一切以用户的需求为标准&#xff0c;确保软件的质量 HTTP与HTTPS协议的区别&#xff1f; …

新160个crackme - 091-DOSKEY-CRACKME2

运行分析 需破解Name和Password PE分析 upx壳&#xff0c;32位 手动脱壳 x32dbg打开程序&#xff0c;按一下F8&#xff0c;根据ESP定律&#xff0c;在此处下断点按一下F9&#xff0c;两下F8&#xff0c;来到OEP处00401000打开Scylla&#xff0c;点击转储保存文件点击IAT自动搜索…

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

ClickHouse安装

一&#xff0c;ClickHouse介绍 ClickHouse 是一个开源的列式数据库管理系统&#xff08;Column-Oriented DBMS&#xff09;&#xff0c;由俄罗斯的 Yandex 公司开发。它最初是为 Yandex 的 Metrica 分析服务设计的&#xff0c;用于处理大规模的数据分析任务。ClickHouse 能够提…

网络设置:静态IP与动态IP,何去何从?

在配置网络设备时&#xff0c;一个基础而重要的选择便是决定使用静态IP地址还是动态IP地址。这一决策直接影响到网络的连接性、管理便捷性以及安全性。静态IP与动态IP各有其独特的优势与适用场景&#xff0c;选择何种方式&#xff0c;需根据实际需求与网络环境来权衡。本文旨在…

po、dto、vo的使用场景

现在项目中有两类模型类&#xff1a;DTO数据传输对象、PO持久化对象&#xff0c;DTO用于接口层向业务层之间传输数据&#xff0c;PO用于业务层与持久层之间传输数据&#xff0c;有些项目还会设置VO对象&#xff0c;VO对象用在前端与接口层之间传输数据&#xff0c;如下图&#…

不用买PSP,画质甚至更好,这款免费神器让你玩遍经典游戏

作为掌机游戏爱好者的福音&#xff0c;PPSSPP模拟器为玩家带来了前所未有的PSP游戏体验&#xff0c;彻底改变了掌机游戏的体验方式。这款精湛的软件不仅完美复刻了PSP主机的游戏体验&#xff0c;更通过先进的模拟技术&#xff0c;将经典游戏提升到了全新的高度。对于那些珍藏PS…

如何新建CANoe工程

本文将从启动CANoe软件开始&#xff0c;一步步引导您完成新工程的创建与基本配置&#xff0c;确保您的仿真测试工作能够顺利进行。 启动CANoe软件&#xff1a;打开CANoe软件&#xff0c;进入主界面。 新建工程&#xff1a;点击菜单栏的 File --> New --> CAN FD&#x…

Facebook群控策略详解

Facebook群控早在前几年就很火爆了&#xff0c;对于做Facebook营销或者电商的跨境选手来说&#xff0c;这是个不错的提高效率扩大增长的办法。具体来说&#xff0c;Facebook群控是一种通过同时管理多个Facebook账户进行自动化推广活动的方法&#xff0c;它可以实现自动发布帖子…

通讯概念-全双工、串行、同步等

1.单工&#xff0c;半双工&#xff0c;双工概念 2.串行和并行&#xff1a; 并行多根数据总线同时传输&#xff0c;需要考虑波特率情况&#xff0c;串行波特率可以很大&#xff0c;不需要考虑传输总线限制 3.同步和异步概念&#xff1a; 同步需要时钟同步&#xff0c;发送和接收…

经济下行,电商人效通过小程序快速实现多端引流

中国经济下行周期&#xff0c;消费者趋向于理性消费&#xff0c;更注重产品的实用性和性价比。中端商品的需求减少&#xff0c;低端消费人群的消费能力下降&#xff0c;导致“消费降级”现象明显。 许多线下实体店以及传统电商&#xff0c;仅仅依靠现在的模式&#xff0c;很难…

Fish Agent:集成 ASR 和 TTS 的端到端语音处理模型,支持多语言转换

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

软件测试工程师面试整理 —— 编程与自动化!

在软件测试领域&#xff0c;编程与自动化是提升测试效率、覆盖率和可靠性的关键因素。掌握编程技术和自动化测试框架&#xff0c;能够帮助测试人员有效地执行大量重复性测试任务&#xff0c;并迅速反馈软件的质量状况。以下是编程与自动化在测试中的主要应用及相关技术介绍&…

04字符串算法/代码随想录

四、字符串 反转字符串 力扣344 遇到数组双指针真是太好用了&#xff0c;左右指针不断逼近即可&#xff0c;代码也很简单 class Solution {public void reverseString(char[] s) {int fast s.length - 1;int slow 0;while (slow < fast) {char temp s[fast];s[fast] s[…

Unreal5从入门到精通之如何使用C++实现一个剧情系统

前言 说到剧情系统,大家可能会说,UE的关卡序列Sequencer,做剧情不是很方便吗?没错,Sequencer确实方便,而且它可以让你为场景中的角色,物体等创建精确的动画,并使用关键帧来控制他们的运动和状态变化。 它还可以做相机的移动,剪辑,音效,特效等故事情节,相机特效,多…

袋鼠云产品功能更新报告12期|让数据资产管理更高效

本期&#xff0c;我们更新和优化了数据资产平台相关功能&#xff0c;为您提供更高效的产品能力。以下为第12期袋鼠云产品功能更新报告&#xff0c;请继续阅读。 一、【元数据】重点更新 &#xff5c;01 元数据管理优化&#xff0c;支持配置表生命周期 之前系统中缺少一个可以…

将多个commit合并成一个commit并提交

0 Preface/foreword 1 压缩多个commit方法 1.1 git merge --squash 主分支&#xff1a;main 开发分支&#xff1a;test 当前在test分支提交了8个commits&#xff0c;功能已经开发完成&#xff0c;需要将test分支合并到main分支&#xff0c;但是不想在合并时候&#xff0c;看…

大数据新视界 -- 大数据大厂之提升 Impala 查询效率:重写查询语句的黄金法则(下)(4/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

我想让AI帮我生成一点不正经的东西……

前言 最近突发奇想&#xff1a;为啥我一定要不断得翻找各种壁纸呢&#xff1f;为啥就不能让AI给我生成一张专属的壁纸&#xff0c;上面有我喜欢的内容&#xff0c;这样&#xff0c;我这张壁纸就是独一无二的了&#xff01; 说干就干&#xff0c;小白默默打开了AI工具…… 点我…