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"