如何通過 TOR 路由 TCP 連接?
我正在閱讀有關torchat的內容,它本質上是一個匿名聊天程序。
聽起來很酷,所以我想嘗試自己製作。首先,我編寫了一個測試來使用 Http 抓取網頁。Sicne .NET 不支持 SOCKS4A/SOCKS5 我使用了 privoxy 並且我的應用程序工作正常。然後我切換到 TCP echo 測試,而 privoxy 不支持 TCP,所以我搜尋並安裝了 6 個以上的代理應用程序(freecap、socat、freeproxy、delegate 是我能記住的那些,我還玩過 putty bc i知道它支持隧道和 SOCK5),但我無法成功地讓它們中的任何一個工作,更不用說通過 privoxy 輕鬆無痛地完成的我的 http 測試執行它了。
我可以使用什麼來獲得通過 TOR 的 TCP 連接?我花了超過 2 個小時沒有成功。我不知道我是否正在尋找在我的搜尋中出現的中繼、隧道、轉發器、代理或代理鏈。我將以下配置用於 .NET。我需要 TCP 工作,但我首先使用 http 進行測試,因為我知道我使用 privoxy 讓它工作。我使用哪些應用程序和配置來讓 TCP 通過 Tor?
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.net> <defaultProxy enabled="true"> <proxy bypassonlocal="True" proxyaddress="http://127.0.0.1:8118"/> </defaultProxy> <settings> <httpWebRequest useUnsafeHeaderParsing="true"/> </settings> </system.net> </configuration>
-edit- 感謝 Bernd,我有一個解決方案。這是我最終編寫的程式碼。這並不令人驚訝,但它是公平的。
static NetworkStream ConnectSocksProxy(string proxyDomain, short proxyPort, string host, short hostPort, TcpClient tc) { tc.Connect(proxyDomain, proxyPort); if (System.Text.RegularExpressions.Regex.IsMatch(host, @"[\:/\\]")) throw new Exception("Invalid Host name. Use FQDN such as www.google.com. Do not have http, a port or / in it"); NetworkStream ns = tc.GetStream(); var HostNameBuf = new ASCIIEncoding().GetBytes(host); var HostPortBuf = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(hostPort)); if (true) //5 { var bufout = new byte[128]; var buflen = 0; ns.Write(new byte[] { 5, 1, 0 }, 0, 3); buflen = ns.Read(bufout, 0, bufout.Length); if (buflen != 2 || bufout[0] != 5 || bufout[1] != 0) throw new Exception(); var buf = new byte[] { 5, 1, 0, 3, (byte)HostNameBuf.Length }; var mem = new MemoryStream(); mem.Write(buf, 0, buf.Length); mem.Write(HostNameBuf, 0, HostNameBuf.Length); mem.Write(new byte[] { HostPortBuf[0], HostPortBuf[1] }, 0, 2); var memarr = mem.ToArray(); ns.Write(memarr, 0, memarr.Length); buflen = ns.Read(bufout, 0, bufout.Length); if (bufout[0] != 5 || bufout[1] != 0) throw new Exception(); } else //4a { var bufout = new byte[128]; var buflen = 0; var mem = new MemoryStream(); mem.WriteByte(4); mem.WriteByte(1); mem.Write(HostPortBuf, 0, 2); mem.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(1)), 0, 4); mem.WriteByte(0); mem.Write(HostNameBuf, 0, HostNameBuf.Length); mem.WriteByte(0); var memarr = mem.ToArray(); ns.Write(memarr, 0, memarr.Length); buflen = ns.Read(bufout, 0, bufout.Length); if (buflen != 8 || bufout[0] != 0 || bufout[1] != 90) throw new Exception(); } return ns; }
用法
using (TcpClient client = new TcpClient()) using (var ns = ConnectSocksProxy("127.0.0.1", 9050, "website.com", 80, client)) {...}
Socks4a 真的很簡單。你可以用 5 行程式碼手動完成 socks4a。查看 socks RFC(或其在 wikipedia 上更簡單的解釋)。
本質上,您只需與 socks 代理建立一個正常的 TCP 連接(這意味著在 tor 的情況下,您只需連接到 127.0.0.1 埠 9050,連接將被接受,然後您在此連接上發送一個非常簡單的請求(範例在RFC),然後一段時間後,tor 將準確地回答 8 個字節(第二個字節是狀態,應該是 90 表示成功)。僅此而已。
在此連接上收到 Tor 的成功回答後,您繼續使用相同的連接,此時您已經通過此套接字與另一端連接,從此刻起,它的行為就像任何其他 TCP 連接一樣,用於所有意圖和目的,並且您可以像直接連接一樣開始發送/接收。
編輯:您不需要學習整個 RFC,在維基百科中有一個非常簡短和完整的 Socks 4a 描述(socks 5 對您的需求來說太過分了,socks 4 無法解析主機名,所以 4a 是 Tor 的理想選擇) :