久久狠狠高潮亚洲精品

  • <span id="jeggp"><pre id="jeggp"><rt id="jeggp"></rt></pre></span>

  • <dd id="jeggp"></dd>
      <rp id="jeggp"><object id="jeggp"><blockquote id="jeggp"></blockquote></object></rp>

        網絡應用知識 News

        HTTP代理與SPDY協議

        來源:本站 作者:管理員 日期:2013-07-16 17:39

        HTTP代理是最經典最常見的代理協議。其用途非常廣泛,普遍見于公司內網環境,一般員工都需要給瀏覽器配置一個HTTP代理才能訪問互聯網。起初,HTTP代理也用來翻越“功夫網”,但是因為“功夫網”不斷發展,普通的HTTP代理早已無效了。但是,基于仍然有不少人使用明文的HTTP代理協議結合stunnel之類的軟件進行加密翻墻,有時這種代理又被稱為HTTPS代理。

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

        代理基礎

        所有的代理,其原理都是類似的。其網絡拓撲結構都是這樣的:

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

        代理左手拿著與客戶端的連接,右手拿著與服務器的連接,然后在兩個TCP連接之間做數據的對拷。各種不同的代理協議,不同的只是TCP連接之上跑的是什么的協議,數據是怎么經過包裝,拆包的。不存在客戶端與服務器之間建立TCP連接的情況。只有VPN這種在IP包這一層工作的,才能實現客戶端與服務器的之間連接。

        HTTP流量,明文的代理連接

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

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

        HTTPS流量,明文的代理連接

        在這種工作方式中,客戶端與代理之間建立的TCP連接仍然是明文的,也就是不經過SSL加密的。但是客戶端發出的請求不是HTTP請求,而是HTTPS請求。因為HTTPS請求是經過SSL加密的,所以做為代理來說,雖然客戶端與其建立的TCP連接本身沒有經過SSL加密,但是中間傳輸的數據確是SSL加密的。于是代理就無法通過檢查HTTPS請求的內容知道目的服務器是什么。

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

        
        

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

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

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

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

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

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

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

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

        因為CONNECT之后,這個左右手的TCP連接里跑什么流量,代理是完全不管的,所以這樣也是可以的:

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

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

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

        [客戶端] -any request-> [代理] -any request-> [服務器]

        [客戶端] <-any response- [代理] <-any response- [服務器]

        正因為CONNECT之后TCP連接可以用來跑任意的東西,當然也就可以用來再跑另外一個代理協議了,比如SOCKS代理。

        只要SOCKS代理是運行在443這樣HTTP CONNECT允許的端口,通過HTTP-CONNECT+SOCKS代理就可以在公司內網里訪問HTTP之外的互聯網內容了。


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

        傳統HTTP代理,客戶端與代理之間是不經過加密的。因為GFW可以從明文的流量中知道你通過HTTP代理訪問的目標服務器,所以可以從中切斷連接。為了讓HTTP代理協議繼續承擔翻墻的重任,人們發明一種新的方式。其拓撲結構如下

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

        雖然拓撲結構復雜了,但是概念其實是很簡單的。因為客戶端與代理都不直接支持SSL的TCP連接,所以通過Stunnel做一個轉換,在客戶端經過Stunnel的客戶端模式進行加密,然后在代理上有用Stunnel的服務器段模式進行解密。這樣GFW夾在中間看到的是經過SSL加密的流量,無法進行URL關鍵字過濾了。收發包的過程如下:

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

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

        傳統的HTTP代理走HTTPS流量的時候,HTTP GET的內容經過SSL加密的,GFW無法做URL關鍵字過濾。但是客戶端與代理之間的HTTP CONNECT仍然是明文傳輸的。GFW仍然可以根據CONNECT的目標域名或者IP地址來判斷是不是訪問了GFW不允許訪問的網站。所以即便客戶端發的是HTTPS請求,仍然有必要在客戶端與代理之間進行SSL加密。拓撲結構與上面相同。收發包的過程如下:

        
        

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

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

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

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

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

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

        ... 以下略去。完成SSL握手之后,數據是在雙層的SSL加密之下傳輸的

        很明顯,HTTP代理加上SSL傳輸的方式可以有效地對付GFW的關鍵字檢查。但是蛋疼的地方是本來是客戶端,代理與服務器之間三方的事情,現在變成了五方會談了。轉手的次數越多,效率就越差。出錯了,調試問題也越麻煩。除此之外,我們還額可以看到每個SSL連接建立需要四個包,兩個來回。這個SSL握手的成本不是一次性的,是附加在每個被代理的連接上的?紤]到很多HTTP請求都是短連接,內容也很少。所以每次多做一次SSL握手,額外負擔相比之下挺重的。


        SPDY

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

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

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

        這里與最傳統的HTTP GET過程的不同是:

        經過了SSL加密,客戶端與服務器直接處理了SSL的加解密而不是經過Stunnel轉手

        SSL除了用來加密其NPN(Next Protocol Negotiation)擴展還用來溝通協議,所以同樣一個443端口可以同時用來支持傳統的HTTPS和新的SPDY協議

        同一個SSL加密連接可以同時用來做多個HTTP GET,因為SYN FRAME與SYN REPLY FRAME的對應關系是通過Stream Id來完成的。而一個SSL連接中可以同時有多個Stream。

        但是直接支持SPDY協議的服務器并不多,大部分都是Google自家的服務器。所以寄期望于所有的服務器都運行SPDY協議,從而GFW無法進行關鍵字檢測是不現實,比寄期望與所有服務器都部署HTTPS還要不現實。單就反GFW關鍵字過濾來說,服務器支持HTTPS與SPDY并無區別。


        HTTP流量,SPDY的代理連接

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

        [客戶端] -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協議
        [客戶端] -SSL加密的SYN FRAME(Stream1 HTTP GET)-> [代理] -HTTP GET-> [服務器1]
        [客戶端] -SSL加密的SYN FRAME(Stream2 HTTP GET)-> [代理] -HTTP GET-> [服務器2]
        [客戶端] <-SSL加密的SYN REPLY FRAME(Stream2 200 OK)- [代理] <-200 OK- [服務器2]
        [客戶端] <-SSL加密的SYN REPLY FRAME(Stream1 200 OK)- [代理] <-200 OK- [服務器1]

        可見利用SPDY協議,客戶端與代理之間的數據傳輸就是SSL加密的,而且避免了每個HTTP請求都建立新的TCP連接,重新進行SSL握手。而代理與服務器因為都在墻外,所以HTTP明文交流并沒有任何問題。

        HTTPS流量,SPDY的代理連接

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

        客戶端] -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協議
        [客戶端] -SSL加密的SYN FRAME(HTTP CONNECT)-> [代理] -TCP SYN-> [服務器]
        [客戶端] <-SSL加密的SYN REPLY FRAME(200 OK)- [代理] <-TCP SYN ACK- [服務器]
        [客戶端] -SSL加密的DATA FRAME(HTTP GET)-> [代理] -HTTP GET-> [服務器]
        [客戶端] <-SSL加密的DATA FRAME(200 OK)- [代理] -200 OK-> [服務器]

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


        PAC文件

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

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

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

        總結

        可見HTTP代理協議自身來說,就兩種:HTTP GET/POST和HTTP CONNECT。一種用來代理HTTP的流量,另外一種用來代理HTTPS的流量。HTTP CONNECT除了可以用來走HTTPS之外,因為代理并不去解析其內容,所以事實上是一個通用的代理隧道。

        另外一個維度是客戶端與代理之間是一個什么樣的連接:不加密的連接,SSL加密的連接,SSL加密同時運行SPDY協議的連接。

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



        上一篇:基于計算機實現通信軟交換機的數據備份
        下一篇:BGP網絡性能優化淺析
        久久狠狠高潮亚洲精品