Nginx系列:安全下載模塊
閱讀文本大概需要3分鐘。
? ? ? ngx_http_secure_link_module模塊用于檢查請求鏈接的真?zhèn)?,保護(hù)資源免受未經(jīng)授權(quán)的訪問,限制鏈接的生命周期。
? ? ? 通過將請求中傳遞的校驗(yàn)和值與請求計(jì)算的值進(jìn)行比較來驗(yàn)證請求鏈接的真實(shí)性。如果鏈接的生命周期有限并且時間已過,則該鏈接將被視為過時。

驗(yàn)證原理:
用戶在客戶端點(diǎn)擊下載按鈕,服務(wù)器收到請求后生成一個
下載地址返回給客戶端。客戶端使用這個生成的下載地址去請求資源,此時nginx去做校驗(yàn),校驗(yàn)鏈接地址真?zhèn)魏玩溄拥刂肥欠襁^期。如果鏈接地址是真的并且鏈接地址沒有過期,就給客戶端返回下載資源。
nginx驗(yàn)證和服務(wù)器生成密鑰規(guī)則要一致,否則驗(yàn)證是不會通過的
該模塊提供兩種備選操作模式:
第一種模式
secure_link_secret指令啟用,用于檢查請求鏈接的真實(shí)性以及保護(hù)資源免受未經(jīng)授權(quán)的訪問第二種模式
secure_link和secure_link_md5指令啟用,也用于限制鏈接生命周期。
更詳細(xì)參考官網(wǎng)
http://nginx.org/en/docs/http/ngx_http_secure_link_module.html
0x01:配置模塊語法
ngx_http_secure_link_module主要有以下三個語法
secure_link
Syntax:?secure_link?expression;
Default:?—
Context:?http,?server,?locationsecure_link_md5
Syntax:?secure_link_md5?expression;
Default:?—
Context:?http,?server,?location
secure_link_secret
Syntax:?secure_link_secret?word;
Default:?—
Context:?location
0x02:安裝ngx_http_secure_link_module模塊
首先檢查nginx是否已安裝模塊
#nginx?-V
結(jié)果如下,沒有安裝ngx_http_secure_link_module模塊

輸出nginx所有已安裝模塊,檢查是否有ngx_http_secure_link_module,因?yàn)檫@個模塊沒有默認(rèn)編譯,在編譯Nginx時,必須使用明確的配置參數(shù)
--with-http_secure_link_module
安裝
執(zhí)行以下命令
#先安裝secure?link?其實(shí)這個組件nginx本身就有,只不過是默認(rèn)不安裝罷了
./configure??--prefix=/usr/local/nginx?--user=nginx?\
--group=nginx?--with-http_secure_link_module?\
--with-http_stub_status_module
執(zhí)行mak編譯nginx
makemake之后的操作需要注意,如果nginx第一次安裝,直接執(zhí)行make install即可
make?install如果單純添加模塊,不需要install,而是執(zhí)行以下操作,將打過補(bǔ)丁的nginx二進(jìn)制文件覆蓋/usr/local/nginx/sbin/目錄中的文件即可
#備份之前的nginx
mv?/usr/local/nginx/sbin/nginx ?/usr/local/nginx/sbin/nginx.bak
#拷貝新的nginx到sbin目錄
cp?/nginx源碼目錄/objs/nginx???/usr/local/nginx/sbin/0x03:?ngx_http_secure_link_module配置
在server節(jié)點(diǎn)增加以下location配置
location?/?{
????root?html;?
????#這里配置了2個參數(shù)一個是md5,一個是expires
????secure_link?$arg_md5,$arg_expires;
????#md5的哈希格式為:?expires+url+addr
????#expires為時間戳單位s
????#url為請求地址
????#remote_addr為遠(yuǎn)程IP地址
????#mysecure為密鑰
????secure_link_md5?"mysecure$secure_link_expires$uri$remote_addr";
????if?($secure_link?=?"")?{
????#資源不存在或哈希比對失敗
????????return?402;
????}
????if?($secure_link?=?"0")?{
????????#時間戳過期
????????return?404;
????}
????if?($request_filename?~*?^.*?\.(mp4)$){
????????#直接下載防止打開文件??格式:?(mp4|txt|jpg)
????????add_header?Content-Disposition?'attachment;';
????}
}
#設(shè)置400,404的跳轉(zhuǎn)
#在server節(jié)點(diǎn)
error_page?400?=?400.html;?#跳轉(zhuǎn)400頁面
error_page?404?=?404.html;?#跳轉(zhuǎn)404頁面
? 在html目錄添加400.html和404.htmll兩個界面

0x04:JAVA計(jì)算防盜鏈地址
需要使用到commons-codec-1.10.jar包,請自行下載
package?com.alibaba.csp.sentinel.datasource.consul;
import?org.apache.commons.codec.binary.Base64;
import?org.apache.commons.codec.digest.DigestUtils;
/**
?*?防盜鏈資源下載地址
?*
?*/
public?class?GenSourceDownloadPath?{
????final?static?String?HTTP?=?"http://";
????final?static?String?ST?=?"?md5=";
????final?static?String?E?=?"&expires=";
????final?static?String?F?=?"/";
????final?static?String?WARN?=?"path參數(shù)最好帶上?\"/\"?,例:?\"/abc.mp4\"?";
????final?static?String?SERVER_IP?=?"127.0.0.1";
????final?static?Long?expires?=?20L;?//過期時間 秒
????final?static?String?secret?=?"mysecure";?//密鑰
????public?static?String?execute(String?path)?{
????????if?(path.indexOf(F)?==?-1)?{
????????????path?=??F?+?path;
????????????System.out.println(WARN);
????????}
????????//?+n代表n秒后地址失效
????????String?time?=?String.valueOf(System.currentTimeMillis()?/?1000?+?expires);?
????????//?$secure_link_expires$uri$remote_addr
????????String?md5Str?=?secret?+?time?+?path?+?SERVER_IP;
????????byte[]?md5byte?=?DigestUtils.md5(md5Str);
????????String?base64?=?Base64.encodeBase64URLSafeString(md5byte);
????????return?HTTP?+?SERVER_IP?+?path+?ST?+?base64?+?E?+?time;
????}
????public?static?void?main(String[]?args)?{
????????System.out.println(execute("my.conf"));
????}
}
現(xiàn)在html目錄存放一個圖片文件my.conf,該文件是需要訪問演示的文件

執(zhí)行GenSourceDownloadPath生成一個訪問的URL:
http://127.0.0.1/my.conf?md5=YO4diAmlVa8NfHlMBCMFaw&expires=1598071052
執(zhí)行訪問

如果沒有帶參數(shù)訪問

超過20s訪問,不在有權(quán)限訪問

備注:
如果按官方秘密mysecure放在最后,需加一個空格與參數(shù)分隔

在使用java計(jì)算時也需要多加一個空格

☆
往期精彩
☆
01?Sentinel如何進(jìn)行流量監(jiān)控
02?Nacos源碼編譯
03?基于Apache Curator框架的ZooKeeper使用詳解
關(guān)注我
每天進(jìn)步一點(diǎn)點(diǎn)
