web-dev-qa-db-fra.com

Comment puis-je me connecter à un service caché Tor en utilisant cURL en PHP?

J'essaie de me connecter à un service caché de Tor à l'aide du code PHP suivant:

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

Quand je le lance, j'obtiens l'erreur suivante:

Impossible de résoudre le nom d'hôte

Cependant, lorsque j'exécute la commande suivante à partir de ma ligne de commande sous Ubuntu:

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

Je reçois une réponse comme prévu

La PHP cURL documentations dit ceci:

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

Je crois que la raison pour laquelle cela fonctionne à partir de la ligne de commande est parce que Tor (le proxy) résout le nom d'hôte .onion, qu'il reconnaît. Lors de l'exécution du code PHP ci-dessus, je suppose que cURL ou PHP tente de résoudre le nom d'hôte .onion et ne le reconnaît pas. J'ai cherché un moyen de dire à cURL/PHP de laisser le proxy résoudre le nom d'hôte, mais je ne trouve pas de moyen.

Il existe une question de débordement de pile très similaire, la requête cURL utilisant le proxy socks5 échoue lors de l'utilisation de PHP, mais elle fonctionne via la ligne de commande.

333
frosty

On dirait que CURLPROXY_SOCKS5_HOSTNAME n'est pas défini en PHP, mais vous pouvez utiliser explicitement sa valeur, qui vaut 7:

curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
95
dr.scre

J'utilise Privoxy et cURL pour gratter les pages 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);
?>

Après avoir installé Privoxy, vous devez ajouter cette ligne au fichier de configuration (/etc/privoxy/config). Notez l'espace et '.' une fin de ligne.

forward-socks4a / localhost:9050 .

Puis redémarrez Privoxy.

/etc/init.d/privoxy restart
19
FattyPotatoes

Essayez d'ajouter ceci:

curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); 
7

TL; DR: Configurez _CURLOPT_PROXYTYPE_ pour utiliser _CURLPROXY_SOCKS5_HOSTNAME_ si vous avez un PHP moderne, la valeur _7_ sinon, et/ou corrigez la valeur _CURLOPT_PROXY_.

Comme vous l'avez correctement déduit, vous ne pouvez pas résoudre les domaines _.onion_ via le système DNS normal, car il s'agit de n domaine de premier niveau réservé spécifiquement utilisé par Tor et, de par leur conception, ne possède pas d'adresse IP. mapper à.

Utiliser _CURLPROXY_SOCKS5_ ordonnera à la commande cURL d’envoyer son trafic au proxy, mais ne le fera pas pour la résolution du nom de domaine. Les demandes DNS, qui sont émises avant que le cURL tente d'établir la connexion réelle avec le site Onion, seront toujours envoyées au résolveur DNS normal du système. Ces requêtes DNS vont sûrement échouer, car le résolveur DNS normal du système ne saura pas quoi faire avec une adresse _.onion_, à moins que cette dernière ne transmette également de telles requêtes à Tor.

Au lieu de _CURLPROXY_SOCKS5_, vous devez utiliser CURLPROXY_SOCKS5_HOSTNAME . Alternativement, vous pouvez également utiliser _CURLPROXY_SOCKS4A_, mais SOCKS5 est de loin préféré. L'un ou l'autre de ces types de proxy indique à cURL d'effectuer à la fois ses recherches DNS et son transfert de données réel via le proxy. Cela est nécessaire pour résoudre avec succès n'importe quel domaine _.onion_.

Il y a également deux autres erreurs dans le code de la question initiale qui n'ont pas encore été corrigées par les précédents commentateurs. Ceux-ci sont:

  • Point-virgule manquant à la fin de la ligne 1.
  • La valeur de l'adresse proxy est définie sur une URL HTTP, mais son type est SOCKS; ceux-ci sont incompatibles. Pour les mandataires SOCKS, la valeur doit être une combinaison d'adresse IP ou de nom de domaine et de numéro de port sans schéma/protocole/préfixe.

Voici le code correct dans son intégralité, avec des commentaires pour indiquer les modifications.

_<?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);
_

Vous pouvez également omettre complètement le réglage _CURLOPT_PROXYTYPE_ en modifiant la valeur _CURLOPT_PROXY_ pour inclure le préfixe _socks5h://_:

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