自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HTTP代理與SPDY協(xié)議

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
HTTP代理是最經(jīng)典最常見的代理協(xié)議。其用途非常廣泛,普遍見于公司內(nèi)網(wǎng)環(huán)境,一般員工都需要給瀏覽器配置一個(gè)HTTP代理才能訪問互聯(lián)網(wǎng)。起初,HTTP代理也用來翻越“功夫網(wǎng)”,但是因?yàn)椤肮Ψ蚓W(wǎng)”不斷發(fā)展,普通的HTTP代理早已無效了。

HTTP代理是最經(jīng)典最常見的代理協(xié)議。其用途非常廣泛,普遍見于公司內(nèi)網(wǎng)環(huán)境,一般員工都需要給瀏覽器配置一個(gè)HTTP代理才能訪問互聯(lián)網(wǎng)。起初,HTTP代理也用來翻越“功夫網(wǎng)”,但是因?yàn)?ldquo;功夫網(wǎng)”不斷發(fā)展,普通的HTTP代理早已無效了。但是,基于仍然有不少人使用明文的HTTP代理協(xié)議結(jié)合stunnel之類的軟件進(jìn)行加密翻墻,有時(shí)這種代理又被稱為HTTPS代理。

再后來,又出現(xiàn)了WebVpn via SPDY 之類的代理協(xié)議,特點(diǎn)是Chrome瀏覽器直接支持。再加上HTTP代理協(xié)議可以代理什么?是只能代理HTTP還是也可以代理HTTPS,還是可以用來實(shí)現(xiàn)SOCKS代理?總之,非?;靵y。在fqsocks項(xiàng)目里用python實(shí)現(xiàn)了HTTP代理的各種主流變種,終于明白了不同稱謂之后的真正含義。本文試圖總結(jié)一二。

代理基礎(chǔ)

所有的代理,其原理都是類似的。其網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)都是這樣的:

[客戶端] <-TCP連接-> [代理] <-TCP連接-> [服務(wù)器]

代理左手拿著與客戶端的連接,右手拿著與服務(wù)器的連接,然后在兩個(gè)TCP連接之間做數(shù)據(jù)的對(duì)拷。各種不同的代理協(xié)議,不同的只是TCP連接之上跑的是什么的協(xié)議,數(shù)據(jù)是怎么經(jīng)過包裝,拆包的。不存在客戶端與服務(wù)器之間建立TCP連接的情況。只有VPN這種在IP包這一層工作的,才能實(shí)現(xiàn)客戶端與服務(wù)器的之間連接。

HTTP流量,明文的代理連接

這是最簡單的一種HTTP代理。其工作方式是客戶端與代理之間建立的TCP連接是明文的,也就是不經(jīng)過SSL加密的。在TCP連接中傳輸?shù)臄?shù)據(jù)就是明文的HTTP的POST和GET這些。對(duì)于這種代理工作方式,客戶端發(fā)給服務(wù)器的包幾乎不用修改發(fā)給代理,就可以獲得幾乎與服務(wù)器一樣的返回。其收發(fā)包過程如下

[客戶端] -HTTP GET-> [代理] -HTTP GET-> [服務(wù)器]
[客戶端] <-200 OK [代理] <-200 OK [服務(wù)器]

HTTPS流量,明文的代理連接

在這種工作方式中,客戶端與代理之間建立的TCP連接仍然是明文的,也就是不經(jīng)過SSL加密的。但是客戶端發(fā)出的請(qǐng)求不是HTTP請(qǐng)求,而是HTTPS請(qǐng)求。因?yàn)镠TTPS請(qǐng)求是經(jīng)過SSL加密的,所以做為代理來說,雖然客戶端與其建立的TCP連接本身沒有經(jīng)過SSL加密,但是中間傳輸?shù)臄?shù)據(jù)確是SSL加密的。于是代理就無法通過檢查HTTPS請(qǐng)求的內(nèi)容知道目的服務(wù)器是什么。

所以客戶端必須在發(fā)HTTPS請(qǐng)求之前用HTTP CONNECT請(qǐng)求告訴代理要連接的服務(wù)器是什么,然后等代理服務(wù)器左右手的TCP連接都握穩(wěn)了,客戶端就可以收發(fā)HTTPS流量了。代理在其中只是一個(gè)簡單的在兩個(gè)TCP連接中做數(shù)據(jù)對(duì)拷,并不知道客戶端與服務(wù)器在干什么。事實(shí)上,利用HTTP CONNECT,客戶端與服務(wù)器之間除了可以交換HTTPS的流量,任何流量都是可以的。經(jīng)過HTTP CONNECT之后,客戶端與代理的TCP連接就“相當(dāng)于”是與服務(wù)器之間建立的TCP連接。當(dāng)然我們前面已經(jīng)說過了,這種直連只是一個(gè)假象。其收發(fā)包過程如下:

