盜鏈的概念
指在自己的頁面上展示一些並不在自己伺服器上的內容。也就是獲得他人伺服器上的資源地址,繞過別人的資源展示頁面,直接在自己的頁面上向終端使用者提供此內容。如,小站盜用大站的圖片、音樂、視訊、軟體等資源來減輕自己伺服器的負擔。
防盜鏈的概念
防止別人通過一些技術手段繞過本站的資源展示頁面,盜用本站的資源。繞開本站資源展示頁面的資源連結失效就達到了防盜鏈。
防盜鏈的工作原理
通過Referer或者簽名,網站可以檢測到目標頁面訪問的來源頁面,如果是資原始檔,則可以跟蹤到顯示它的網址頁面。一旦檢測到來源不是本站即進行組織或者返回指定的頁面。
觀察一下NetWork中Request Header中的Referer,可以根據此方法判斷是不是盜鏈。
還比如用簽名,就是在請求圖片的時候,帶一個引數,這個引數是彼此之前約定好的簽名,伺服器在顯示圖片的時候判斷簽名是否正確來判斷,通常簽名是很複雜的。
Referer方法
Nginx模組ngx_http_referer_module用於阻擋來源非法的域名請求。
Nginx指令valid_referers,全域性變數$invalid_referer。也就是如果想用這個模組,那麼就用這個變數。
使用方法
valid_referers none | blocked | server_names | string ...;
node :代表是referer是否為空,寫none表示也是合法的,不寫none表示來源不合法(Referer來源頭部為空的情況下)
blocked :"Referer"來源頭部不為空,但是裡面的值被代理了或者防火牆刪除了,這些值都不以http://或者htps://開頭
server_names : "Referer"來源頭部包含當前的server_names,也就是被允許的源的列表。
下面在虛擬機器上做一下測試,WEB伺服器是Nginx。
分別是192.168.136.135(實際檔案源伺服器) 192.168.136.138(盜用連線的伺服器)
進入192.168.136.135的網站根目錄,上傳圖片,編寫一個訪問頁面並連結圖片,訪問檢視NetWork
下面開始編輯192.168.136.135的Nginx配置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$
其中“gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico”設定防盜鏈檔案型別,自行修改,每個字尾用“|”符號分開!
valid_referers none blocked *.baidu.com baidu.com;
就是白名單,允許檔案鏈出的域名白名單,自行修改成您的域名!*.baidu.com這個指的是子域名,域名與域名之間使用空格隔開!
rewrite ^/ http://www.baidu.com/img/bd_logo1.png;
這個圖片是盜鏈返回的圖片,也就是替換盜鏈網站所有盜鏈的圖片。這個圖片要放在沒有設定防盜鏈的網站上,因為防盜鏈的作用,這個圖片如果也放在防盜鏈網站上就會被當作防盜鏈顯示不出來了,盜鏈者的網站所盜鏈圖片會顯示X符號。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
#通過valid_referers做防盜鏈,寫了三項
#node :表示referer為空的時候也可以顯示(直接在瀏覽器訪問圖片)
#blocked :表示防火牆或者代理刪除我們的referer的時候也可以
#server_names : "Referer" 來源頭部包含當前的server_names,也就是被允許的源的列表,直接通過IP也可以(測試用的IP)
valid_referers none blocked 192.168.136.135;
if ($invalid_referer ) {
#return 403; #如果開啟此項,http狀態碼為403
rewrite ^/ http://www.baidu.com/img/bd_logo1.png; #百度LOGO
}
expires 30d;
access_log off;
}
/usr/local/nginx/sbin/nginx -s reload //修改完成之後,別忘了重新載入一下Nginx配置,平滑重啟
下面在盜用的伺服器上做一下測試,圖片的連線地址是http://192.168.136.135/img/1.png,然後訪問192.168.136.138檢視響應
當然也可以針對目錄進行防盜鏈
location /img/ {
#通過valid_referers做防盜鏈,寫了三項
#node :表示referer為空的時候也可以顯示(直接在瀏覽器訪問圖片)
#blocked :表示防火牆或者代理刪除我們的referer的時候也可以
#server_names : "Referer" 來源頭部包含當前的server_names,也就是被允許的源的列表,直接通過IP也可以(測試用的IP)
valid_referers none blocked 192.168.136.135;
if ($invalid_referer ) {
#return 403; #如果開啟此項,http狀態碼為403
rewrite ^/ http://www.baidu.com/img/bd_logo1.png; #百度LOGO
}
expires 30d;
access_log off;
}
這樣設定差不多就可以起到防盜鏈作用了,上面說了,這樣並不是徹底地實現真正意義上的防盜鏈!當然也可以把前兩項去掉:valid_referers 192.168.136.135;,更嚴謹一步防止盜鏈。因為可以偽造Referer。
加密簽名方法
請求圖片的時候帶簽名過去,當返回圖片的時候判斷簽名是否正確,也就是暗號。
加密簽名的時候需要使用第三方模組HttpAccessKeyModule,因為在服務端php裡需要顯示圖片的時候跟一個簽名,交給Nginx的時候,Nginx需要做一個判斷,判斷前面是否正確,Nginx在判斷的時候就需要這個模組了。
連結:https://pan.baidu.com/s/1bqekisB 密碼:h24h //下載地址
用法:
用之前需要安裝,安裝好配置指令
accesskey on | off //模組開關
開啟之後
accesskey_hashmethod md5 | sha-1 //簽名加密的方式
accesskey_arg GET 引數名稱 //我們去請求圖片或者資源的時候,後面帶的引數名稱是什麼,需要傳遞簽名,但是前提需要知道簽名的key(名稱)是多少
accesskey_signature //加密規則,需要跟Nginx說我們的加密規則是什麼,需要PHP的規則和Nginx的規則保持一致,那麼才會控制圖片的顯示
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
accesskey on;
accesskey_hashmethod md5;
accesskey_arg sign; #引數鍵名
accesskey_signaurre "mytest$remote_addr"; #mytest字串拼接客戶端ip然後md5加密
expires 30d;
}
儲存reload
然後再我們的PHP端模擬訪問一個圖片
<?php
$accesskey = "mytest"; //自定義的祕鑰串
$user_addr = $_SERVER['REMOTE_ADDR']; //客戶端IP
$urlkey = md5($accesskey .$user_addr );
echo '<img src="./img/1.png?sing="'. $urlkey .'">'; //sign是Nginx配置中的引數鍵
echo '<img src="./img/1.png">'; //對比測試
測試以下,OK,NetWork圖片referer帶引數,實現了防盜鏈~