C# 使用 Tor 作为代理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1962483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
using Tor as Proxy
提问by Lay
I'm trying to use Tor-Server as a proxy in HttpWebRequest
, my code looks like this:
我正在尝试使用 Tor-Server 作为 中的代理HttpWebRequest
,我的代码如下所示:
HttpWebRequest request;
HttpWebResponse response;
request = (HttpWebRequest)WebRequest.Create("http://www.google.com");
request.Proxy = new WebProxy("127.0.0.1:9051");
response = (HttpWebResponse)request.GetResponse();
response.Close();
it works perfect with "normal" proxies but with Tor I'm getting Exceptions while calling
它与“普通”代理完美配合,但使用 Tor 我在调用时遇到异常
GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"
GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"
回答by Mehrdad Afshari
Tor is notan HTTP proxy. It's a SOCKS proxy. You can use an HTTP proxy that supports forwarding on SOCKS (like Privoxy) and connect to that via code instead.
Tor不是HTTP 代理。这是一个 SOCKS 代理。您可以使用支持在 SOCKS 上转发的 HTTP 代理(如 Privoxy)并通过代码连接到该代理。
回答by jspcal
Yes like the other poster said, a socks client is needed. Some libraries are Starksoft Proxy, ProxySocketand ComponentSpace Socks Proxy. sockscapis a tool that intercepts and reroutes winsock calls, and privoxyis a local proxy that can tunnel your requests over socks. A couple different solutions.
是的,就像另一张海报说的那样,需要一个袜子客户端。一些库是Starksoft Proxy、ProxySocket和ComponentSpace Socks Proxy。sockscap是一个拦截和重新路由 winsock 调用的工具,privoxy是一个本地代理,可以通过socks 传输您的请求。几个不同的解决方案。
回答by Christopher Tarquini
回答by Fernando Reis Guimaraes
You need "extract" a stream from socks...
你需要从袜子中“提取”一个流......
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Runtime.CompilerServices
Public Class Form1
Sub Form1_Load() Handles Me.Load
Dim Host As String = "google.com"
Dim P As New SocksProxy("localhost", 64129) 'Set your socks proxy here
Dim Stream As NetworkStream = P.GetStream(Host, 80)
Dim buffer As Byte() = Download(Stream, Host, "")
My.Computer.FileSystem.WriteAllBytes("C:\webpage.html", buffer, False)
MsgBox("ok")
End Sub
Function Download(Stream As NetworkStream, Host As String, Resource As String) As Byte()
Using writer = New StreamWriter(Stream)
writer.Write(String.Format("GET /{2} HTTP/1.1{0}Host: {1}{0}{0}", vbCrLf, Host, Resource))
writer.Flush()
Dim byteList As New List(Of Byte)
Dim bufferSize As Integer = 4096
Dim buffer(bufferSize - 1) As Byte
Do
Dim bytesRead As Integer = Stream.Read(buffer, 0, bufferSize)
byteList.AddRange(buffer.Take(bytesRead))
Loop While Stream.DataAvailable
Return byteList.ToArray
End Using
End Function
End Class
Public Class SocksProxy
Private _SocksHost As String
Private _SocksPort As Integer
Sub New(SocksHost As String, SocksPort As Integer)
_SocksHost = SocksHost
_SocksPort = SocksPort
End Sub
Function GetStream(HostDest As String, PortDest As Short) As NetworkStream
Dim client As TcpClient = New TcpClient()
client.Connect(_SocksHost, _SocksPort)
Dim stream As NetworkStream = client.GetStream()
'Auth
Dim buf = New Byte(299) {}
buf(0) = &H5
buf(1) = &H1
buf(2) = &H0
stream.Write(buf, 0, 3)
ReadExactSize(stream, buf, 0, 2)
If buf(0) <> &H5 Then
Throw New IOException("Invalid Socks Version")
End If
If buf(1) = &HFF Then
Throw New IOException("Socks Server does not support no-auth")
End If
If buf(1) <> &H0 Then
Throw New Exception("Socks Server did choose bogus auth")
End If
buf(0) = &H5
buf(1) = &H1
buf(2) = &H0
buf(3) = &H3
Dim domain = Encoding.ASCII.GetBytes(HostDest)
buf(4) = CByte(domain.Length)
Array.Copy(domain, 0, buf, 5, domain.Length)
Dim port = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(CShort(PortDest)))
buf(5 + domain.Length) = port(0)
buf(6 + domain.Length) = port(1)
stream.Write(buf, 0, domain.Length + 7)
' Reply
ReadExactSize(stream, buf, 0, 4)
If buf(0) <> &H5 Then
Throw New IOException("Invalid Socks Version")
End If
If buf(1) <> &H0 Then
Throw New IOException(String.Format("Socks Error {0:X}", buf(1)))
End If
Dim rdest = String.Empty
Select Case buf(3)
Case &H1
' IPv4
ReadExactSize(stream, buf, 0, 4)
Dim v4 = BitConverter.ToUInt32(buf, 0)
rdest = New IPAddress(v4).ToString()
Exit Select
Case &H3
' Domain name
ReadExactSize(stream, buf, 0, 1)
If buf(0) = &HFF Then
Throw New IOException("Invalid Domain Name")
End If
ReadExactSize(stream, buf, 1, buf(0))
rdest = Encoding.ASCII.GetString(buf, 1, buf(0))
Exit Select
Case &H4
' IPv6
Dim octets = New Byte(15) {}
ReadExactSize(stream, octets, 0, 16)
rdest = New IPAddress(octets).ToString()
Exit Select
Case Else
Throw New IOException("Invalid Address type")
End Select
ReadExactSize(stream, buf, 0, 2)
Dim rport = CUShort(IPAddress.NetworkToHostOrder(CShort(BitConverter.ToUInt16(buf, 0))))
Return stream
End Function
Private Sub ReadExactSize(stream As NetworkStream, buffer As Byte(), offset As Integer, size As Integer)
While size <> 0
Dim read = stream.Read(buffer, offset, size)
If read < 0 Then
Throw New IOException("Premature end")
End If
size -= read
offset += read
End While
End Sub
End Class
回答by Ogglas
Use the library "SocksWebProxy". You can use it with WebClient & WebRequest (Just assign a new SocksWebProxy to the *.Proxy attribute). No Need for Privoxy or similar service to translate http traffic to tor.
使用库“SocksWebProxy”。您可以将它与 WebClient 和 WebRequest 一起使用(只需为 *.Proxy 属性分配一个新的 SocksWebProxy)。无需 Privoxy 或类似服务将 http 流量转换为 Tor。
https://github.com/Ogglas/SocksWebProxy
https://github.com/Ogglas/SocksWebProxy
I made some extensions to it as well by enabling the control port. Here is how you could have Tor running in the background without Tor Browser Bundle started and to control Tor we can use Telnet or send commands programmatically via Socket.
我还通过启用控制端口对其进行了一些扩展。下面是如何在没有 Tor 浏览器包启动的情况下让 Tor 在后台运行,并且为了控制 Tor,我们可以使用 Telnet 或通过 Socket 以编程方式发送命令。
Socket server = null;
//Authenticate using control password
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(endPoint);
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
//Request a new Identity
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
}
else
{
Console.WriteLine("SIGNAL NEWNYM sent successfully");
}
Steps to configure Tor:
配置 Tor 的步骤:
- Copy torrc-defaults into the directory in which tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Data\Tor"
- Open a cmd prompt window
- chdir to the directory where tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Tor\"
- Generate a password for Tor control port access.
tor.exe --hash-password “your_password_without_hyphens” | more
- Add your password password hash to torrc-defaults under ControlPort 9151. It should look something like this:
hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507
. If you accept your password to be "password" you can copy the string above. - You can now access Tor control via Telnet once it is started. Now the code can run, just edit the path to where your Tor files are located in the program. Test modifying Tor via Telnet:
- Start tor with the following command:
tor.exe -f .\torrc-defaults
- Open up another cmd prompt and type:
telnet localhost 9151
- If all goes well you should see a completely black screen. Type "
autenticate “your_password_with_hyphens”
" If all goes well you should see "250 OK". - Type "
SIGNAL NEWNYM
" and you will get a new route, ergo new IP. If all goes well you should see "250 OK". - Type "
setevents circ
" (circuit events) to enable console output - Type "
getinfo circuit-status
" to see current circuits
- 将 torrc-defaults 复制到 tor.exe 所在的目录中。如果您使用 Tor 浏览器,则默认目录为:“~\Tor Browser\Browser\TorBrowser\Data\Tor”
- 打开一个 cmd 提示窗口
- chdir 到 tor.exe 所在的目录。如果您使用 Tor 浏览器,则默认目录为:“~\Tor Browser\Browser\TorBrowser\Tor\”
- 为 Tor 控制端口访问生成密码。
tor.exe --hash-password “your_password_without_hyphens” | more
- 您的密码,密码哈希加入的torrc,默认ControlPort 9151.下,它应该是这个样子:
hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507
。如果您接受密码为“password”,则可以复制上面的字符串。 - 现在您可以通过 Telnet 启动 Tor 控制。现在代码可以运行了,只需编辑程序中 Tor 文件所在位置的路径。通过 Telnet 测试修改 Tor:
- 使用以下命令启动 tor:
tor.exe -f .\torrc-defaults
- 打开另一个 cmd 提示符并键入:
telnet localhost 9151
- 如果一切顺利,您应该会看到一个全黑的屏幕。输入“
autenticate “your_password_with_hyphens”
” 如果一切顺利,您应该看到“250 OK”。 - 输入“
SIGNAL NEWNYM
”,你会得到一个新的路由,也就是新的IP。如果一切顺利,您应该会看到“250 OK”。 - 输入“
setevents circ
”(电路事件)以启用控制台输出 - 输入“
getinfo circuit-status
”查看当前电路