[客戶端] -HTTP CONNECT a.b.c.d:port-> [代理] -TCP SYN-> [服務(wù)器]

[客戶端] <-200 OK- [代理] <-TCP SYN ACK- [服務(wù)器] # 這里的200 OK與下面的200 OK的含義不同

[客戶端] -SSL CLIENT HELLO-> [代理] -SSL CLIENT HELLO-> [服務(wù)器] # SSL握手包1

[客戶端] <-SSL SERVER HELLO- [代理] <-SSL SERVER HELLO/CERTIFICATE等- [服務(wù)器] # SSL握手包2

[客戶端] -SSL CLIENT CERTIFICATE等-> [代理] -SSL CLIENT CERTIFICATE等-> [服務(wù)器] # SSL握手包3

[客戶端] <-SSL SERVER FINISHED- [代理] <-SSL SERVER FINISHED- [服務(wù)器] # SSL握手包4

[客戶端] -SSL加密的HTTP GET-> [代理] -SSL加密的HTTP GET-> [服務(wù)器]

[客戶端] <-SSL加密的200 OK- [代理] <-SSL加密的200 OK- [服務(wù)器]

因?yàn)镃ONNECT之后,這個(gè)左右手的TCP連接里跑什么流量,代理是完全不管的,所以這樣也是可以的:

[客戶端] -HTTP CONNECT a.b.c.d:port-> [代理] -TCP SYN-> [服務(wù)器]

[客戶端] <-200 OK- [代理] <-TCP SYN ACK- [服務(wù)器]

# 這里的200 OK與下面的200 OK的含義不同

[客戶端] -any request-> [代理] -any request-> [服務(wù)器]

[客戶端] <-any response- [代理] <-any response- [服務(wù)器]

正因?yàn)镃ONNECT之后TCP連接可以用來跑任意的東西,當(dāng)然也就可以用來再跑另外一個(gè)代理協(xié)議了,比如SOCKS代理。

只要SOCKS代理是運(yùn)行在443這樣HTTP CONNECT允許的端口,通過HTTP-CONNECT+SOCKS代理就可以在公司內(nèi)網(wǎng)里訪問HTTP之外的互聯(lián)網(wǎng)內(nèi)容了。#p#

HTTP流量,SSL加密的代理連接

傳統(tǒng)HTTP代理,客戶端與代理之間是不經(jīng)過加密的。因?yàn)镚FW可以從明文的流量中知道你通過HTTP代理訪問的目標(biāo)服務(wù)器,所以可以從中切斷連接。為了讓HTTP代理協(xié)議繼續(xù)承擔(dān)翻墻的重任,人們發(fā)明一種新的方式。其拓?fù)浣Y(jié)構(gòu)如下

[客戶端] <-TCP連接-> [Stunnel客戶端模式] <-TCP over SSL連接-> 
[Stunnel服務(wù)器模式] <-TCP連接-> [代理] <-TCP連接-> [服務(wù)器]

雖然拓?fù)浣Y(jié)構(gòu)復(fù)雜了,但是概念其實(shí)是很簡單的。因?yàn)榭蛻舳伺c代理都不直接支持SSL的TCP連接,所以通過Stunnel做一個(gè)轉(zhuǎn)換,在客戶端經(jīng)過Stunnel的客戶端模式進(jìn)行加密,然后在代理上有用Stunnel的服務(wù)器段模式進(jìn)行解密。這樣GFW夾在中間看到的是經(jīng)過SSL加密的流量,無法進(jìn)行URL關(guān)鍵字過濾了。收發(fā)包的過程如下:

[客戶端] -HTTP GET-> [Stunnel客戶端模式] -SSL加密的HTTP GET-> 
[Stunnel服務(wù)器模式] -HTTP GET-> [代理] -HTTP GET-> [服務(wù)器]
[客戶端] <-200 OK- [Stunnel客戶端模式] <-SSL加密的200 OK- 
[Stunnel服務(wù)器模式] <-200 OK- [代理] <-200 OK- [服務(wù)器]

HTTPS流量,SSL加密的代理連接

