HTTP

HTTP 代理 (proxy)、隧道 (tunnel) 與 閘道 (gateway)

HTTP 允許使用 中介 (Intermediary):
以 連接鏈 (chain of connection) 來滿足請求。
其中,三種常見的 中介: 代理 (proxy)、隧道 (tunnel) 與 閘道 (gateway)。
 

中介 (Intermediaries) 示意圖
中介 (Intermediaries) 示意圖

 
中介 (Intermediary) 或稱 中間人,
可能用於提升性能、可用性,或是 存取控制 與 內容過濾…。
 
正常情況下,HTTP 的請求、回應訊息,
將經歷 連接鍊 (chain of connection) 中的連線,
最終抵達 使用者代理 (User Agent) 或 源伺服器 (Origin Server)。
 
從圖中可知,連接鍊 不一定線性 (linear) 的!
每個 HTTP 參與者,皆可能同時進行多個通訊。
 


 

代理 (Proxy)

代理 (proxy),通常是 Client 透過一些本機設定、規則,
所選擇的 訊息轉發 (message-forwarding) 中間人。
 
用於接收一些 絕對 URI (absolute URI) 類型的請求,
並嘗試以 HTTP 介面 轉譯、滿足這些請求 (i.e., 更動訊息內容)。
 
例如,代理 (proxy) 為了節省快取空間 或 減少在慢速連線上的流量,
可能在酬載格式之間進行轉換 (e.g., PNG 轉 JPG、1280×1024 轉 640×480)。
這種根據語義來修改訊息的 HTTP-to-HTTP 的代理,則稱為 轉換代理 (transforming proxy)
 
 
proxy
 
 

功能

代理 (proxy) 用途非常廣泛 (e.g., 防火牆Debug、共享快取、企業網路存取),
也可能做為 兩個不同應用層協議的「翻譯者」…,
因此, 源伺服器 (Origin Server) 可能並非「HTTP」協議 (e.g., FTP)。
 
就像 老闆 (User Agent) 給予 員工 (proxy) 任務,
員工 (proxy) 依任務內容 去 商店 (Origin Server) 購物,
過程中,員工 (proxy) 可能 改變/增加 任意一方的訊息內容:
proxy-2

Material from Freepik
 
 

權威回應 vs. 非權威回應

從圖中可知:
員工 (proxy),對 老闆 (User Agent) 來說是「服務者 (server)」,
而對 商店 (Origin Server) 來說是「顧客 (client)」。
 
這也是為何 HTTP 得區分出,「發起」請求者 — 使用者代理 (User Agent)
以及 「真正」具權威性的送出回應者 — 源伺服器 (Origin Server)
 
然而,HTTP 仍存在的弱點是 :

沒有一致的機制來區分權威的回應 (由 源伺服器發出),
和非權威的回應 (沒有訪問 源伺服器 (Origin Server),而是從中介或快取取得)。

 
解決的辦法是 — — HTTPS 與 no-cache 指令 (不使用快取) 。
 
 

TLS Problem

Proxy使用者代理 來說是 Server,
源伺服器 來說是 Client。」
此特性卻使 HTTPS 無法有效運用 代理 (proxy)。
 
 
欲使用 傳輸層安全協議 (TLS) 進行安全連線 (i.e., HTTPS),
Client 與 Server 在建立連線 (TCP 三向交握) 後,
需進行 TLS/SSL handshake 交換加密資訊 (e.g., 協議版本、憑證、加密方法、雜湊)…。
 
然而,使用 TLS,
會變成 使用者代理 (User Agent)代理 (proxy) 進行 TLS/SSL handshake
除非 代理 (prxoy) 也有 TLS/SSL 憑證,且 使用者代理 (User Agent) 信任該憑證,
使用者代理 (User Agent) 無法直接源伺服器 (Origin Server) 建立安全連線。
 
TLS on Proxy
 


 

隧道 (Tunnel)

隧道 (tunnel),有效解決了上述的 TLS Problem:

代理 (proxy) 再也 不用理解、轉譯
使用者代理 (User Agent)源伺服器 (Origin Server) 的訊息內容。

 
隧道 (tunnel),是將兩個連線之間的 代理 (proxy) 做為盲中繼 (blind relay) — — 純跑腿,
例如,傳輸層安全協議 (TLS) 需通過 共享防火牆代理 (shared firewall proxy) 建立機密通訊時。
 
tunnel
 
原理是藉由一或多個 代理 (proxy),
建立 端與端之間的 虛擬連線 (virtual connection),
在連線的兩端之間發送封包,而 不改變訊息
直到其中一端結束連線,關閉隧道。
 
使用 隧道 (tunnel) 中繼 HTTPS:
tunnel-proxy
 
(複習)
未使用 隧道 (tunnel) 中繼 HTTPS:
除非 代理 (prxoy) 也有 TLS/SSL 憑證,且 使用者代理 (User Agent) 信任該憑證:
tls-proxy
 
