锁定。对此问题的评论已被禁用,但它仍在接受新的答案和其他互动。学到更多。
我正在尝试使用以下 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 让代理解析主机名,但我找不到方法。
有一个非常相似的 Stack Overflow 问题,cURL request using socks5 proxy fails when using PHP, but it works through the command line。
您需要将选项 CURLOPT_PROXYTYPE
设置为 CURLPROXY_SOCKS5_HOSTNAME
,遗憾的是 wasn't defined in old PHP versions, circa pre-5.6;如果您之前有,但您可以显式使用它的值,它等于 7
:
curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
我使用 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
)。注意空格和'.' a 行尾。
forward-socks4a / localhost:9050 .
然后重新启动 Privoxy。
/etc/init.d/privoxy restart
尝试添加这个:
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
TL;DR:如果您有现代 PHP,请将 CURLOPT_PROXYTYPE
设置为使用 CURLPROXY_SOCKS5_HOSTNAME
,否则设置为 7
,和/或更正 CURLOPT_PROXY
值。
正如您正确推断的那样,您无法通过正常的 DNS 系统解析 .onion
域,因为这是 a reserved top-level domain specifically for use by Tor 并且此类域在设计上没有可映射到的 IP 地址。
使用 CURLPROXY_SOCKS5
将指示 cURL 命令将其流量发送到代理,但不会对域名解析执行相同的操作。在 cURL 尝试与 Onion 站点建立实际连接之前发出的 DNS 请求仍将发送到系统的正常 DNS 解析器。这些 DNS 请求肯定会失败,因为系统的普通 DNS 解析器不知道如何处理 .onion
地址,除非它也专门将此类查询转发给 Tor。
您必须使用 CURLPROXY_SOCKS5_HOSTNAME
而不是 CURLPROXY_SOCKS5
。或者,您也可以使用 CURLPROXY_SOCKS4A
,但更喜欢 SOCKS5。这些代理类型中的任何一种都会通知 cURL 执行其 DNS 查找和通过代理进行的实际数据传输。这是成功解析任何 .onion
域所必需的。
原始问题的代码中还有两个额外的错误尚未被先前的评论者纠正。这些是:
第 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_PROXY
值以包含 socks5h://
前缀来完全省略设置 CURLOPT_PROXYTYPE
:
// Note no trailing slash, as this is a SOCKS address, not an HTTP URL.
curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050');
这是一个简单的功能来帮助你。首先要节省时间,您需要确保通过 fsocketopen() 进行简单检查来检查代理是否有效
try {
$fp = fsockopen($ip, $port, $errno, $errstr, 10);
fclose($fp);
return true;
} catch (\Throwable $th) {
return false;
}
如果套接字返回 true,则使用 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);
//Check for errors.
// if (curl_errno($curl)) {
// return new \Exception(curl_error($curl));
// }
curl_close($curl);
return $contents;
}
不定期副业成功案例分享
forward-socks5 / localhost:9150 .