傳統(tǒng)的HTTP代理走HTTPS流量的時(shí)候,HTTP GET的內(nèi)容經(jīng)過SSL加密的,GFW無法做URL關(guān)鍵字過濾。但是客戶端與代理之間的HTTP CONNECT仍然是明文傳輸?shù)?。GFW仍然可以根據(jù)CONNECT的目標(biāo)域名或者IP地址來判斷是不是訪問了GFW不允許訪問的網(wǎng)站。所以即便客戶端發(fā)的是HTTPS請(qǐng)求,仍然有必要在客戶端與代理之間進(jìn)行SSL加密。拓?fù)浣Y(jié)構(gòu)與上面相同。收發(fā)包的過程如下:

[客戶端] -HTTP CONNECT-> [Stunnel客戶端模式] -SSL加密的HTTP CONNECT->

[Stunnel服務(wù)器模式] -HTTP CONNECT-> [代理] -TCP SYN-> [服務(wù)器]

[客戶端] <-200 OK- [Stunnel客戶端模式] -SSL加密的200 OK-> [Stunnel服務(wù)器模式]

<-200 OK- [代理] <-TCP SYN ACK- [服務(wù)器] # 這里的200 OK與下面的200 OK的含義不同

[客戶端] -SSL CLIENT HELLO-> [Stunnel客戶端模式] -SSL加密的SSL CLIENT HELLO->

[Stunnel服務(wù)器模式] -SSL CLIENT HELLO-> [代理] -SSL CLIENT HELLO-> [服務(wù)器] # SSL握手包1

... 以下略去。完成SSL握手之后,數(shù)據(jù)是在雙層的SSL加密之下傳輸?shù)?/p>

很明顯,HTTP代理加上SSL傳輸?shù)姆绞娇梢杂行У貙?duì)付GFW的關(guān)鍵字檢查。但是蛋疼的地方是本來是客戶端,代理與服務(wù)器之間三方的事情,現(xiàn)在變成了五方會(huì)談了。轉(zhuǎn)手的次數(shù)越多,效率就越差。出錯(cuò)了,調(diào)試問題也越麻煩。除此之外,我們還額可以看到每個(gè)SSL連接建立需要四個(gè)包,兩個(gè)來回。這個(gè)SSL握手的成本不是一次性的,是附加在每個(gè)被代理的連接上的。考慮到很多HTTP請(qǐng)求都是短連接,內(nèi)容也很少。所以每次多做一次SSL握手,額外負(fù)擔(dān)相比之下挺重的。#p#

SPDY

SPDY是Google家提出來的協(xié)議。其核心內(nèi)容是用一個(gè)TCP連接,跑多個(gè)HTTP的STREAM。對(duì)于用SPDY協(xié)議跑HTTP代理來說,其意義就在于之前是每個(gè)HTTP請(qǐng)求都要開連接關(guān)連接,用了SPDY之后,客戶端與代理之間是保持長連接的,然后在這個(gè)連接里,代理訪問不同的HTTP服務(wù)器,就是不同的HTTP STREAM。而且,用SPDY協(xié)議雖然沒有強(qiáng)制但是一般客戶端與代理之間是SSL連接的,所以GFW也無法對(duì)連接的內(nèi)容做關(guān)鍵字過濾。相比Stunnel的方案,省去了每個(gè)連接額外的SSL過程,而且也省去了每個(gè)HTTP請(qǐng)求額外的TCP握手過程。所以從執(zhí)行效率的角度來看,SPDY是非常理想的。

以一個(gè)最簡單的HTTP GET為例SPDY的交互過程是這樣的:

[客戶端] -SSL CLIENT HELLLO-> [服務(wù)器]
[客戶端] <-SSL SERVER HELLO/CERTIFICATE/NPN (HTTP/1.1, SPDY/3, SPDY/2)等 
[服務(wù)器] # 服務(wù)器通過SSL的NPN擴(kuò)展告訴客戶端我這支持HTTP 1.1也支持SPDY 2和3
[客戶端] -SSL CLIENT CERTIFICATE/NPN(SPDY/3)等-> [服務(wù)器] # 客戶端告訴服務(wù)器我選擇SPDY3
[客戶端] <-SSL SERVER FINISHED- [服務(wù)器] # SSL握手完成
[客戶端] -SSL加密的SYN FRAME(HTTP GET)-> [服務(wù)器] 
# SYN FRAME是SPDY版的HTTP GET,意思是一樣的
[客戶端] <-SSL加密的SYN REPLY FRAME(200 OK)- [服務(wù)器]
 # SYN REPLAY FRAME是SPDY版的200 OK,意思是一樣的

這里與最傳統(tǒng)的HTTP GET過程的不同是:

