單有效的防盜鏈?zhǔn)侄?/p>
如果做過(guò)個(gè)人站點(diǎn)的同學(xué),可能會(huì)遇到別人盜用自己站點(diǎn)資源鏈接的情況,這就是盜鏈。說(shuō)到盜鏈就要說(shuō)一個(gè) HTTP 協(xié)議的 頭部,referer 頭部。當(dāng)其他網(wǎng)站通過(guò) URL 引用了你的頁(yè)面,用戶在瀏覽器上點(diǎn)擊 URL 時(shí),HTTP 請(qǐng)求的頭部會(huì)通過(guò) referer 頭部將該網(wǎng)站當(dāng)前頁(yè)面的 URL 帶上,告訴服務(wù)器本次請(qǐng)求是由誰(shuí)發(fā)起的。
例如,在谷歌中搜索 Nginx 然后點(diǎn)擊鏈接:
在打開(kāi)的新頁(yè)面中查看請(qǐng)求頭會(huì)發(fā)現(xiàn),請(qǐng)求頭中包含了 referer 頭部且值是 https://www.google.com/。
像谷歌這種我們是允許的,但是有一些其他的網(wǎng)站想要引用我們自己網(wǎng)站的資源時(shí),就需要做一些管控了,不然豈不是誰(shuí)都可以拿到鏈接。
這里目的其實(shí)已經(jīng)很明確了,就是要拒絕非正常的網(wǎng)站訪問(wèn)我們站點(diǎn)的資源。
要實(shí)現(xiàn)上面的目的,referer 模塊可得算頭一號(hào),一起看下 referer 模塊怎么用的。
referer 模塊有三個(gè)指令,下面看一下。
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
Syntax: referer_hash_bucket_size size;
Default: referer_hash_bucket_size 64;
Context: server, location
Syntax: referer_hash_max_size size;
Default: referer_hash_max_size 2048;
Context: server, location
這里面最重要的是 valid_referers 指令,需要重點(diǎn)來(lái)說(shuō)明一下。
可以同時(shí)攜帶多個(gè)參數(shù),表示多個(gè) referer 頭部都生效。
參數(shù)值
invalid_referer 變量
下面來(lái)看一個(gè)配置文件。
server {
server_name referer.ziyang.com;
listen 80;
error_log logs/myerror.log debug;
root html;
location /{
valid_referers none blocked server_names
*.ziyang.com www.ziyang.org.cn/nginx/
~\.google\.;
if ($invalid_referer) {
return 403;
}
return 200 'valid\n';
}
}
那么對(duì)于這個(gè)配置文件而言,以下哪些請(qǐng)求會(huì)被拒絕呢?
curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/
curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/
curl -H 'referer: ' referer.ziyang.com/
curl referer.ziyang.com/
curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/
curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/
curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/
curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/
我們需要先來(lái)解析一下這個(gè)配置文件。valid_referers 指令配置了哪些值呢?
valid_referers none blocked server_names
*.ziyang.com www.ziyang.org.cn/nginx/
~\.google\.;
下面就實(shí)際看下響應(yīng):
# 返回 403,沒(méi)有匹配到任何規(guī)則
? ~ curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.8</center>
</body>
</html>
? ~ curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.8</center>
</body>
</html>
# 匹配到了 *.ziyang.com
? ~ curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/
valid
? ~ curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/
valid
# 匹配到了 server name
? ~ curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/
valid
# 匹配到了 blocked
? ~ curl -H 'referer: ' referer.ziyang.com/
valid
# 匹配到了 none
? ~ curl referer.ziyang.com/
valid
# 匹配到了 ~\.google\.
? ~ curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/
valid
referer 模塊是一種簡(jiǎn)單的防盜鏈?zhǔn)侄危仨氁蕾嚍g覽器發(fā)起請(qǐng)求才會(huì)有效,如果攻擊者偽造 referer 頭部的話,這種方式就失效了。
secure_link 模塊是另外一種解決的方案。
它的主要原理是,通過(guò)驗(yàn)證 URL 中哈希值的方式防盜鏈。
基本過(guò)程是這個(gè)樣子的:
原理如下:
模塊:
Syntax: secure_link expression;
Default: —
Context: http, server, location
Syntax: secure_link_md5 expression;
Default: —
Context: http, server, location
Syntax: secure_link_secret word;
Default: —
Context: location
命令行生成安全鏈接
echo -n '時(shí)間戳URL客戶端IP密鑰' | openssl md5 -binary | openssl base64 | tr +/ - | tr -d =
/test1.txt?md5=md5生成值&expires=時(shí)間戳(如 2147483647)
Nginx 配置
下面是一個(gè)實(shí)際的配置文件,我這里就不做演示了,感興趣的可以自己做下實(shí)驗(yàn)。
server {
server_name securelink.ziyang.com;
listen 80;
error_log logs/myerror.log info;
default_type text/plain;
location /{
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
return 200 '$secure_link:$secure_link_expires\n';
}
location /p/ {
secure_link_secret mysecret2;
if ($secure_link = "") {
return 403;
}
rewrite ^ /secure/$secure_link;
}
location /secure/ {
alias html/;
internal;
}
}
除了上面這種相對(duì)復(fù)雜的方式防盜鏈,還有一種相對(duì)簡(jiǎn)單的防盜鏈方式,就是只對(duì) URI 進(jìn)行哈希,這樣當(dāng) URI 傳
命令行生成安全鏈接
Nginx 配置
這個(gè)防盜鏈的方法比較簡(jiǎn)單,那么具體是怎么用呢?大家都在網(wǎng)上下載過(guò)資源對(duì)吧,不管是電子書(shū)還是軟件,很多網(wǎng)站你點(diǎn)擊下載的時(shí)候往往會(huì)彈出另外一個(gè)頁(yè)面去下載,這個(gè)新的頁(yè)面其實(shí)就是請(qǐng)求的 Nginx 生成的安全 URL。如果這個(gè) URL 被拿到的話,其實(shí)還是可以用的,所以需要經(jīng)常的更新密鑰來(lái)確保 URL 不會(huì)被盜用。
者:Java3y
原文:轉(zhuǎn)載自微信公眾號(hào),Java3y
只有光頭才能變強(qiáng)。
文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/ZhongFuCheng3y/3y
我們絕大多數(shù)的Web應(yīng)用都是基于HTTP來(lái)進(jìn)行開(kāi)發(fā)的。我們對(duì)Web的操作都是通過(guò)HTTP協(xié)議來(lái)進(jìn)行傳輸數(shù)據(jù)的。
簡(jiǎn)單來(lái)說(shuō),HTTP協(xié)議就是客戶端和服務(wù)器交互的一種通迅的格式。
HTTP的誕生主要是為了能夠讓文檔之間相互關(guān)聯(lián),形成超文本可以互相傳閱
可以說(shuō),Http就是Web通信的基礎(chǔ),這是我們必學(xué)的。
我們學(xué)計(jì)算機(jī)網(wǎng)絡(luò)的時(shí)候就知道,我們把計(jì)算機(jī)網(wǎng)絡(luò)分層了5層,一般我們現(xiàn)在用的都是TCP/IP這么一個(gè)分層結(jié)構(gòu)。
雖然官方的是ISO 提出的7層結(jié)構(gòu),但是僅僅是理論基礎(chǔ),在實(shí)際上大多人都是使用TCP/IP的分層結(jié)構(gòu)
首先,我們先得知道,為什么我們要在計(jì)算機(jī)網(wǎng)絡(luò)中分層次???
因?yàn)槿绻麅膳_(tái)計(jì)算機(jī)能夠相互通信的話,實(shí)際實(shí)現(xiàn)起來(lái)是非常困難操作的…我們分層的目的就是為了將困難的問(wèn)題簡(jiǎn)單化,并且如果我們分層了,我們?cè)谑褂玫臅r(shí)候就可以僅僅關(guān)注我們需要關(guān)注的層次,而不用理會(huì)其他層。
如果需要改動(dòng)設(shè)計(jì)的時(shí)候,我們只需要把變動(dòng)的層替換即可,并不用涉及到其他的層次。這與我們程序設(shè)計(jì)中的低耦合是一個(gè)概念。
而我們的HTTP協(xié)議是在最上層,也就是應(yīng)用層。這是最貼近我們的程序員的層次。
網(wǎng)站通信粗略過(guò)程
我們知道HTTP是在應(yīng)用層中的,顯然,我們?cè)赪eb通信的過(guò)程中,不僅僅是需要HTTP協(xié)議的,還會(huì)涉及到其他的協(xié)議的。
DNS:負(fù)責(zé)解析域名
HTTP:產(chǎn)生請(qǐng)求報(bào)文數(shù)據(jù)
這里寫(xiě)圖片描述
TCP協(xié)議:分割HTTP數(shù)據(jù),保證數(shù)據(jù)運(yùn)輸
IP協(xié)議:傳輸數(shù)據(jù)包,找到通信目的地地址。
接下來(lái)就離我們比較遠(yuǎn)了,屬于硬件相關(guān)的了,也就是鏈路層和物理層。以后復(fù)習(xí)到計(jì)算機(jī)網(wǎng)絡(luò)的時(shí)候再來(lái)補(bǔ)充吧!
我們網(wǎng)頁(yè)上請(qǐng)求數(shù)據(jù)就是上邊這么一個(gè)流程。
我們?nèi)绻_(kāi)發(fā)過(guò)Web程序的話,我們知道常用的提交方式有POST和GET方法
我們也知道GET是用來(lái)獲取數(shù)據(jù)的,POST是用來(lái)提交數(shù)據(jù)的。
其實(shí)HTTP協(xié)議中還支持著其他的方法,比如:Input、Delete、OPTIONS很多這樣的方法。而由于常用,于是我們也可能僅僅知道GET和POST方法了。
HTTP提供方法的目的就是為了告知服務(wù)器該客戶端想進(jìn)行什么操作。當(dāng)HTTP是OPTIONS方法的時(shí)候,服務(wù)器端就會(huì)返回它支持什么HTTP方法。
當(dāng)然了,現(xiàn)在RESTful盛行,也就是充分利用了HTTP協(xié)議的這些方法。
HTTP是無(wú)狀態(tài)的,也就是說(shuō),它是不對(duì)通信狀態(tài)進(jìn)行保存的。它并不知道之前通信的對(duì)方是誰(shuí)。這樣設(shè)計(jì)的目的就是為了讓HTTP簡(jiǎn)單化,能夠快速處理大量的事務(wù)!
但是,我們經(jīng)常是需要知道訪問(wèn)的人是誰(shuí),于是就有了Cookie技術(shù)了。
在HTTP1.0的時(shí)候,每一次進(jìn)行HTTP通信就會(huì)斷開(kāi)一次連接。如果容量很少的文本傳輸是沒(méi)有問(wèn)題的。但是如果我們?cè)L問(wèn)一個(gè)網(wǎng)頁(yè),該網(wǎng)頁(yè)有非常多的圖片。一個(gè)圖片就算上一個(gè)HTTP請(qǐng)求了。那么在中途中就不斷地建立TCP連接、獲取圖片、斷開(kāi)TCP連接。
這樣是非常浪費(fèi)資源的,因此在HTTP1.1版本,就是持久連接了。一次HTTP連接能夠處理多個(gè)請(qǐng)求。
持久連接為“管線化”方式發(fā)送成為了可能:在一次HTTP連接里面,不需要等待服務(wù)器響應(yīng)請(qǐng)求,就能夠繼續(xù)發(fā)送第二次請(qǐng)求。
在說(shuō)明之前,首先我們要知道什么是實(shí)體主體
一般地,實(shí)體主體可以等價(jià)為報(bào)文主體,報(bào)文主體是HTTP中的一部分。
我們?nèi)绻皇褂萌魏问侄危?wù)器返回的數(shù)據(jù)實(shí)體主體是原樣返回的。我們可以使用兩種方式來(lái)提高傳輸效率
我們?nèi)绻谙螺d東西的過(guò)程中斷了,按照以前我們是需要重新下載的,但是現(xiàn)在可以在中斷中繼續(xù)下載。我們可以使用到獲取范圍數(shù)據(jù),這種叫做范圍請(qǐng)求!
這種請(qǐng)求只會(huì)下載資源的一部分。
2XX
一般是請(qǐng)求成功
200 正常處理
204 成功處理,但服務(wù)器沒(méi)有新數(shù)據(jù)返回,顯示頁(yè)面不更新
206 對(duì)服務(wù)器進(jìn)行范圍請(qǐng)求,只返回一部分?jǐn)?shù)據(jù)
3XX
一般表示重定向
301 請(qǐng)求的資源已分配了新的URI中,URL地址改變了。【永久重定向】
302 請(qǐng)求的資源臨時(shí)分配了新的URI中,URL地址沒(méi)變【轉(zhuǎn)發(fā)】
303 與302相同的功能,但明確客戶端應(yīng)該采用GET方式來(lái)獲取資源
304 發(fā)送了附帶請(qǐng)求,但不符合條件【返回未過(guò)期的緩存數(shù)據(jù)】
307 與302相同,但不會(huì)把POST請(qǐng)求變成GET
4XX
表示客戶端出錯(cuò)了。
400 請(qǐng)求報(bào)文語(yǔ)法錯(cuò)誤了
401 需要認(rèn)證身份
403 沒(méi)有權(quán)限訪問(wèn)
404 服務(wù)器沒(méi)有這個(gè)資源
5XX
服務(wù)器出錯(cuò)了
500 內(nèi)部資源出錯(cuò)了
503 服務(wù)器正忙
首先要說(shuō)的是,一個(gè)HTTP服務(wù)器可以擁有多個(gè)站點(diǎn),也就是說(shuō):HTTP下可以配置多個(gè)虛擬主機(jī)。當(dāng)用戶訪問(wèn)不同主機(jī)的時(shí)候,實(shí)際上都是訪問(wèn)同一臺(tái)HTTP服務(wù)器。
在客戶端和服務(wù)器中還有一些用于通信數(shù)據(jù)轉(zhuǎn)發(fā)的應(yīng)用程序:
HTTP請(qǐng)求報(bào)文
HTTP請(qǐng)求報(bào)文:在請(qǐng)求中,HTTP報(bào)文由方法、URI、HTTP版本、HTTP首部字段等部分組成。
首部字段例子:
HTTP響應(yīng)報(bào)文
HTTP響應(yīng)報(bào)文:在響應(yīng)中,HTTP報(bào)文由HTTP版本、狀態(tài)碼(數(shù)字和原因短語(yǔ))、HTTP首部字段3部分組成。
狀態(tài)行:
首部字段例子:
對(duì)于HTTP首部這一部分是非常龐大的一個(gè)章節(jié),知識(shí)點(diǎn)也很多,我就沒(méi)有一一去記錄了。用到的時(shí)候再查吧。我看的是《圖解HTTP》。
HTTP在安全上是不足的
我們一般在上網(wǎng)時(shí),使用抓包工具就很容易獲取到HTTP請(qǐng)求的信息了,這是TCP/IP在網(wǎng)絡(luò)通信中無(wú)法避免的。
假設(shè)我們對(duì)HTTP報(bào)文進(jìn)行加密了, 那也僅僅是是內(nèi)容的加密。別人獲取到了HTTP內(nèi)容了,即使無(wú)法破解HTTP內(nèi)容,還是能夠篡改的。
我們最好就是使用SSL建立安全的通信線路,就可以在這條線路上進(jìn)行HTTP通信了。
其實(shí)HTTPS就是披著SSL的HTTP…
HTTPS使用的是共享密鑰和公開(kāi)私有密鑰混合來(lái)進(jìn)行加密的。由于公開(kāi)私有密鑰需要太多的資源,不可能一直以公開(kāi)私有密鑰進(jìn)行通信。因此,HTTP在建立通信線路的時(shí)候使用公開(kāi)私有密鑰,當(dāng)建立完連接后,隨后就使用共享密鑰進(jìn)行加密和解密了
對(duì)于認(rèn)證方面,HTTPS是基于第三方的認(rèn)證機(jī)構(gòu)來(lái)獲取認(rèn)受認(rèn)可的證書(shū)、因此,可以從中認(rèn)證該服務(wù)器是否是合法的。
而客戶端方面則需要自己購(gòu)買(mǎi)認(rèn)證證書(shū)、這實(shí)施起來(lái)難度是很大的【認(rèn)證證書(shū)需要錢(qián)】。
所以,一般的網(wǎng)站都是使用表單認(rèn)證就算了,這是用得最廣泛的客戶端認(rèn)證了。
Java識(shí)堂,一個(gè)高原創(chuàng),高收藏,有干貨的微信公眾號(hào),一起成長(zhǎng),一起進(jìn)步,歡迎關(guān)注
習(xí)Python也有一段時(shí)間了,在學(xué)習(xí)過(guò)程中不斷的練習(xí)學(xué)到的各類知識(shí),做的最多的還是爬蟲(chóng),也就是簡(jiǎn)單的數(shù)據(jù)采集,有采集圖片(這個(gè)最多了。。。),有下載電影的,也有學(xué)習(xí)相關(guān)的比如ppt模板的抓取,當(dāng)然也寫(xiě)過(guò)類似收發(fā)郵件,自動(dòng)登錄論壇發(fā)帖,驗(yàn)證碼相關(guān)操作等等!
這些腳本有一個(gè)共性,都是和web相關(guān)的,總要用到獲取鏈接的一些方法,在此總結(jié)一下,也共享給正在學(xué)習(xí)的小伙伴
python的各個(gè)版本其實(shí)分別并不大,所以不用太糾結(jié)用3.6還是3.7.
而我們經(jīng)常使用的庫(kù)呢,建議大家學(xué)到什么庫(kù)安裝什么庫(kù)
有的同學(xué)會(huì)糾結(jié),庫(kù)安裝不上的問(wèn)題,這個(gè)推薦大家百度搜索:python whl 第一個(gè)就是吧,在里面有各個(gè)庫(kù)的各個(gè)版本,選擇對(duì)應(yīng)的下載回來(lái),用pip install 文件完整路徑 安裝即可!
import requests#導(dǎo)入庫(kù)
html = requests.get(url)#獲取源代碼
適用于靜態(tài)網(wǎng)頁(yè)
大部分的網(wǎng)站(各類中小型網(wǎng)站)都會(huì)需要你的代碼有headers的信息,如果沒(méi)有,會(huì)直接拒絕你的訪問(wèn)!大型網(wǎng)站反而很少,尤其是門(mén)戶網(wǎng)站,比如新浪新聞、頭條圖集、百度圖片的爬蟲(chóng),基本沒(méi)有什么反爬措施,相關(guān)內(nèi)容可以看看我的其他文章!
而有反爬措施的網(wǎng)站,大部分可以按加入U(xiǎn)A信息——加入HOST、Referer(反盜鏈)信息的順序加入到headers數(shù)據(jù)(字典格式)中來(lái)嘗試!代碼格式 requeststs.get(url,headers=headers)
UA信息是瀏覽器信息,告訴對(duì)方服務(wù)器我們是什么瀏覽器,平時(shí)可以收集下相關(guān)信息做個(gè)UA池,需要的時(shí)候調(diào)用就可以,也可以隨機(jī)調(diào)用,防止被網(wǎng)站發(fā)現(xiàn),注意的是如果是移動(dòng)端,一定要注意移動(dòng)端的網(wǎng)頁(yè)和pc端的不一樣,比如做微博爬蟲(chóng),我們就比較喜歡移動(dòng)端,它的反爬力度比pc端的要低很多,也提醒大家,如果一個(gè)網(wǎng)站反爬很厲害,你可以去看看移動(dòng)端(手機(jī)登錄然后復(fù)制url),也許會(huì)有驚喜!
ua信息
HOST信息, 網(wǎng)站的主機(jī)信息,這個(gè)一般是不變的
Referer信息 ,這個(gè)就是“反盜鏈”的關(guān)鍵信息,簡(jiǎn)單的說(shuō),就是你是從哪里到當(dāng)前頁(yè)面的,破解也很簡(jiǎn)單,把url放到里面就行!
如果上述辦法還是繞不過(guò)反爬,那么就麻煩一些,把headers里面的信息都寫(xiě)進(jìn)去吧
終極反“反爬”:去學(xué)習(xí)selenium吧少年!
其實(shí)可以簡(jiǎn)單的分兩大類:字符串內(nèi)容保存和其他內(nèi)容保存!那么簡(jiǎn)單的2中代碼就可以解決
a+為文末追加寫(xiě)入模式,適用于字符串內(nèi)容的寫(xiě)入,注意排版,也可以在'a+'后面添加參數(shù)encoding='utf-8'指定保存文本的編碼格式
wb為二進(jìn)制寫(xiě)入模式,適用于找到對(duì)象的真實(shí)下載地址后用二進(jìn)制方式下載文件
篇幅有限,本來(lái)想寫(xiě)完的,但是有人和我說(shuō),寫(xiě)的太多沒(méi)人看。。。這就很尷尬了!那就先寫(xiě)到這里吧!
也正好有時(shí)間重新整理下后面的內(nèi)容,大概有:自動(dòng)登錄(cookie池)和保持登錄、ip代理、驗(yàn)證碼(這個(gè)是大項(xiàng))以及scarpy框架的一些注意事項(xiàng)。
有其他技巧或者疑問(wèn)的同學(xué),也可以在評(píng)論區(qū)寫(xiě)上,咱們一起討論哦!
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。