一. 防盜鏈原理
http 協議中,如果從一個網頁跳到另一個網頁,http 頭字段里面會帶個 Referer。圖片服務器通過檢測 Referer 是否來自規定域名,來進行防盜鏈。
設置突破防盜鏈方法
1. 使用apache文件FileMatch限制,在httpd.conf中增加 ( 其實也可以將把下面的語句存成一個.htaccess文件),並放到你的網站的根目錄(就是www/html目錄),這樣子別人就沒有辦法盜連你的東東了~~
SetEnvIfNoCase Referer "^http://kuaishou.com/" local_ref=1 Order Allow,Deny Allow from env=local_ref Allow from 127.0.0.1
2. 使用rewrite,需要增加apache的mode_rewrite,支持.htaccess文件目錄權限限制
在虛擬主機根目錄增加.htaccess文件,描述從定向,把非本地地址refer的圖片文件都從定向到警告圖片或者警告網頁上。
RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ [NC] RewriteCond %{HTTP_REFERER} !simcole.cn [NC] RewriteCond %{HTTP_REFERER} !zhuaxia.com [NC] RewriteCond %{HTTP_REFERER} !google.com [NC] RewriteCond %{HTTP_REFERER} !baidu.com [NC] RewriteCond %{HTTP_REFERER} !bloglines.com [NC] //這部分是判斷是否盜鏈,如果以上條件都成立(即訪問圖片的請求,既不是直接輸入網址,也不是來自simcole.cn,也不是來自zhuaxia.com,也不是來自google.com,也不是來自baidu.com,也不是來自bloglines.com 的話),就執行下列轉向: RewriteRule .(jpg|gif|png|bmp|swf|jpeg) /image/replace.gif [R,NC,L] //意思是讓所有盜鏈 img 目錄下 jpg、gif、png、bmp、swf、jpeg 文件的網頁,顯示的圖片都用 image 目錄下的 replace.gif 圖片替換掉。 注意替換顯示的圖片不要放在設置防盜鏈的 img 目錄下。如果照上面的規則判斷出圖片請求不是盜鏈的,就執行以下轉向: RewriteRule ^(.*)$ http://image.simcole.cn/image/$1 [L] //意思是對 img 目錄下所有的請求都轉向到目標服務器,比如有個圖片原來的 url 是 http://www.bebecn.com/img/girl.jpg ,現在就會轉到 http://image.bebecn.com/image/girl.jpg 去
3. 通過php直接獲取資源,在php中進行攔截
$referer = $_SERVER['HTTP_REFERER']; //HTTP Referer是header的一部分,當瀏覽器向web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器基此可以獲得一些信息用於處理。 $selfurl = $_SERVER['HTTP_HOST'];//在php中,我們一般通過$_SERVER['HTTP_HOST']來活得URL中網站的域名或者ip地址。 if(false == strpos($referer,$selfurl)) { echo '非法盜鏈!'; exit(1); }
4. nginx防盜鏈
location ~* \.(gif|jpg|png|bmp)$ { valid_referers none blocked *.ttlsa.com server_names ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; #rewrite ^/ http://www.ttlsa.com/403.jpg; } }
參數說明:
none:“Referer” 來源頭部為空的情況
blocked:“Referer”來源頭部不為空,但是里面的值被代理或者防火牆刪除了,這些值都不以http://或者https://開頭.
server_names:“Referer”來源頭部包含當前的server_names(當前域名)
5. nodejs express模塊防盜鏈
var express = require('express'), path = require('path'), app = express(); var AntiLeech = require('express-anti-leech'); // 允許引用的域名白名單 var hosts = ['localhost', 'localhost:8004']; // 反盜鏈類型 var exts = ['.png', '.jpg', '.jpeg', '.gif', '.swf', '.flv']; // 盜鏈默認指向圖片 var pictrue = "/images/default.png"; app.use(AntiLeech({ allow: hosts, exts: exts, log: console.log, // 你也可以使用自己的方法來記錄 default: pictrue })); // 請在調用靜態資源之前先使用反盜鏈模塊 app.use(express.static(path.join(__dirname, 'public'))); app.set('port', process.env.PORT || 8004); app.get('/', function(req, res) { res.redirect("/index.html"); }); app.listen(app.get('port'), function() { console.log("Express test server listening on http://localhost:" + app.get('port')); });
二. 突破防盜鏈
1. referer為空
若不發送Referer,也就是沒有來源。那么官方那邊,就認為是從瀏覽器直接訪問的,所以就能加載正常的圖片
a. https訪問http
如果盜用網站是 https 的 protocol,而圖片鏈接是 http 的話,則從 https 向 http 發起的請求會因為安全性的規定,而不帶 referer,從而實現防盜鏈的繞過
b.
某些開啟隱私模式的瀏覽器中,或https頁面引用下,referer是空的
c. 設置頭部信息
Nodejs: res.writeHead(200, { 'Content-Type': 'image/*' }); let url = req.query.url; if (!url) { res.send(""); return false; } superagent.get(req.query.url) .set('Referer', '') .set("User-Agent", 'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.933.400 QQBrowser/9.4.8699.400' ) .end(function(err, result) { if (err) { //res.send(err); return false; } res.end(result.body); return; });
2. 代碼內請求偽造referer
PHP: $http = new Http("http://www.baidu.com/img/avatar.jpg"); $http->setHeader('Referer:http://www.baidu.com/');
3. 利用iframe偽造請求referer
function showImg( url ) { var frameid = 'frameimg' + Math.random(); window.img = '<img id="img" src=\''+url+'?'+Math.random()+'\' /><script>window.onload = function() { parent.document.getElementById(\''+frameid+'\').height = document.getElementById(\'img\').height+\'px\'; }<'+'/script>'; document.write('<iframe id="'+frameid+'" src="javascript:parent.img;" frameBorder="0" scrolling="no" width="100%"></iframe>'); }
4. meta標簽控制referer
如果頁面中包含了如下 meta 標簽,所有從當前頁面中發起的請求將不會攜帶 referer:
<meta name="referrer" content="never">
如果頁面中包含了如下 meta 標簽,則從當前頁面中發起的 http請求將只攜帶 origin 部分(注:根據原文中的語境,我理解這里的 origin 是包含了 schema 和 hostname 的部分 url,不包含 path 等后面的其他 url 部分),而不是完整的 URL :
<meta name="referrer" content="origin">
注意:在使用本文中所述的 meta 標簽的時候,瀏覽器原有的 referer 策略將被打破,比如從 http 協議的頁面跳轉到 https 的頁面的時候,如果設置了適當的值,也會攜帶 referer。
技術細節:
referer 的 metedata 參數可以設置為以下幾種類型的值:
never always origin default
如果在文檔中插入 meta 標簽,並且 name 屬性的值為 referer,瀏覽器客戶端將按照如下步驟處理這個標簽:
1.如果 meta 標簽中沒有 content 屬性,則終止下面所有操作 2.將 content 的值復制給 referrer-policy ,並轉換為小寫 3.檢查 content 的值是否為上面 list 中的一個,如果不是,則將值置為 default
上述步驟之后,瀏覽器后續發起 http 請求的時候,會按照 content 的值,做出如下反應(下面 referer-policy 的值即 meta 標簽中 content 的值):
1.如果 referer-policy 的值為never:刪除 http head 中的 referer; 2.如果 referer-policy 的值為default:如果當前頁面使用的是 https 協議,而正要加載的資源使用的是普通的 http 協議,則將 http header 中的 referer 置為空; 3.如果 referer-policy 的值為 origin:只發送 origin 部分; 4.如果 referer-policy 的值為 always:不改變http header 中的 referer 的值,注意:這種情況下,如果當前頁面使用了 https 協議,而要加載的資源使用的是 http 協議,加載資源的請求頭中也會攜帶 referer。
三. 防御反防盜鏈
關於防御方法,有以下3點:
1、不允許referer為空(不建議,因在某些開啟隱私模式的瀏覽器中,或https頁面引用下,referer是空的)
2、地址變更(lighttpd的是根據有效時間,nginx的根據是md5,IP地址變化)
3、登錄校驗(如必須登錄網站帳號后才能訪問)
擴展一:視頻防盜鏈和加密
視頻加密技術分為兩種:
1. 防盜鏈:通過驗證的用戶才能訪問到沒有加密的視頻內容,這種方案存在視頻很容易就被下載的風險,嚴格來說這不屬於加密。這種方式其實是資源訪問授權,它實現起來簡單。
2. 加密視頻本身:通過對稱加密算法加密視頻內容本身,用戶獲得加密后的視頻內容,通過驗證的用戶可以獲取解密視頻的密鑰,在客戶端解密后播放。這種方式實現起來流程復雜會帶來更多的計算量。
市面上常見的防盜手段:
1.設置 referer 白名單,非白名單內的一律拒絕訪問
2.在 URL 中添加 token 校驗,使用私有 key 和 time 實時計算 token,服務器作校驗
3.在第2條的基礎上,使用 https POST token 參數,增加抓取難度
4.使用 HLS(m3u8) 自帶的加密功能,加密傳輸數據,沒有密碼無法播放
5.使用數字版權保護(DRM)技術
還有一些不太常見的手段:
1.使用HTTPS客戶端證書,服務器可以對客戶端進行識別(目前常見的HTTPS是服務器端證書)
2.使用HLS(m3u8)自帶的加密功能,並對密碼做二次處理,客戶端經過兩次解密才能得到原數據
3.對視頻編碼進行二次處理,解碼時需要知道算法,否則無數得到原數據,見於海康監控系統
詳解見:http://imweb.io/topic/59819d7bf8b6c96352a593ff
擴展二:防止網站被鏡像,被iframe
1.防止網站被鏡像(被惡意解析和轉發等)
現象:他人域名訪問到的是我的網站解析的ip地址我的
解決方法:
http.ini里可以這樣寫
"RewriteCond Host: !^www.web\.cn$ RewriteRule (.*) http\://www\.web\.cn$1 [I,RP]"
.htaccess里可以這樣寫
“RewriteCond %{HTTP_HOST} !^www.web.cn$ [NC] RewriteRule ^(.*)$ http://www.web.cn/$1 [L,R=301]”
代碼的意思非常簡單:訪問這個網站的域名如果不是"www.web.cn"就自動跳轉到"www.web.cn"上。這樣設置就不怕自己辛辛苦苦維護的網站被別人鏡像了。
2.防止網址被iframe
代碼:在頁面底部或其它公用部位加入如下代碼
<script type=”text/javascript> if(window!=parent) window.top.location.href = window.location.href; < /script>
代碼的意思也很簡單,用js方法檢測地址欄域名是不是當前網站綁定的域名,如果不是,則跳轉到綁定的域名上來,這樣就不怕網站被別人iframe了。
3.如何防止網站被復制保存或者被下載
參考文檔:http://www.3lian.com/edu/2013/10-12/101296.html
參考:
http://www.freebuf.com/news/57497.html
https://www.zhihu.com/question/35044484/answer/350722473
https://www.cnblogs.com/lydiawork/p/7838153.html
https://blog.csdn.net/enweitech/article/details/45745171
https://www.zhihu.com/question/64369225/answer/219528505