2009-12-26 26 views
32

Estoy tratando de usar Tor-Server como un proxy en HttpWebRequest, mi código es el siguiente:usando Tor como proxy

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(); 

funciona perfecto con proxies "normales" pero con Tor estoy recibiendo excepciones, mientras que llaman

GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"

Respuesta

22

Tor es no un proxy HTTP. Es un proxy SOCKS. Puede utilizar un proxy HTTP que admita el reenvío en SOCKS (como Privoxy) y, en su lugar, conectarse a ese código de transmisión.

+0

argh ... derecha. entonces ¿puedo usarlo * de alguna manera * para hacer una solicitud? – Lay

+2

Lay: no se incluye nada en .NET para reenviar cosas HTTP a través de un proxy SOCKS. –

34

Si tiene privoxy instalados y en funcionamiento que puede hacer

request.Proxy = new WebProxy("127.0.0.1:8118"); // default privoxy port 

que le permitirá hacer pedidos usando Tor

+0

Pero creo que esto filtra dns – Para

+0

Vidalia ahora se eliminó del Tor Bundle. –

0

Es necesario "extraer" una corriente de calcetines ...

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 
4

Utilice la biblioteca "SocksWebProxy". Puede usarlo con WebClient & WebRequest (Simplemente asigne un nuevo SocksWebProxy al atributo * .Proxy). No es necesario que Privoxy o un servicio similar traduzca tráfico HTTP a tor.

https://github.com/Ogglas/SocksWebProxy

Hice algunas extensiones a él también al permitir que el puerto de control. Aquí es cómo podría hacer que Tor se ejecute en segundo plano sin que se inicie Tor Browser Bundle y para controlar Tor podemos usar Telnet o enviar comandos programáticamente a través de 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"); 
} 

pasos para configurar Tor:

  1. Copiar torrc de opciones por defecto en el directorio en el que está tor.exe. El directorio predeterminado si está utilizando el navegador Tor es: "~ Tor Browser \ Browser \ TorBrowser \ Data \ Tor"
  2. Abra una ventana de solicitud de cmd
  3. chdir al directorio donde está tor.exe. El directorio predeterminado si está utilizando el navegador Tor es: "~ Tor Browser \ Browser \ TorBrowser \ Tor \"
  4. Genera una contraseña para el acceso al puerto de control Tor. tor.exe --hash-password “your_password_without_hyphens” | more
  5. Agregue su contraseña hash de contraseña a torrc-defaults en ControlPort 9151. Debería verse algo como esto: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. Si acepta su contraseña para ser "contraseña", puede copiar la cadena de arriba.
  6. Ahora puede acceder al control Tor a través de Telnet una vez que se inicia. Ahora el código puede ejecutarse, simplemente edite la ruta hacia donde se encuentran sus archivos Tor en el programa. prueba modificando Tor a través de Telnet:
  7. tor de inicio con el siguiente comando: tor.exe -f .\torrc-defaults
  8. abrir otra cmd de tipo puntual y: telnet localhost 9151
  9. Si todo va bien debería ver una pantalla completamente en negro. Escriba "autenticate “your_password_with_hyphens”" Si todo va bien, debería ver "250 OK".
  10. Escriba "SIGNAL NEWNYM" y obtendrá una nueva ruta, ergo nueva dirección IP. Si todo va bien, debería ver "250 OK".
  11. Tipo "setevents circ" (eventos del circuito) para permitir la salida de consola
  12. Tipo "getinfo circuit-status" para ver los circuitos de corriente
Cuestiones relacionadas