Pipy 實現 SOCKS 代理
上篇我們介紹了服務網格 osm-edge 出口網關使用的 HTTP 隧道,其處理方式與另一種代理有點類似,就是今天要介紹的 SOCKS 代理。二者的主要差別簡單來說就是前者使用 HTTP CONNECT
告知代理目的地址,而後者則是通過 SOCKS 協議。值得一提的是,SOCKS 也是出口網關的可選協議之一。
SOCKS 是一種網絡傳輸協議,是 Socket Secure 的縮寫,主要用於客戶端與外網服務器之間通訊的中間傳遞。根據 OSI 模型,SOCKS 是會話層的協議,位於表示層與傳輸層之間。
SOCKS 協議的最新版本是 SOCKS5,在 SOCKS4 的基礎上增加了 UDP、認證 和 IPv6 的支持。因此,後面提到的 SOCKS 都是使用最廣泛的 SOCKS5。
先看一下 SOCKS 代理的工作流程。
-
協商階段:客戶端與代理建立連接,並進行協商,包括協議版本、認證的方式等等。
-
連接階段:客戶端告知代理要連接的目的地址和端口(SOCKS 報文),代理使用報文中的地址和端口與服務端創建連接,並將結果作爲狀態返回給客戶端。
-
數據傳輸階段:客戶端向代理發送數據,代理將數據發送到服務端;然後將服務端返回的數據返回給客戶端。
Demo
還是使用上篇中的例子,在防火牆後有個 TCP 服務端,由於監聽在 127.0.0.1:8081
還能在本地訪問。同樣,使用 Pipy 來模擬這個服務。
pipy()
.listen('127.0.0.1:8081')
.replaceData(
() => new Data('Hi, TCP!\n')
)
接下來,在服務端一側建立一個 SOCKS 代理。
PipyJS 編碼
我們的代理監聽在 8000
端口,使用 acceptSOCKS
過濾器 [1] 來處理 SOCKS 協議報文,從報文中獲取目的地址和端口,然後使用該地址和端口創建到服務端的連接。
pipy({
_host: null,
_port: null,
})
//socks
.listen(8000)
.acceptSOCKS(
(host, port) => (
_host = host,
_port = port,
true // return true to accept the session
)
).to(
$ => $.connect(
() => `${_host}:${_port}`
)
)
測試
在主機 192.168.1.110
上運行我們的代理以及服務端,客戶端 curl
運行在主機 192.168.1.11
上。使用下面的命令進行測試:
curl -x socks5://192.168.1.110:8000 telnet://127.0.0.1:8081
引用鏈接
[1]
acceptSOCKS
過濾器: https://flomesh.io/pipy/docs/zh/reference/api/Configuration/acceptSOCKS
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/2_ctaOig2OJf__A-PpAqSw