隧道 (tunnel) 僅預期用於 代理 (proxy),
因此,大部分的 源伺服器 (Origin Server) 並未 (也不需) 支援。
 
 

白名單 (whitelist)

代理 (proxy) 建立到任意 Server 的 隧道 (tunnel) 存在重大風險,
特別當目的地是不適用於 Web 流量的 著名 (well-known) 或 保留的 TCP 埠 (port) 時。
因此,支援 隧道 (tunnel) 的代理,應限制 可服務的 埠號 (port)白名單 (whitelist)
 
例如,SMTP (簡單郵件傳輸協定) 通常使用 TCP 25 port,
若 代理 (proxy) 允許建立至任意 Server 的 25 port 隧道 (tunnel),
可能使其中繼許多垃圾郵件。
 
 
[註]:
隧道 (Tunnel) 一旦啟用,就不被認為是 HTTP 通信的一方。
(儘管 隧道 是由 HTTP 請求發起的)
 
 


 

閘道 (Gateway)

閘道/網關 (gateway),有時又稱 反向代理 (reverse proxy)
通常是 Server 透過一些本機設定、規則,
所選擇的 訊息轉發 (message-forwarding) 中間人。
 
做為 源伺服器 (Origin Server) 出站 (outbound) 連接的中介,
其轉譯接收到的請求,並轉發 進站 (inbound) 到另一台 (或多台) server。
gateway
 
 

哪尼!? 這跟 代理 (proxy) 不是一模一樣嗎? 😑

 
 
非也,依 [RFC 7230] 定義,兩者最大的差異為:

代理 (proxy) 由 Client 配置,
而 閘道 (gateway) 主要由 Server 配置。

 

中介協議 (Intermediation Protocol)

HTTP 被設計為 — 可做為 轉譯、通訊 非 HTTP 資訊系統的 中介協議 (intermediation protocol)
因此,HTTP 代理 (proxy) 與 閘道 (gateway),皆能將支援的各種通訊協定,
轉譯為 Client 可以查看和操作的格式 (e.g., HTML、JSON)。
 
並非 傳統所述:

代理 (proxy) 連接兩相同協議的應用程序,
閘道 (gateway) 為使用不同協議兩端點的轉譯者。

 
 

功能

 

快取 & 負載

閘道 (gateway) 的兩大功能 — 快取 (cache)負載平衡 (load balancing):

閘道 (gateway) 常封裝一些訊息服務,
並藉由 加速器 (accelerator) 快取,或 計算機叢集 分區、負載平衡 (分配流量),
以節省頻寬、提高應用程序的容錯能力,並增進伺服端效能。

 
顧客 (User Agent)店家 (gateway) 購物,
它如果有 現貨 (cache) 就賣你,而非大老遠跑去找 源伺服器。
 
若沒有,就幫你調貨
— — 把「請求」轉發 (平衡)其他店家、工廠、公司 (Origin Server):
gateway-2
 
例如,能在主機間自動分配應用程式內送流量,
實現應用程式容錯能力 的 AWS 雲端網路負載平衡器 (ELB)。
 
又或者 AWS 內容交付網路 (CloudFront)
會自動將 Client 路由到可提供最低延遲的節點,以最佳的效能發佈內容 (靜態 + 動態)。
 
例如:

 
如果該內容已存在於該節點,CloudFront 會立即提供該內容。
如果內容不存在於該節點,CloudFront 會從 源伺服器 (Origin Server) 取得該內容。
 
當然,也可自行建置如 Varnish …等的 反向快取代理,
因能更快速的交付資源,又稱為 HTTP 加速器 (accelerator)
 
[註]:
負載平衡 (load balancing) 根據 請求內容、網路流量、地理位置…etc
有多種實作方式 (e.g., DNS),不能與 反向代理 (reverse proxy) 劃上等號。
 
 

隱藏來源

此外,閘道 (gateway) 還做為防火牆、DDOS攻擊防護、身份驗證…etc.
Client 可能不知道,正在通訊的對象是 閘道 (gateway),而以為是 源伺服器!
詳見 伺服端快取 (Server-Side Cache)
 


 

總結

上述的中介類別,僅考慮到 HTTP 通訊參與者,
實際上還有非常多種 代理 (proxy) 或 中介 (intermediary),
有些可能是運作在較低的網路層級上 (e.g., SOCKS)。
 
例如,常見於公用網路的 攔截代理 (interception proxy)
或有時稱 透明代理 (transparent proxy),
即可做為監控網路使用策略的 企業防火牆。
 
嚴格來說,透明代理 (transparent proxy) 並非規範所述的「HTTP 代理」,
因為它 並非由 Client 所選擇,Client 甚至不知道它的存在!
 
另外,就通訊協定的層級來說,
網路中介 與 中間人攻擊 (man-in-the-middle attack) 是難以區別的,
可能因錯誤地違反 HTTP 語義,而導致操作性問題 或 引入安全漏洞。
 
 

作者: 鄭中勝

喜愛音樂,但不知為何總在打程式 ?
期許能重新審視、整理自身所學,幫助有需要的人。

發表迴響