Wie kann ich mit cURL in PHP eine Verbindung zu einem versteckten Tor-Dienst herstellen?

366

Ich versuche, mit dem folgenden PHP-Code eine Verbindung zu einem versteckten Tor-Dienst herzustellen:

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

Wenn ich es ausführe, wird folgende Fehlermeldung angezeigt:

Hostname konnte nicht aufgelöst werden

Wenn ich jedoch den folgenden Befehl über meine Befehlszeile in Ubuntu ausführe:

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

Ich bekomme wie erwartet eine Antwort

In den PHP cURL- Dokumentationen heißt es:

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

Ich glaube, der Grund, warum es über die Befehlszeile funktioniert, ist, dass Tor (der Proxy) den .onion-Hostnamen auflöst, den er erkennt. Wenn Sie den obigen PHP-Code ausführen, vermute ich, dass cURL oder PHP versucht, den .onion-Hostnamen aufzulösen, und ihn nicht erkennt. Ich habe nach einer Möglichkeit gesucht, cURL / PHP anzuweisen, dass der Proxy den Hostnamen auflösen soll, aber ich kann keinen Weg finden.

Es gibt eine sehr ähnliche Frage zum Stapelüberlauf : Die cURL-Anforderung mit dem socks5-Proxy schlägt bei Verwendung von PHP fehl, funktioniert jedoch über die Befehlszeile .

eisig
quelle

Antworten:

21

Ich benutze Privoxy und cURL, um Tor-Seiten zu kratzen:

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

Nach der Installation von Privoxy müssen Sie diese Zeile zur Konfigurationsdatei ( /etc/privoxy/config) hinzufügen . Beachten Sie das Leerzeichen und '.' a das Zeilenende.

forward-socks4a / localhost:9050 .

Starten Sie dann Privoxy neu.

/etc/init.d/privoxy restart
FattyPotatoes
quelle
Das funktioniert! Getestet unter Windows 10 und CentOS 6, auch wenn Tor Socks 5 anstelle von Socks 4 verwendet, verwenden Sie dies:forward-socks5 / localhost:9150 .
David Refoua
Benötige ich TOR und Privoxy, damit dies funktioniert? danke
8

Versuchen Sie Folgendes hinzuzufügen:

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

TL; DR: Wird CURLOPT_PROXYTYPEverwendet, CURLPROXY_SOCKS5_HOSTNAMEwenn Sie ein modernes PHP haben, den Wert 7anderweitig und / oder den CURLOPT_PROXYWert korrigieren .

Wie Sie richtig festgestellt haben, können Sie .onionDomains nicht über das normale DNS-System auflösen , da dies eine reservierte Top-Level-Domain ist, die speziell für die Verwendung durch Tor vorgesehen ist und solche Domains keine IP-Adressen haben, denen sie zugeordnet werden können.

Mit CURLPROXY_SOCKS5wird der Befehl cURL angewiesen, seinen Datenverkehr an den Proxy zu senden, bei der Auflösung von Domänennamen jedoch nicht . Die DNS-Anforderungen, die ausgegeben werden, bevor cURL versucht, die tatsächliche Verbindung mit der Onion-Site herzustellen, werden weiterhin an den normalen DNS-Resolver des Systems gesendet. Diese DNS-Anforderungen werden sicherlich fehlschlagen, da der normale DNS-Resolver des Systems nicht weiß, was mit einer .onionAdresse zu tun ist, es sei denn, er leitet solche Anfragen speziell an Tor weiter.

Stattdessen CURLPROXY_SOCKS5müssen Sie verwenden CURLPROXY_SOCKS5_HOSTNAME. Alternativ können Sie auch verwenden CURLPROXY_SOCKS4A, aber SOCKS5 wird sehr bevorzugt. Jeder dieser Proxy-Typen weist cURL an, sowohl die DNS-Suche als auch die tatsächliche Datenübertragung über den Proxy durchzuführen. Dies ist erforderlich, um eine .onionDomain erfolgreich aufzulösen .

Es gibt auch zwei zusätzliche Fehler im Code in der ursprünglichen Frage, die von früheren Kommentatoren noch korrigiert werden müssen. Diese sind:

  • Fehlendes Semikolon am Ende von Zeile 1.
  • Der Proxy-Adresswert wird auf eine HTTP-URL festgelegt, der Typ lautet jedoch SOCKS. diese sind nicht kompatibel. Bei SOCKS-Proxys muss der Wert eine Kombination aus IP- oder Domänenname und Portnummer ohne Schema / Protokoll / Präfix sein.

Hier ist der korrekte Code mit Kommentaren zur Angabe der Änderungen.

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

Sie können die Einstellung auch CURLOPT_PROXYTYPEganz weglassen, indem Sie den CURLOPT_PROXYWert so ändern , dass er das socks5h://Präfix enthält:

// 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
quelle