¿Cómo puedo conectarme a un servicio oculto de Tor usando cURL en PHP?

366

Estoy tratando de conectarme a un servicio oculto de Tor usando el siguiente código PHP:

$url = 'http://jhiwjjlqpyawmpjx.onion/'
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROXY, "http://127.0.0.1:9050/");
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);

print_r($output);
print_r($curl_error);

Cuando lo ejecuto, aparece el siguiente error:

No se pudo resolver el nombre de host

Sin embargo, cuando ejecuto el siguiente comando desde mi línea de comandos en Ubuntu:

curl -v --socks5-hostname localhost:9050 http://jhiwjjlqpyawmpjx.onion

Recibo una respuesta como se esperaba

La documentación de PHP cURL dice esto:

--socks5-hostname
Use  the  specified  SOCKS5 proxy (and let the proxy resolve the host name).

Creo que la razón por la que funciona desde la línea de comandos es porque Tor (el proxy) está resolviendo el nombre de host .onion, que reconoce. Cuando ejecuto el código PHP anterior, supongo que cURL o PHP está tratando de resolver el nombre de host .onion y no lo reconoce. He buscado una manera de decirle a cURL / PHP que permita que el proxy resuelva el nombre de host, pero no puedo encontrar una manera.

Hay una pregunta de desbordamiento de pila muy similar, la solicitud cURL que usa el proxy socks5 falla cuando se usa PHP, pero funciona a través de la línea de comando .

escarchado
fuente

Respuestas:

21

Uso Privoxy y cURL para raspar páginas Tor:

<?php
    $ch = curl_init('http://jhiwjjlqpyawmpjx.onion'); // Tormail URL
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
    curl_setopt($ch, CURLOPT_PROXY, "localhost:8118"); // Default privoxy port
    curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
    curl_exec($ch);
    curl_close($ch);
?>

Después de instalar Privoxy, debe agregar esta línea al archivo de configuración ( /etc/privoxy/config). Tenga en cuenta el espacio y '.' al final de la línea.

forward-socks4a / localhost:9050 .

Luego reinicie Privoxy.

/etc/init.d/privoxy restart
Papas Grasas
fuente
¡Esto funciona! Probado en Windows 10 y CentOS 6, también si Tor usa Socks 5 en lugar de Socks 4, use esto:forward-socks5 / localhost:9150 .
David Refoua
¿Necesito TOR y Privoxy para que esto funcione? gracias
8

Intenta agregar esto:

curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); 
Anthony Garcia-Labiad
fuente
5

TL; DR: se establece CURLOPT_PROXYTYPEpara usar CURLPROXY_SOCKS5_HOSTNAMEsi tiene un PHP moderno, el valor de lo 7contrario, y / o corrige el CURLOPT_PROXYvalor.

Como dedujo correctamente, no puede resolver .oniondominios a través del sistema DNS normal, porque este es un dominio de nivel superior reservado específicamente para su uso por Tor y tales dominios por diseño no tienen direcciones IP para asignar.

El uso CURLPROXY_SOCKS5dirigirá el comando cURL para enviar su tráfico al proxy, pero no hará lo mismo para la resolución de nombres de dominio. Las solicitudes de DNS, que se emiten antes de que cURL intente establecer la conexión real con el sitio de Onion, aún se enviarán al sistema de resolución de DNS normal del sistema. Estas solicitudes DNS seguramente fallarán, porque el .onionsolucionador DNS normal del sistema no sabrá qué hacer con una dirección a menos que, también, esté enviando específicamente tales consultas a Tor.

En lugar de CURLPROXY_SOCKS5, debes usar CURLPROXY_SOCKS5_HOSTNAME. Alternativamente, también puede usar CURLPROXY_SOCKS4A, pero SOCKS5 es muy preferido. Cualquiera de estos tipos de proxy informa a cURL para realizar sus búsquedas de DNS y su transferencia de datos real a través del proxy. Esto es necesario para resolver con éxito cualquier .oniondominio.

También hay dos errores adicionales en el código en la pregunta original que aún no han sido corregidos por los comentaristas anteriores. Estos son:

  • Falta el punto y coma al final de la línea 1.
  • El valor de la dirección proxy se establece en una URL HTTP, pero su tipo es SOCKS; Estos son incompatibles. Para los servidores proxy SOCKS, el valor debe ser una combinación de IP o nombre de dominio y número de puerto sin un esquema / protocolo / prefijo.

Aquí está el código correcto completo, con comentarios para indicar los cambios.

<?php
$url = 'http://jhiwjjlqpyawmpjx.onion/'; // Note the addition of a semicolon.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:9050"); // Note the address here is just `IP:port`, not an HTTP URL.
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); // Note use of `CURLPROXY_SOCKS5_HOSTNAME`.
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);

print_r($output);
print_r($curl_error);

También puede omitir la configuración CURLOPT_PROXYTYPEpor completo cambiando el CURLOPT_PROXYvalor para incluir el socks5h://prefijo:

// Note no trailing slash, as this is a SOCKS address, not an HTTP URL.
curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050');
Meitar
fuente