經(jīng)過了SSL加密,客戶端與服務(wù)器直接處理了SSL的加解密而不是經(jīng)過Stunnel轉(zhuǎn)手

SSL除了用來加密其NPN(Next Protocol Negotiation)擴(kuò)展還用來溝通協(xié)議,所以同樣一個(gè)443端口可以同時(shí)用來支持傳統(tǒng)的HTTPS和新的SPDY協(xié)議

同一個(gè)SSL加密連接可以同時(shí)用來做多個(gè)HTTP GET,因?yàn)镾YN FRAME與SYN REPLY FRAME的對(duì)應(yīng)關(guān)系是通過Stream Id來完成的。而一個(gè)SSL連接中可以同時(shí)有多個(gè)Stream。

但是直接支持SPDY協(xié)議的服務(wù)器并不多,大部分都是Google自家的服務(wù)器。所以寄期望于所有的服務(wù)器都運(yùn)行SPDY協(xié)議,從而GFW無法進(jìn)行關(guān)鍵字檢測是不現(xiàn)實(shí),比寄期望與所有服務(wù)器都部署HTTPS還要不現(xiàn)實(shí)。單就反GFW關(guān)鍵字過濾來說,服務(wù)器支持HTTPS與SPDY并無區(qū)別。#p#

HTTP流量,SPDY的代理連接

有了SPDY協(xié)議,客戶端與代理之間就又多了一種選擇,除了明文的不加密的傳統(tǒng)的HTTP,和效率低下的Stunnel模式,還可以用Shrpx+Squid跑SPDY協(xié)議。其過程是這樣的

[客戶端] -SSL CLIENT HELLLO-> [代理]
[客戶端] <-SSL SERVER HELLO/CERTIFICATE/NPN (HTTP/1.1, SPDY/3, SPDY/2)等 [代理]
[客戶端] -SSL CLIENT CERTIFICATE/NPN(SPDY/3)等-> [代理]
[客戶端] <-SSL SERVER FINISHED- [代理]
 # 與代理建立好SSL連接,通過NPN選擇了選擇SPDY3協(xié)議
[客戶端] -SSL加密的SYN FRAME(Stream1 HTTP GET)-> [代理] -HTTP GET-> [服務(wù)器1]
[客戶端] -SSL加密的SYN FRAME(Stream2 HTTP GET)-> [代理] -HTTP GET-> [服務(wù)器2]
[客戶端] <-SSL加密的SYN REPLY FRAME(Stream2 200 OK)- [代理] <-200 OK- [服務(wù)器2]
[客戶端] <-SSL加密的SYN REPLY FRAME(Stream1 200 OK)- [代理] <-200 OK- [服務(wù)器1]

可見利用SPDY協(xié)議,客戶端與代理之間的數(shù)據(jù)傳輸就是SSL加密的,而且避免了每個(gè)HTTP請(qǐng)求都建立新的TCP連接,重新進(jìn)行SSL握手。而代理與服務(wù)器因?yàn)槎荚趬ν?,所以HTTP明文交流并沒有任何問題。

HTTPS流量,SPDY的代理連接

SPDY協(xié)議的SYN FRAME除了支持HTTP GET/POST這些之外,HTTP CONNECT也是可以的。除了需要包裝成SPDY的各種FRAME之外,HTTP協(xié)議自身的語義其實(shí)都是一樣的。其交互過程是這樣的:

客戶端] -SSL CLIENT HELLLO-> [代理]
[客戶端] <-SSL SERVER HELLO/CERTIFICATE/NPN (HTTP/1.1, SPDY/3, SPDY/2)等 [代理]
[客戶端] -SSL CLIENT CERTIFICATE/NPN(SPDY/3)等-> [代理]
[客戶端] <-SSL SERVER FINISHED- [代理]
 # 與代理建立好SSL連接,通過NPN選擇了選擇SPDY3協(xié)議
[客戶端] -SSL加密的SYN FRAME(HTTP CONNECT)-> [代理] -TCP SYN-> [服務(wù)器]
[客戶端] <-SSL加密的SYN REPLY FRAME(200 OK)- [代理] <-TCP SYN ACK- [服務(wù)器]
[客戶端] -SSL加密的DATA FRAME(HTTP GET)-> [代理] -HTTP GET-> [服務(wù)器]
[客戶端] <-SSL加密的DATA FRAME(200 OK)- [代理] -200 OK-> [服務(wù)器]

