我试图连接到使用下面的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的卷曲单证这样说:
--socks5-hostname
Use the specified SOCKS5 proxy (and let the proxy resolve the host name).
我相信,在命令行工作的原因是因为托尔(代理)是解决.onion主机名,经其认可。 当运行上面的PHP代码,我的猜测是,卷曲或PHP是试图解决.onion主机名,不承认它。 我所搜寻的方式来告诉卷曲/ PHP让代理解析主机名,但我不能找到一种方法。
有一个非常类似的堆栈溢出的问题, 使用socks5代理失败使用PHP时卷曲的要求,但它的工作原理通过命令行 。
貌似CURLPROXY_SOCKS5_HOSTNAME
没有在PHP中定义的,但你可以明确地使用它的价值,这等于7:
curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
我用Privoxy的和卷曲刮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
尝试添加此:
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
TL; DR:设置CURLOPT_PROXYTYPE
使用CURLPROXY_SOCKS5_HOSTNAME
如果你有一个现代化的PHP,值7
,否则,和/或纠正CURLOPT_PROXY
值。
当你正确地推论,你解决不了.onion
通过正常的DNS系统域,因为这是专供Tor的保留顶级域名和域名等设计都没有IP地址映射到。
使用CURLPROXY_SOCKS5
将直接卷曲命令其流量发送到代理,但不会做域名解析相同。 该DNS请求,卷曲试图建立与洋葱现场实际连接之前被发出,仍然会被发送到系统的正常DNS解析器。 这些DNS请求一定会失败,因为系统的正常DNS解析程序将不知道该怎么做了.onion
地址,否则它也专门转发这样的查询托尔。
取而代之的CURLPROXY_SOCKS5
,你必须使用CURLPROXY_SOCKS5_HOSTNAME
。 另外,您也可以使用CURLPROXY_SOCKS4A
,但SOCKS5,但最好。 任一这些类型的代理的通知卷曲以执行它的两个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_PROXYTYPE
完全改变CURLOPT_PROXY
值包括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');