PHPでcURLを使用してTor非表示サービスに接続するにはどうすればよいですか?


366

次のPHPコードを使用してTor非表示サービスに接続しようとしています。

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

実行すると、次のエラーが発生します。

ホスト名を解決できませんでした

ただし、Ubuntuのコマンドラインから次のコマンドを実行すると、

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

期待通りに返事がある

PHP cURLドキュメントはこれを言います:

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

コマンドラインから機能する理由は、Tor(プロキシ)が認識している.onionホスト名を解決しているためだと思います。上記のPHPコードを実行すると、cURLまたはPHPが.onionホスト名を解決しようとし、それを認識しないと思います。プロキシにホスト名を解決させるようにcURL / PHPに指示する方法を探しましたが、方法が見つかりません。

非常によく似たスタックオーバーフローの質問があります。PHPを使用するとsocks5プロキシを使用したcURLリクエストが失敗しますが、コマンドラインを介して機能します。

回答:



21

私はPrivoxyとcURLを使って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);
?>

Privoxyをインストールした後、この行を構成ファイル(/etc/privoxy/config)に追加する必要があります。スペースと「。」に注意してください 行の終わり。

forward-socks4a / localhost:9050 .

次に、Privoxyを再起動します。

/etc/init.d/privoxy restart

これでうまくいきます!:両方のWindows 10およびCentOSの6でテストされ、また、Torは代わりソックス4のソックス5を使用する場合は、この使用forward-socks5 / localhost:9150 .
デヴィッドRefoua

これを機能させるには、TORとPrivoxyの両方が必要ですか?感謝


5

TL; DR:最新のPHP CURLOPT_PROXYTYPEを使用しているCURLPROXY_SOCKS5_HOSTNAME場合に使用するように設定し、7それ以外の場合は値を設定し、CURLOPT_PROXY値を修正します。

正しく推論.onionしたように、通常のDNSシステムを介してドメインを解決することはできません。これは、Torが使用するために予約されたトップレベルドメインであり、そのようなドメインには設計するIPアドレスがないためです。

を使用CURLPROXY_SOCKS5すると、cURLコマンドはそのトラフィックをプロキシに送信するように指示されますが、ドメイン名の解決については同じこと行われません。cURLがOnionサイトとの実際の接続を確立しようとする前に発行されるDNS要求は、引き続きシステムの通常のDNSリゾルバーに送信されます。システムの通常のDNSリゾルバーは.onion、特にそのようなクエリをTorに転送しない限り、アドレスをどうするかわからないため、これらのDNS要求は確実に失敗します。

の代わりにCURLPROXY_SOCKS5、を使用する必要がありますCURLPROXY_SOCKS5_HOSTNAME。または、を使用することもできますがCURLPROXY_SOCKS4A、SOCKS5を使用することをお勧めします。これらのプロキシタイプのいずれかは、DNSルックアップとプロキシ経由の実際のデータ転送の両方を実行するようにcURLに通知します。これは、.onionドメインを正常に解決するために必要です。

元の質問のコードには、以前のコメント投稿者によってまだ修正されていない2つの追加のエラーもあります。これらは:

  • 行1の終わりにセミコロンがありません。
  • プロキシアドレスの値はHTTP URLに設定されていますが、そのタイプはSOCKSです。これらには互換性がありません。SOCKSプロキシの場合、値は、スキーム/プロトコル/プレフィックスなしのIPまたはドメイン名とポート番号の組み合わせである必要があります。

変更を示すコメント付きの正しいコード全体を以下に示します。

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

値をCURLOPT_PROXYTYPE変更しCURLOPT_PROXYsocks5h://接頭辞を含めることにより、設定を完全に省略することもできます。

// Note no trailing slash, as this is a SOCKS address, not an HTTP URL.
curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.