基於SNI的Linux netfilter NAT?

基於SNI的Linux netfilter NAT?

我正在嘗試對路由器上的子網路進行 SNI 代理,同時保留 src IP。

背景:我有一個路由器進行 DNAT 來為許多應用程式連接埠進行連接埠轉發,並且它連接到具有不同後端的子網路(實際上使用 VPN)。對於沒有像 HTTP Host 或 TLS SNI 這樣可以根據請求路由到不同 IP 的協議,我只是使用 DNAT 和 TCP 連接埠過濾器,它們運作良好。

對於 TLS,我正在使用SNI代理基於 TLS SNI 將傳入連線複用到不同的伺服器。它工作得很好,但 SINProxy 從路由器本身發送 TLS 封包,丟棄 src 位址。這會破壞一些依賴 src IP 的後端服務。

因此,我想知道 netfilter 是否可以使用 TLS SNI(可選地使用外部模組)過濾流量並使用 DNAT 路由它們(而不是僅僅丟棄)。如果不可能,有其他選擇嗎?

順便說一句,我不想​​在我的路由器上部署完整的 HTTP(或任何 L5 伺服器),因為:

  1. 我必須解密流量並將它們代理到後端。這是一個巨大的開銷。
  2. 由於管理複雜,我不想在路由器上部署 TLS 憑證。

非常感謝您提前提供的任何有用的回應。

答案1

理論上,使用-j NFQUEUE讓用戶空間更改第一個資料包並執行 NAT,您可以想像做這樣的事情。實際上你不能,因為你需要收到帶有 SNI 擴展的完整 ClientHello 訊息才能猜測新的目標位址,並且由於第一個 TCP 封包將為空,或者對於 UDP,DTLS 無論如何都需要幾輪,然後對現在由conntrack 管理的流進行NAT 太晚了。

你需要一個代理。但是代理可以變得透明,或者您可以使用 PROXY 協定和支援它的後端應用程式(儘管它們必須支援同時使用 PROXY 協定和 TLS)。

例如,haproxy在網關上運行可以執行以下任一操作: 這是提議的項目代理協定,也可以使用Linux代理伺服器透明(來源和目標均透明)代理的目標。

這是我找到的 github gist 的鏈接,提供了兩種選擇:利用 HAProxy 將請求透明地路由到由主機名稱識別的 Web 服務。以下是有關透明代理配置的幾行內容,將在 Linux 核心中使用代理伺服器文檔(也在同一要點中):

HAProxy 伺服器配置如下圖所示。它適用於 TCP 和 HTTP 模式。

server app1-tls 192.0.2.10:3001 source * usesrc client weight 0

答案2

因此,我想知道 netfilter 是否可以使用 TLS SNI 過濾流量(可選地使用外部模組)

這不可能。 NAT 必須從連線的第一個封包開始,也就是啟動 TCP 握手的 TCP SYN。但SNI僅存在於TLS握手的ClientHello中,僅在TCP握手完成後傳送。換句話說:NAT 所需的資訊在需要時尚未可用。

如果不可能,有其他選擇嗎?

haproxy 可以終止 TCP 連接,然後根據 ClientHello 中的 SNI 轉發資料 - 無需在代理處終止 TLS。然後,它可以使用 PROXY 協定在 TCP 連線內轉送客戶端的原始來源 IP(基本上是轉送連線開頭的標頭)。如果上游伺服器不理解 PROXY 協定本身,可以使用類似的軟體代理伺服器對來自 haproxy 的連線進行 SNAT,以便顯示原始來源 IP。

相關內容