完成了HTTP CONNECT之后,對(duì)應(yīng)的SPDY STREAM就是自由的了。無論發(fā)送什么樣的DATA FRAME(SPDY的FRAME的一種,傳輸二進(jìn)制數(shù)據(jù)流)給代理,代理就直接轉(zhuǎn)給服務(wù)器。服務(wù)器無論返回什么樣的數(shù)據(jù),代理也以DATA FRAME的形式轉(zhuǎn)給客戶端。這個(gè)SPDY STREAM和一個(gè)TCP連接就一樣了。除了可以用來發(fā)HTTP GET之外,跑什么樣的協(xié)議都行了,代理反正也不管里面是什么,它只管轉(zhuǎn)發(fā)DATA FRAME。#p#

PAC文件

HTTP代理的一個(gè)流行用法是寫一個(gè)PAC文件,描述什么樣的時(shí)候走什么樣的代理。經(jīng)典的PAC文件只有兩種返回值,PROXY和DIRECT。如果返回的是PROXY則走代理,DIRECT則是直連。這里的走代理當(dāng)然是最傳統(tǒng)的HTTP代理方式,也就是瀏覽器與代理之間是明文的連接,不經(jīng)過SSL加密的。具體瀏覽器是用HTTP GET/POST還是CONNECT,取決于瀏覽器要訪問的目標(biāo)服務(wù)器是HTTP還是HTTPS的,和PAC文件無關(guān)。

Chrome在PAC的PROXY與DIRECT之外添加了第三種返回值,也就是HTTPS。這種返回值的含義與PROXY是一樣,都是走代理。區(qū)別在于PROXY是明文的連接,HTTPS是SSL加密的連接。所以HTTPS這個(gè)返回值的歧義在于讓人以為它只用來代理HTTPS流量。因?yàn)镾PDY是基于SSL的NPN擴(kuò)展的,所以當(dāng)瀏覽器與代理進(jìn)行SSL握手的時(shí)候,可以選擇是用HTTP/1.1協(xié)議還是SPDY/2還是SPDY/3。于是HTTPS這個(gè)PAC返回值,還可以用來支持SPDY,前提當(dāng)然是代理在NPN里說它支持SPDY,而且瀏覽器也知道SSL的NPN擴(kuò)展,而且支持SPDY協(xié)議。

另外一個(gè)PAC的擴(kuò)展是蘋果給iOS的PAC文件添加的SOCKS返回值。利用這個(gè)返回值可以給iPhone配置SOCKS的全局代理。但是這個(gè)與本文討論的HTTP代理就無關(guān)了。

總結(jié)

可見HTTP代理協(xié)議自身來說,就兩種:HTTP GET/POST和HTTP CONNECT。一種用來代理HTTP的流量,另外一種用來代理HTTPS的流量。HTTP CONNECT除了可以用來走HTTPS之外,因?yàn)榇聿⒉蝗ソ馕銎鋬?nèi)容,所以事實(shí)上是一個(gè)通用的代理隧道。

另外一個(gè)維度是客戶端與代理之間是一個(gè)什么樣的連接:不加密的連接,SSL加密的連接,SSL加密同時(shí)運(yùn)行SPDY協(xié)議的連接。

所以工作模式共有2*3=6種。

責(zé)任編輯:藍(lán)雨淚 來源: fqrouter
相關(guān)推薦

2014-10-22 09:36:41

TCPIP

2012-07-16 09:58:15

SPDY協(xié)議HTTP

2014-01-09 10:07:27

SPDY編譯nginx

2019-08-23 06:36:32

2014-11-13 10:57:03

http協(xié)議

2015-02-05 09:25:51

HTTPSSPDYHTTP2

2015-09-29 14:01:45

SPDY網(wǎng)絡(luò)協(xié)議響應(yīng)頭網(wǎng)絡(luò)協(xié)議

2018-11-14 15:00:08

HTTP程序員前端

2015-02-13 10:34:28

HTTP.2GoogleSPDY

2019-04-22 11:38:00

HTTPHTTP2.0HTTPS

2019-04-23 10:48:55

HTTPTomcat服務(wù)器

2010-05-24 17:59:11

SNMP協(xié)議

2009-02-12 15:33:00

代理服務(wù)器HTTPSOCKS

2017-05-26 10:35:13

前端HTTP

2021-05-07 09:17:21

HTTPTCP協(xié)議

2011-04-12 10:00:41

SPDYSPDY協(xié)議

2016-11-08 09:04:20

ChromeHTTP網(wǎng)站

2015-03-03 13:47:34

HttpTCPIP

2016-08-05 13:19:29

GET請(qǐng)求github項(xiàng)目 POST請(qǐng)求

2020-08-07 10:20:01

HTTP3Web
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)