How can I connect to a Tor hidden service using cURL in PHP?
我尝试使用以下PHP代码连接到Tor隐藏服务:
1 2 3 4 5 6 7 8 9 10 11 12 | $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); |
当我运行它时,我得到以下错误:
Couldn't resolve host name
号
但是,当我从Ubuntu中的命令行运行以下命令时:
1 | curl -v --socks5-hostname localhost:9050 http://jhiwjjlqpyawmpjx.onion |
号
我得到了预期的答复
php curl文档显示:
1 2 | --socks5-hostname Use the specified SOCKS5 proxy (and let the proxy resolve the host name). |
我相信它在命令行中工作的原因是Tor(代理)正在解析它识别的.洋葱主机名。当运行上面的PHP代码时,我猜想curl或php正在尝试解析.onion主机名,但无法识别它。我已经找到了一种方法来告诉curl/php让代理解析主机名,但是我找不到一种方法。
有一个非常类似的堆栈溢出问题:使用socks5代理的curl请求在使用php时失败,但它通过命令行工作。
看起来
1 |
我用privoxy和curl来刮纸:
1 2 3 4 5 6 7 8 9 | <?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后,需要将此行添加到配置文件(
1 | forward-socks4a / localhost:9050 . |
然后重启privoxy。
1 | /etc/init.d/privoxy restart |
。
尝试添加:
1 2 |
tl;dr:设置
正如您正确推断的那样,您不能通过普通的DNS系统解析
使用
您必须使用
在最初的问题中,代码中还有两个额外的错误尚未被以前的注释者纠正。这些是:
- 第1行末尾缺少分号。
- 代理地址值设置为HTTP URL,但其类型为SOCKS;这些是不兼容的。对于SOCKS代理,该值必须是没有方案/协议/前缀的IP或域名和端口号组合。
这里是完整的正确代码,带有注释以指示更改。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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); |
。
您也可以通过将
1 2 | // Note no trailing slash, as this is a SOCKS address, not an HTTP URL. curl_setopt(CURLOPT_PROXY, 'socks5h://127.0.0.1:9050'); |
。