什麼是 tproxy 透明代理?

在 Istio 最新的 Ambient 模式中,使用了 tproxy 做透明流量劫持(見此博客 [1] ),這與 Sidecar 模式中基於 IPtables 的流量劫持方式有些許不同,這篇文文章,我們就就一起來探究下什麼是 tproxy。

什麼是代理?

在介紹透明代理之前,我們先了解下什麼是代理。

代理的功能

代理在互聯網中的用途非常廣泛,例如:

代理的分類

代理的分類方式有很多,下圖根據代理的位置將其劃分爲了兩類:

代理可能與客戶端或服務器位於同一節點(或網絡空間,如 Kubernetes 中的 Pod),也可以位於遠端。另外還可以根據代理對客戶端或服務端是否可見(visible)來分爲透明代理和非透明代理,如下圖所示:

使用 tproxy 透明代理

tproxy 是 Linux 的內核模塊(自 Linux 2.2 版本開始引入),用於實現透明代理,其名稱中的字母 t 即代表透明(transparent)。

要使用透明代理首先需要把指定的數據包使用 iptables 攔截到指定的網卡上,然後在該網卡監聽並轉發數據包。

使用 tproxy 實現透明代理的步驟如下:

    1. 首先需要實現流量攔截:在 iptables 的 PREROUTING 鏈的 mangle 表中創建一個規則,攔截流量發送給 tproxy 處理,例如 iptables -t mangle -A PREROUTING -p tcp -dport 9080 -j TPROXY --on-port 15001 --on-ip 127.0.0.1 --tproxy-mark 0x1/0x1,給所有目的地爲 9080 端口的 TCP 數據包打上標記 1,你還可以指定來源 IP 地址或者 IP 集 [3] ,進一步縮小標記範圍,tproxy 監聽在 15001 端口;
  1. 2. 創建一個路由規則,將所有帶有標記 1 的數據包查找特定的路由表:例如 ip rule add fwmark 1 lookup 100,讓所有 fwmark 爲 1 的數據包查找 100 路由表;

    1. 將數據包映射到特定的本地地址:例如 ip rule add local 0.0.0.0/0 dev lo table 100,在 100 路由表中將所有 IPv4 地址聲明爲本地,當然這只是一個例子,實際使用時需要請將特定的 IP 的數據包轉發到本地的 lo 迴環網卡;
  2. 4. 至此流量已被攔截到 tproxy 的監聽端口 15001(從 Linux 內核空間進入用戶空間),你可以編寫網絡應用處理數據包或使用 Squid[4] 或 Envoy[5] 等支持 tproxy 的軟件來處理數據包;

透明代理的優點

透明代理具有以下優點:

透明代理的缺點

透明代理有以下缺點:

總結

透明代理作爲代理中的一類重要類型,它的用途廣泛,不論是 xray、clash 等代理軟件,還是 Istio 服務網格中得使用了應用。瞭解它的原理和工作方式有助於我們科學正確的使用代理,而是否使用透明代理取決於你對它的信任和了解程度。

參考

引用鏈接

[1] 見此博客: https://jimmysong.io/blog/ambient-mesh-l4-traffic-path/
[2] 在這裏: https://jimmysong.io/awesome-cloud-native/#proxy
[3] IP 集: https://ipset.netfilter.org/
[4] Squid: http://www.squid-cache.org/
[5] Envoy: https://www.envoyproxy.io/
[6] tproxy-example - github.com: https://github.com/kristrev/tproxy-example
[7] Linux transparent proxy support - powerdns.org: https://powerdns.org/tproxydoc/tproxy.md.html
[8] Feature: TPROXY version 4.1+ Support - wiki.squid-cache.org: https://wiki.squid-cache.org/Features/Tproxy4

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/sm0FvppqKgbZzVUOVBIxwQ