SSH 動態埠轉發中如何使用 SOCKS 協議?
- 通過 SSH 動態埠轉發在應用程序客戶端和應用程序伺服器之間創建連接時
ssh -D
,如何使用 SOCKS 協議?SOCKS 是否用作通信協議
- 在應用程序客戶端和 SSH 客戶端之間,
- 或者在 SSH 客戶端和 SSH 伺服器之間,
- 還是在 SSH 伺服器和應用伺服器之間?
- 一旦應用程序客戶端通過 SSH 動態埠轉發連接到應用程序伺服器,則 SSH 客戶端和伺服器通常被稱為“讓路”。這是否意味著現在沒有使用 SSH 協議?哪些協議仍在使用,例如,SOCKS 和/或 SSH 是否仍在使用?應用程序客戶端和應用程序伺服器之間的通信是否仍然封裝在 SSH 協議中(如此保護)?
謝謝。
我會說 SSH 客戶端和伺服器“讓開”是描述動態埠轉發的一種非常糟糕的方式,並且可能是由於幾位作者重複了他們可能被教導過的寫得不好或過於簡化的描述在某一點。
正如其他人所描述的,SOCKS 被用作一種標準化的方式來告訴任何兼容的 TCP 代理代理連接應該去哪裡。從本質上講,SOCKS 協議就像使用老式的手動切換電話:“接線員,請給我連接到 X 鎮的電話號碼 Y!” 在這樣做之後,接線員就不會(應該)監聽連接,您可以使用您想要的任何語言與另一端的人交談。
在 SSH 動態轉發中,應用程序客戶端打開到動態轉發埠(SOCKS 伺服器埠)的 TCP 連接,發出標準 SOCKS 請求以連接到特定 IP 地址和埠,然後可以繼續使用它將使用的任何協議本機通過該 TCP 連接。它需要能夠發出初始的 SOCKS 請求,但它不需要進一步了解任何資訊。(在連接結束時可能會有一些特定於 SOCKS 的小事,但就端點而言,轉發的連接將是完全透明的和協議中立的。)
另一端的應用程序伺服器只看到來自 SSH 伺服器的普通舊 TCP 連接:它不需要知道連接正在被轉發,也不需要知道客戶端涉及 SOCKS 協議。
(當您的電話響起並接聽時,即使電話碰巧來自具有功能性手動電話交換機的技術博物館,您也不需要做任何特別的事情,並且有出線到固定電話網路。)
因此,在嚴格的客戶端/伺服器術語中,當啟動動態轉發功能時,SSH 客戶端還將充當具有特定附加屬性的SOCKS 伺服器,即所有使用 SOCKS 伺服器的連接都將在加密的 SSH 隧道中傳遞到遠端SSH 伺服器並從那裡恢復為正常 TCP 連接。
或者,換句話說,啟用動態轉發的 SSH 客戶端 + SSH 連接 + SSH 伺服器的組合將充當 SOCKS 代理,該代理已被 SSH 連接覆蓋的距離拉長,因此 SOCKS 代理的入站端與 SSH 客戶端位於同一位置,出站端位於 SSH 伺服器上,而在這兩者之間發生的事情對於外部觀察者來說看起來像是非描述性的加密 SSH 流量。
請注意,**只有 SSH 客戶端和 SSH 伺服器之間的躍點會受到 SSH 的保護。**但是應用程序客戶端和 SSH 客戶端/SOCKS 伺服器之間的躍點通常在單個主機內。唯一可能未加密的剩餘部分(除非應用程序協議包含其自己的加密)是 SSH 伺服器和應用程序伺服器之間的躍點。
SSH 協議允許通過一個 TCP 連接復用多個獨立的數據流。每個數據流稱為一個通道。通過 TCP 連接發送的所有數據都是加密的。發送者將來自不同通道的數據聚合成單個數據流,然後對其進行加密。接收器將解密數據並將聚合的數據流分離回各自的通道。
在埠轉發的情況下,SSH 客戶端通過 TCP 連接使用SSH 協議連接到遠端 SSH 伺服器。在客戶端->伺服器轉發的通常情況下,SSH 客戶端也在偵聽某個埠上的 TCP 連接。到此埠的連接將通過伺服器轉發到某個目標。
當一個“發起者”(也就是你的“應用程序客戶端”)連接到 SSH 客戶端的監聽埠時,SSH 客戶端將向伺服器發送一個通道打開請求,請求一個“direct-tcpip”通道。此請求的參數包括通道應連接到的主機名/IP 地址和埠。SSH 伺服器將與指定的主機和埠建立另一個 TCP 連接,我將其稱為“目標”。現在有三個 TCP 連接:
- 在發起者和 SSH 客戶端之間
- SSH 客戶端和 SSH 伺服器之間
- 在 SSH 伺服器和轉發目標之間
SSH 客戶端和伺服器通過 SSH 連接在發起方和目標之間雙向中繼數據。
因此,在轉發來自發起者的連接時,SSH 客戶端必須告訴 SSH 伺服器應該將連接轉發到哪裡。如果您
ssh
使用命令行選項執行以轉發埠,例如:ssh -L 1234:example.com:2345 ...
那麼關於將連接轉發到哪裡的資訊來自命令行參數;
ssh
記得到埠 1234 的連接被轉發到 example.com 埠 2345。如果
ssh
使用執行 SOCKS 伺服器的選項呼叫,例如:ssh -D 1234
那麼每個連接到 SOCKS 埠的發起者應該首先發送一個 SOCKS 協議消息,指定它想要連接的主機和埠。
ssh
將使用 SOCKS 消息中的資訊來構造 direct-tcpip 通道打開請求。