【充电】《Nginx核心知识100讲》防盗链:referer模块
极客专栏《Nginx核心知识100讲》75~76小节,笔记
注意:这个是看专栏视频,敲的哈。这个专栏让我收货蛮大的。
75 | 使用变量防盗链的referer模块
有一类http模块只是在提供变量或修改变量。比如referer模块。
image.png指令
image.png image.png例子
image.png看看下面八个小例子,可以根据配置思考下为什么。
image.png image.png image.png image.png image.png image.png image.png image.png image.png使用referer模块防盗链是非常简易的,因为攻击者可以很方便的修改头部。
留言问题
- 爬虫中可以修改refer吗?
作者回复
可以
2。refer 字段是浏览器加到头里面的。所以自己构造请求时可以任意修改
作者回复
对的!
76 | 使用变量实现防盗链功能实践:secure_link模块
功能更强的防盗链模块——secure_link。
image.png来看一看secure_link 提供了两种防盗链方式是怎样实现的。
实现防盗链的过程
做法是怎样的?首先生成的链接URL不是简单的罗列资源,而是做过处理,可以理解为加密过的安全URL,至于这个URL是谁生成的呢?这不重要,可以是一个tomcat也可以是其他服务器。但是它需要跟nginx共享它们密钥就可以。当然你用nginx或openresty +lua生成密钥也是可以的。客户端拿到是加密过的密钥。客户端使用这个样的安全的URL访问nginx,nginx使用了secure_link模块,这个模块提供了一个变量secure_link变量,根据这个变量是真还是假,真的时候可以通过0和1来做一些时间是否过期的判断。这就是实现防盗链的过程。
原理
算法不可逆。
谁能拿到hash前呢URL呢?一个是生成url的服务器能拿到原始字符串,一个是nginx能拿到原始字符串。客户端做任何操作都会导致验证不通过。因为nginx验证的方式,因为它能构造出原始的字符串。基于原始的字符串,基于大家认可的hash算法,做一次hash。然后把hash完的结果与用户请求中携带的hash结果做匹配。如果匹配到了就是合法的。如果没有匹配到就是非法的。这个原始字符串,它与生成hash值的服务器,它两是想通的。
原始字符串通常包含四个部分,如果没有包含也是可以用的,但是安全性就会降低。比如要包含资源的位置,也就是url通常包含资源的路径,它在哪个目录下,他是哪个文件,文件名、后缀名是什么。如果没有包含位置,就有可能攻击者拿到安全URL去下载任意资源。而我们在原始字符串中,含有资源位置可以防止攻击者访问任意资源。第二个,包含用户信息,某一个用户可以访问,不代表其他用户可以访问这个资源,用户名和用户ip都可以。第三个,时间戳,我们希望我们的连接是有效的。比如我们下载一个1M的文件,可能我们预估一个1小时或两小时,一定可以下完。为了防止密钥泄露,要使URL能够及早过期。第四,密钥,如果没有密钥,可以通过组合以上不同字符串的顺序,来作为原始字符串。但组合的场景非常少。所以要引入一个密钥。这个密钥 由生成生成加密连接的服务器生成拥有,nginx也拥有。然后把这个密钥掺杂到前三个部分中。使得攻击者猜测原始字符串的难度增加。
模块指令
image.png image.png image.png示例
image.png生成摘要(md5)
image.png image.png把时间改错,再试下
image.png一个简单办法
image.png image.png示例
密钥是 myscret2
image.png配置
internal 只能内部可以访问。
image.png image.png以上我们介绍了secure_link模块通过变量的方式提供了两种防盗链的方法。前一种方法可以对用户、时间戳区分。后一种更简单,只能对用户访问的资源URI作区分。
留言问题
- 在视频的11:38的时候的那个rewrite我没有看明白,rewrite不是应该跟一个正则表达式和一个跳转的location吗,为什么^后面没有正则表达式呢?
作者回复
^可以匹配上任何url,而且当前场景也不需要从url中取出一些分组的值,故如此使用。
2.这个的原理是生成一个下载的 token,用户访问的时候 nginx 来验证这个 token 就可以了
作者回复
没错!
3.老师,看完这个视频后,如何将secert_link应用到生产环境中,现在还是一头雾水,总不能每次的访问请求都用md5先只做好相关的信息再进行请求吧?
作者回复
是的,所以它依赖于下载页面,这个页面中的下载URL都是通过这个规则生成的。这个模块一定要配合应用服务一起工作的。