此儲存庫包含客戶端和伺服器,可讓您透過其他網路協定傳輸 TCP 和 UDP 流量。
目前,支援的隧道有:
主要工具是用 Rust 編寫的,端到端測試是用 Python 編寫的。
docker pull ghcr.io/dlemel8/tunneler-server:latest
docker pull ghcr.io/dlemel8/tunneler-client:latest
cargo --version || curl --proto ' =https ' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo build --release
如果您想建立本機 docker 映像,還有一個 docker 文件
docker run -e LOCAL_PORT=45301
-e REMOTE_PORT=5201
-e REMOTE_ADDRESS=localhost
-e TUNNELED_TYPE=udp
--rm -p 45301:45301 ghcr.io/dlemel8/tunneler-server:latest tcp
./target/release/client
--tunneled-type tcp
--remote-address 1.1.1.1
--remote-port 53
--log-level debug
dns
--read-timeout-in-milliseconds 100
--idle-client-timeout-in-milliseconds 30000
使用--help
運行 docker 映像或編譯的二進位檔案以獲取更多信息
cargo test --all-targets
python3 -m pip install -r e2e_tests/requirements.txt
PYTHONPATH=. python3 -m pytest -v
此儲存庫包含一些使用 Docker Compose 的伺服器部署範例:
您可以在本機上執行每個範例,也可以使用 Terraform 和 Ansible 進行部署。請在此處查看更多資訊。
每個可執行檔包含 2 個透過客戶端流通道進行通訊的元件(位元組讀取器和寫入器的元組):
基於 TCP 的流量可以簡單地轉換為流。基於 UDP 的流量轉換取決於隧道協定。
基於 UDP 的流量還需要一種方法來識別現有客戶端以繼續其會話。該解決方案是記憶體中的客戶端緩存,它將客戶端的標識符映射到其流。
為了將 UDP 流量轉換為流,每個資料包有效負載之前都有一個 2 位元組大小的標頭(採用大端字節序)。
UDP 偵聽器使用傳入封包對等位址作為其用戶端快取的金鑰。
我們在這裡面臨一些挑戰:
為了解決這些挑戰,每個客戶端會話首先產生一個隨機客戶端 ID(4 個字母數字字元)。客戶端讀取資料到隧道並透過編碼器管道運行它:
然後,編碼資料將用作 TXT DNS 查詢的名稱。
如果您擁有權威 DNS 伺服器,用戶端可以將請求傳送到遞歸 DNS 解析器。解析器將從您的網域註冊商取得您的 IP,並將請求轉發到您的 IP。另一種選擇(更快但對任何流量分析器來說更明顯)是配置客戶端將請求直接發送到您的 IP(在連接埠 UDP/53 或伺服器正在偵聽的任何其他連接埠上)。
伺服器解碼資料(忽略任何非客戶端流量)並使用客戶端 ID 作為其客戶端快取的金鑰。
為了處理大型伺服器回應和空 TCP ACK,客戶端和伺服器都使用讀取逾時。如果讀取逾時已過,將發送空訊息。客戶端和伺服器端都使用空閒逾時來停止轉送並清理本機資源。
為了實現相互身份驗證,我們使用私有憑證授權單位:
用戶端和伺服器都配置為在 TLS 握手中使用其金鑰和憑證。 CA 憑證用作根憑證。
由於使用了伺服器名稱指示擴展,因此客戶端請求特定的伺服器名稱,且伺服器僅在請求該名稱時才提供其證書。伺服器名稱也必須是憑證的一部分,例如作為主題備用名稱。