上一篇學習了Web伺服器,這一篇我來學習一下代理的知識。現在的網絡中存在着各種各樣的代理。學習Web代理伺服器,更有利于我們隊網絡請求過程的了解。
簡介
代理伺服器是網絡的中間實體,其既是Web伺服器,也是Web用戶端。是以其必須要能正确處理用戶端的請求,并傳回響應,同時也要能正确的向伺服器發起請求并接收響應。
1.1 私有和共享代理
代理伺服器可以作為某個用戶端單獨使用的私有代理,也可以作為衆多用戶端共有的代理伺服器——即公共代理。
實際當中,公共代理更為常見,它是一種集中式代理。比如緩存代理,我們可以将某一個區域的緩存放入一個代理伺服器中,那這個區域任何用戶端都能利用同一個緩存代理
私有代理,相對來比較少見,一般都是使用者自行有某些特殊需求的時候,專門為用戶端配置代理伺服器。
1.2 代理與網關
代理與網關都是網絡中的中間實體,雖然看起來作用相似。但是他們有一點差別就是:代理連接配接的一般是用的同一種協定應用程式。而網關一般是用于連接配接不同協定的應用程式。如下圖就展示了代理與網關的差別:

上圖a中,Web代理與用戶端和伺服器之間的傳輸協定都是用的HTTP協定。圖b的網關,與用戶端使用的是HTTP協定,與伺服器端則采用的是POP協定。其作用是讓客戶可以在浏覽器上用HTTP協定進行收發郵件了。
2 代理的用途
用戶端和伺服器端直接通信相較于通過代理的時間,理論上來說應該更短,為什麼還需要在中間加一個代理呢?這就不得不說代理的用途,或者說給我們帶來的好處。
-
内容過濾器
通過代理,我們可以對網絡上的資源進行過濾,某些不合适用戶端的資源,我們可以将其過濾掉。比如對于小孩而言,我們可以通過代理将網絡上的成人内容進行過濾,或者對于在校學生而言,我們可以過濾掉那些和學習無關的内容,讓學生專注于學習的内容。
-
通路權限控制
這種用途在一些企業的裡面非常常見,通過對通路控制的政策進行配置,達到控制員工的越級通路。比如:銷售部的員工,不應該查詢公司保密财務資料和,這個時候我們可以通過代理,對發起請求的使用者進行判斷,如果需要通路保密财務資料,就需要密碼之類的指令,否則阻止其對越級資源的通路,如下圖所示:
Http權威指南筆記(六)——代理簡介2 代理的用途3 代理的層次及結構4 追蹤封包5 代理認證6 代理的互操作性7 代理的一些其他問題 -
安全防火牆
網絡安全工程師通常會使用代理伺服器來提高安全性。代理伺服器會在網絡中的單一安全節點上限制哪些應用層協定的資料可以流入或流出一個組織。還可以提供用來消除病毒的 Web 和 E-mail 代理使用的那種挂鈎程式
-
Web緩存
根據需要,我們可以在代理伺服器上緩存某些資源的副本,用戶端在擷取資源的時候,就能夠直接在代理伺服器中擷取,而無需連接配接最終目的Web伺服器,既可以減少Web伺服器的并發量,也能節約帶寬資源。
-
反向代理
代理可以假扮Web伺服器與用戶端進行通信,這種代理通常被稱為反向代理。他們代理伺服器來接收用戶端的真實請求,然後根據需要,将請求定位到所需要的伺服器資源。這種代理可以提高通路慢速Web伺服器時候的性能(即一個加速器的作用),同時也可以達到負載均衡的目的。當一個請求來到的時候,可以根據目前所有伺服器的負載情況,将請求給負載相對較低的伺服器進行處理。
-
内容路由器
對這一用途不是非常了解,目前了解就是可以将使用者分級,如:普通,付費,VIP等。然後根據不同的使用者,提供不同的内容,示例圖如下:
Http權威指南筆記(六)——代理簡介2 代理的用途3 代理的層次及結構4 追蹤封包5 代理認證6 代理的互操作性7 代理的一些其他問題 -
轉碼器
代理伺服器在将内容發送給用戶端之前,可以修改内容的主體格式。在這些資料表示法之間進行的透明轉換被稱為轉碼(transcoding)。如:傳輸圖檔或者文檔的時候,可以先對其進行壓縮,然後再進行傳輸。
-
匿名代理
匿名代理的主要目的在于保護隐私,它會主動的從HTTP封包中書删除一些和使用者身份資訊相關的東西,如用戶端 IP 位址、From 首部、Referer 首部、cookie、URI 的會話 ID。
3 代理的層次及結構
3.1 代理的部署位置
根據代理的目的不同,可以将代理部署在不同的地方,常見的如下圖所示:
圖a中的代理,部署在LAN的出口處的局部私有代理,由其統一代理和管理本地用戶端發起的請求。這樣可以就本地用戶端發起請求進行管理。如:很多企業會使用該種方式,管理者工日常工作中的網絡通路,一些不允許通路的位址就會被攔截和過濾。
圖b中的代理,一般被稱為通路代理,這種代理在IPS提供商會經常用到,可以集中處理用戶端的請求,同時可以作為緩存代理,将一些經常使用的資源進行緩存,讓使用者可以高速通路資源,同時節約帶寬資源。
圖c中的就是常說的反向代理,這個前面已經介紹過了,這裡不摘贅述。
圖d一般被稱為網絡交換器,放在真正的英特網交換節點中間,也是可以通過緩存來實作減少英特網節點之間的擁堵,同時也能實作對流量進行監控。
3.2 代理的層次結構
所謂的代理層級結構,即代理互相之間的關系。在關系當中涉及到父代理和子代理兩個概念。這兩個概念是同時成對出現,是一種相對的概念。父代理是指更靠近伺服器端的代理,相對的子代理即更靠近用戶端的代理。以下圖為例:
代理2為代理1的父代理,代理3位代理2的父代理,代理2稱為代理3的子代理,代理1稱為代理2的子代理。
在實際當中,一般代理的層次結構并非是禁止不變的,根據請求的不同,可能代理會選擇将請求轉發給不同的下級代理,甚至直接轉發給原始Web伺服器。實際當中,常見的動态代理情景有如下幾個:
- 負載均衡——代理會根據目前它的下一級代理的負載情況,來決定将目前請求轉發給哪個父代理,以便達到負載均衡的目的。
- 地理位置附件路由——代理會根據目前地理位置和請求的情況,選擇不同地方的父代理。
- 協定/類型路由——根據商定的協定或者URI來決定将目前請求轉發到哪個父代理上。
- 基于訂購的路由——也就是常見的如果是付費使用者,就将轉發到高速緩存伺服器,如果是普通使用者,就轉發到一般的Web伺服器。這樣就能提高付費使用者的體驗性能。
3.3 如何将請求流行代理
- 修改用戶端配置——可以直接修改用戶端(如浏覽器)的配置,讓其請求發送到我們制定的代理上。
- 修改網絡——這種一般是網絡服務提供商進行的操作,這些服務商對網絡交換和路由裝置進行監視,再需要的時候,對請求進行攔截轉發。一般對使用者而言是透明的。使用者感覺不到請求被發送到代理了。
- 修改DNS命名空間——通過對DNS的命名空間進行修改,讓代理假扮伺服器的角色。這樣用戶端發送給Web伺服器的請求就會被發送到代理。如日常使用的反向代理,用戶端正常發送的請求會先被發送到方向代理,然後再由其真正給到Web伺服器。
- Web伺服器的配置——通過對Web伺服器進行修改和配置,将一些請求通過重定向的方式轉發到代理伺服器上。
4 追蹤封包
現在将請求從用戶端發送到服務端的路徑上通過多個代理的轉發是很常見的。有時候當出現問題的時候,我們需要跟蹤整個請求路徑上封包的轉發流程,本節就是介紹怎麼去跟蹤代理轉發的封包。
4.1 Via首部
HTTP規範指定了如果有Via首部,封包每經過一個節點,都需要将該節點添加到Via清單的末尾。通過Via首部,我們可以記錄封包轉發,診斷封包的循環等問題。
-
Via的文法
每個 Via 路标中最多包含 4 個元件:一個可選的協定名(預設為 HTTP)、一個必選的協定版本、一個必選的節點名和一個可選的描述性注釋。其文法格式如下:
Via = "Via" ":" 1#( waypoint )
waypoint = ( received-protocol received-by [ comment ] )
received-protocol = [ protocol-name "/" ] protocol-version
received-by = ( host [ ":" port ] ) | pseudonym
其中:
協定名:預設為HTTP,如果是HTTP可以省略,如果不是,則必須加上
協定版本:這個字段的格式和協定有關,如HTTP協定的就是 1.0,1.1等
節點名:主機名加端口号。端口号如果省略,則人為是該協定的預設端口号,主機名不一定是真實的。
節點注釋:用于對節點的注釋說明,可以省略。
如下面的Via首部:
Via = 1.1 cache.joes-hardware.com, 1.1 proxy.irenes-isp.net
說明有兩個代理,第一個代理是 HTTP協定的1.1版本,節點為
cache.joes-hardware.com
,第二個代理也是HTTP協定的1.1版本,節點名稱為
proxy.irenes-isp.net
-
Via的請求和響應路徑
請求和響應封包都會經過代理進行傳輸,是以,請求和響應封包中都要有 Via 首部。
請求和響應通常都是通過同一條 TCP 連接配接傳送的,是以響應封包會沿着與請求封包相同的路徑回傳。如果一條請求封包經過了代理 A、B 和 C,相應的響應封包就會通過代理 C、B、A 進行傳輸。是以,響應的 Via 首部基本上總是與請求的 Via 首部相反
-
Via與網關
有些代理會為使用非 HTTP 協定的伺服器提供網關的功能。Via 首部記錄了這些協定轉換,這樣,HTTP 應用程式就會了解代理鍊上各點的協定處理能力以及所做的協定轉換了
-
Server與Via首部
Server首部是用于對原始伺服器的描述,如:
Server: Apache/1.3.14 (Unix) PHP/4.0.4
Server: Netscape-Enterprise/4.1
Server: Microsoft-IIS/5.0
Server首部不能用于代理,代理不應該對該首部首部進行修改,代理隻需要添加Via即可。
-
Via和隐私、安全問題
如果出于隐私或者安全考慮,不想提供主機名和端口号等資訊。可以使用一個假的節點資訊,但是必須要有節點資訊。同時如果是同一組織下的同一協定,且同一版本,可以将多個節點合并為一個節點。但是前提是同一組織,同一協定,同一協定版本。任何一個不同都不能進行合并。
4.2 TRACE方法
通過 HTTP/1.1 的 TRACE 方法,使用者可以跟蹤經代理鍊傳輸的請求封包,觀察封包經過了哪些代理,以及每個代理是如何對請求封包進行修改的。TRACE 對代理流的調試非常有用。當然,前提是要伺服器支援TRACE方法。
如下所示,展示了TRACE方法請求響應過程:
從圖中可以看到,TRACE的處理過程為:當TRACE請求到達伺服器後,如果伺服器支援該方法,會将完整的請求封包封裝為響應體,然後傳回給用戶端。響應頭中的Content-type的值為:message/http。用戶端收到該響應後,就能通過響應體中的資料知道請求封包最終被修改後的内容。
一般情況下,TRACE的請求會沿着整條路徑一路轉發,最終達到原始伺服器。但是如果請求體中包含Max-forward,那轉發次數就會被限制在該首部規定的值以内。工作原理是,沒經過一次轉發,就會将Max-forward的值-1,當其值為0的時候,就證明達到了最大限制,這個時候無論是否達到最終伺服器,都應該結束該條請求繼續轉發,并傳回響應。
5 代理認證
代理可以作為通路控制裝置使用。HTTP 定義了一種名為代理認證(proxy authentication)的機制,這種機制可以阻止對内容的請求,直到使用者向代理提供了有效的通路權限證書為止。
其工作流程如下:
- 當一個受限通路的請求達到代理時,代理檢查該通路是否有權限,如果沒有,會傳回一個407狀态碼和Proxy Authorization Required的資訊,告知用戶端需要使用證書。同時可以包含一個怎麼擷取該證書的描述資訊。
- 用戶端收到該響應後,會根據提示嘗試獲驗證書,或者提示使用者提供證書
- 用戶端獲得證書後,會再次發送請求,這次會在請求頭中添加Proxy-Authorization字段來提供證書
- 伺服器收到請求,會判斷證書是否有效,有效則繼續後面的流程,否則回到1的情況。
6 代理的互操作性
由于用戶端,代理、伺服器都是由不同的廠商進行提供。那就意味着它們之間或多或少存在一些差異。某些首部字段,可能代理支援,但是伺服器不支援,又或者一些請求方法,伺服器支援,代理不支援。為了更好的系統工作,一般采用如下的原則進行處理。
- 當代理遇到自己不能處理的首部字段的時候,一般應該将其進行轉發,并且保持原有的順序,同樣,如果代理對某個方法無法處理,其應該嘗試将封包轉發到下一級節點。
-
通過OPTIONS方法,用于判斷伺服器所支援的特性,這樣在請求前知道了伺服器所支援的特性,就能更好的同不同代理和伺服器之間進行互操作了
OPTIONS請求的URI如果是一個”*“号,請求的就是整個伺服器所支援的功能,如果請求的URI是某個具體的資源,就是查詢指定資源支援的功能。如果OPTIONS請求成功,會傳回一個200 OK的響應。其有一個Allow首部字段,其值會列出所有支援的請求方法。如:
Allow: GET, HEAD, PUT
7 代理的一些其他問題
7.1 代理的URI和伺服器URI的差別
用戶端向代理和伺服器發送請求的時候,URI是有差別的。如果是向伺服器發送請求,URI一般不會包含shceme,host和port,如:
GET /index.html HTTP/1.0
User-Agent: SuperBrowser v1.3
如果是向代理發起請求,就會包含完整的URI路徑,如:
GET http://www.marys-antiques.com/index.html HTTP/1.0
User-Agent: SuperBrowser v1.3
之是以出現上述的差別,是因為,最初沒有代理的時候,用戶端發送的請求都是給最終伺服器的,伺服器是知道自己的主機名和端口等資訊的,是以為了減少備援資訊,發送部分URI就可以了。但是代理出現以後,代理可能并不是針對某單個伺服器的,這個時候嗎,如果沒有完整的URI路徑,代理就無法知道将該請求發往哪個下一級節點。
但是我們用戶端并不一定都顯式的知道請求是發文代理還是伺服器的,這個時候采用如下原則:
- 沒有顯示設定代理的用戶端,會發送部分URI;
- 明确設定了代理,或者用戶端明确知道自己将要發送給代理的時候,發送完整的URI
到這裡還需要提到的一點是,上述提到的問題,即除了URI中的路徑部分外,還需要确定主機名。除了代理會遇到這個問題,前面章節提到的虛拟Web伺服器也會遇到相同的問題,但是解決方式是不同,代理同時是要求直接使用完整的URI,Web虛拟主機是需要Host請求頭來提供主機和端口資訊。
7.2 攔截代理的URI處理
上一小節提到了,用戶端在知道是發送給代理的時候,是發送完整的URI,但是像一些攔截作用的代理,用戶端一般是不知道請求是發給代理的,這個時候,用戶端預設隻會發送部分URI。這個時候,攔截代理怎麼處理請求呢?這個時候就要求我們的代理要具有處理部分URI的能力。一般代理的處理原則如下:
- 如果提供了完的URI,則使用完整的URI
- 如果提供了部分URI,但是有Host請求頭,應該使用Host的值來确定主機名和端口資訊
- 如果提供了部分URI,且沒有Host請求頭,按照下面的方式處理:如果代理是反向代理一類的代理,可以用真實伺服器的位址和端口号來配置代理;如果是攔截代理一類的代理,一般攔截者本身是可以提供真實主機位址和端口資訊的
- 如果代理最終都無法獲得真實的主機位址和端口号等必要資訊,就必須傳回一條錯誤封包給用戶端,讓其提供Host請求頭
最後除了上述提到的問題外,另外一個代理還需要注意的問題是,對URI的修改問題。有時候可能用戶端提供的URI并不一定非正常範,這個時候代理檢查到問題後,需要做的是能夠識别出URI,就進行轉發或者處理該請求,不行就傳回錯誤資訊,不要嘗試去修正URI。雖然修正URI出發點是好的,但是可能會造成一些其他問題。