470 Stimmen

Wie kann ich mich mit einem Tor Hidden Service unter Verwendung von cURL in PHP verbinden?

Ich versuche, eine Verbindung zu einem Tor Hidden Service mit folgendem PHP-Code 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, erhalte ich den folgenden Fehler:

Konnte den Hostnamen nicht auflösen

Wenn ich jedoch folgenden Befehl in meinem Ubuntu-Terminal ausführe:

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

erhalte ich eine erwartete Antwort.

Die PHP cURL Dokumentation sagt dies:

--socks5-hostname
Verwenden  Sie  den  angegebenen  SOCKS5 Proxy (und lassen Sie den Proxy den Hostnamen auflösen).

Ich glaube, dass es vom Befehlszeilen-Terminal funktioniert, weil Tor (der Proxy) den .onion Hostnamen auflöst, den es erkennt. Beim Ausführen des obigen PHP-Codes ist meine Vermutung, dass cURL oder PHP versucht, den .onion Hostnamen aufzulösen und ihn nicht erkennt. Ich habe nach einer Möglichkeit gesucht, cURL/PHP mitzuteilen, dass der Proxy den Hostnamen auflösen soll, aber ich kann keinen Weg finden.

Es gibt eine sehr ähnliche Stack Overflow Frage, cURL-Anfrage mit Socks5-Proxy schlägt in PHP fehl, funktioniert aber über die Befehlszeile.

117voto

dr.scre Punkte 2167

Sie müssen die Option CURLOPT_PROXYTYPE auf CURLPROXY_SOCKS5_HOSTNAME setzen, die leider in alten PHP-Versionen vor etwa 5.6 nicht definiert war; falls Sie eine frühere Version haben können Sie jedoch explizit den Wert verwenden, der gleich 7 ist:

curl_setopt($ch, CURLOPT_PROXYTYPE, 7);

23voto

FattyPotatoes Punkte 793

Ich verwende Privoxy und cURL, um Tor-Seiten abzurufen:

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

forward-socks4a / localhost:9050 .

Dann starten Sie Privoxy neu.

/etc/init.d/privoxy restart

9voto

Versuche dies hinzuzufügen:

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

9voto

M12 Punkte 679

TL;DR: Set CURLOPT_PROXYTYPE auf CURLPROXY_SOCKS5_HOSTNAME, wenn Sie ein modernes PHP haben, andernfalls den Wert 7 verwenden und/oder den Wert von CURLOPT_PROXY korrigieren.

Wie Sie richtig erkannt haben, können .onion-Domains nicht über das normale DNS-System aufgelöst werden, da dies eine reservierte Top-Level-Domain speziell für die Verwendung durch Tor ist und solche Domains von Design keine IP-Adressen zugeordnet haben.

Die Verwendung von CURLPROXY_SOCKS5 leitet den cURL-Befehl an den Proxy weiter, löst jedoch nicht den Domainnamen auf. Die DNS-Anfragen, die bevor cURL versucht, die tatsächliche Verbindung mit der Onion-Seite herzustellen, ausgegeben werden, werden dennoch an den normalen DNS-Resolver des Systems gesendet. Diese DNS-Anfragen werden sicher fehlschlagen, da der normale DNS-Resolver des Systems nicht weiß, was mit einer .onion-Adresse anzufangen ist, es sei denn, auch er leitet solche Anfragen explizit an Tor weiter.

Statt CURLPROXY_SOCKS5 müssen Sie CURLPROXY_SOCKS5_HOSTNAME verwenden. Alternativ können Sie auch CURLPROXY_SOCKS4A verwenden, aber SOCKS5 ist deutlich bevorzugt. Diese Proxytypen informieren cURL, sowohl seine DNS-Lookups als auch den eigentlichen Datentransfer über den Proxy durchzuführen. Dies ist erforderlich, um jede .onion-Domain erfolgreich aufzulösen.

Es gibt auch zwei zusätzliche Fehler im Code in der Ursprungsfrage, die bisher von früheren Kommentatoren nicht korrigiert wurden. Dies sind:

  • Fehlendes Semikolon am Ende von Zeile 1.
  • Der Proxy-Adresswert ist auf eine HTTP-URL gesetzt, aber sein Typ ist SOCKS; diese sind inkompatibel. Für SOCKS-Proxies muss der Wert eine IP oder eine Kombination aus Domainnamen und Portnummer ohne Schema/Protokoll/Präfix sein.

Hier ist der vollständige korrekte Code, mit Kommentaren, die die Änderungen anzeigen.

`Sie können auch das Setzen vonCURLOPT_PROXYTYPEganz weglassen, indem Sie den Wert vonCURLOPT_PROXYändern, um das Präfixsocks5h://` einzuschließen:

// Beachten Sie das Fehlen des abschließenden Schrägstrichs, da dies eine SOCKS-Adresse, keine HTTP-URL ist.
curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050');``

0voto

Pushkraj Jori Punkte 103

Hier ist eine einfache Funktion, um Ihnen zu helfen. Um Zeit zu sparen, müssen Sie zuerst sicherstellen, dass Sie überprüfen, ob der Proxy gültig ist oder nicht, indem Sie einfach mit fsocketopen() überprüfen

        try {
            $fp = fsockopen($ip, $port, $errno, $errstr, 10);
            fclose($fp);
            return true;
        } catch (\Throwable $th) {
            return false;
        }

Wenn der Socket true zurückgibt, gehen Sie zur Funktion requestUrl

    private function requestUrl($url, $proxy)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_PROXY, $proxy);
        curl_setopt($curl, CURLOPT_HEADER, 1); 
        curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, 1); 
        curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        $contents = curl_exec($curl);
        //Überprüfen Sie auf Fehler.
        // if (curl_errno($curl)) {
        //     return new \Exception(curl_error($curl));
        // }
        curl_close($curl);
        return $contents;
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X