上篇我們介紹了服務網格 osm-edge 出口網關使用的?HTTP 隧道,其處理方式與另一種代理有點類似,就是今天要介紹的 SOCKS 代理。二者的主要差別簡單來說就是前者使用?HTTP CONNECT
?告知代理目的地址,而后者則是通過 SOCKS 協議。值得一提的是,SOCKS 也是出口網關的可選協議之一。
SOCKS 是一種網絡傳輸協議,是 Socket Secure 的縮寫,主要用于客戶端與外網服務器之間通訊的中間傳遞。根據 OSI 模型,SOCKS 是會話層的協議,位于表示層與傳輸層之間。
SOCKS 協議的最新版本是 SOCKS5,在 SOCKS4 的基礎上增加了 UDP、認證 和 IPv6 的支持。因此,后面提到的 SOCKS 都是使用最廣泛的 SOCKS5。
先看一下 SOCKS 代理的工作流程。

1. 協商階段:客戶端與代理建立連接,并進行協商,包括協議版本、認證的方式等等。
2. 連接階段:客戶端告知代理要連接的目的地址和端口(SOCKS 報文),代理使用報文中的地址和端口與服務端創建連接,并將結果作為狀態返回給客戶端。
3. 數據傳輸階段:客戶端向代理發送數據,代理將數據發送到服務端;然后將服務端返回的數據返回給客戶端。
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