使用变量防盗链的secure_link模块

440 阅读2分钟

secure_link模块默认是没有被编译进nginx中的,所以要使用--with=http_secure_link_module模块编译进nginx中。

一、实现的过程

  • 有服务器A生成加密后的安全URL,并返回给客户端。

  • 客户端获取到URL之后,再向服务器B进行访问,根据服务器B的nginx中的secure_link变量进行判断,是否验证通过。

这里的服务器A、B时相通的,都知道原始url和密钥是什么,我觉得这两个服务器可以是一个。

二、实现原理

  • 哈希算法是不可逆的。数学思想上是可逆的,但是实现成本非常高,所以认为是不可逆的。

  • 客户端只能拿到安全URL。

  • 服务器B的nginx在接收到来自客户端的安全链接时,将自己知道原始url使用密钥进行加密,加密之后的链接和请求的安全链接进行对比,如果一致,则验证通过,如果不一致,则验证不通过。

  • 原始字符串的组成:

  • 资源位置,例如HTTP中指定资源的URI,防止攻击者拿到一个安全的URL之后,可以访问任意资源。

  • 用户信息,例如用户的IP地址或者用户名,防止其他用户盗用安全URL。一个用户能够访问安全URL,不代表其他用户也能访问。

  • 时间戳,使安全URL能够过期。

  • 密钥,只有生成安全URL的服务器和nginx有,增加攻击者猜测出原始URL的难度。

三、指令

第一种较为复杂的使用方式,是我们平常使用的secure_link + secure_link_md5。

另外,还有一种比较简单的方式是secure_link_secret。

四、变量

  • secure_link:值为空字符串,表示校验不通过;值为0,表示URL过期;值为1,表示验证通过。

  • secure_link_expires:返回验证通过时的时间戳

五、案例

原链接:/text/1.txt?md5=md5生成值&expires=时间戳

生成md5:echo -n '时间戳URL客户端IP地址密钥 | openssl md5 -binary | openssl base64 | tr +/ - | tr -d ='

nginx配置:

       secure_link $arg_md5 $arg_expires       
       secure_link_md5 "$secure_link_expires$uri$remote_addr secret"