proxy onion - Как я могу подключиться к скрытой службе Tor, используя cURL в PHP?





(4)


Похож, что CURLPROXY_SOCKS5_HOSTNAME не определен в PHP, но вы можете явно использовать его значение, равное 7:

curl_setopt($ch, CURLOPT_PROXYTYPE, 7);

Я пытаюсь подключиться к скрытой службе Tor, используя следующий код PHP:

$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 hostname, которое он распознает. При запуске PHP-кода выше, я предполагаю, что cURL или PHP пытается разрешить имя .onion hostname и не распознает его. Я искал способ сообщить cURL / PHP, чтобы прокси-сервер разрешил имя хоста, но я не могу найти способ.

Существует очень похожий вопрос переполнения стека, запрос cURL с использованием прокси-сервера socks5 не работает при использовании PHP, но он работает через командную строку .




Попытайтесь добавить это:

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



Я использую 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



ПРИМЕЧАНИЕ ДЛЯ PHP 7

Чтобы обновить этот ответ, поскольку он приобрел некоторую популярность: этот ответ больше не применяется с PHP 7. Как поясняется в « Отказоустойчивых изменениях », в PHP 7 foreach работает с копией массива, поэтому любые изменения в самом массиве не отражаются на петле foreach. Подробнее по ссылке.

Объяснение (цитата из php.net ):

Первая форма петли над массивом, заданным выражением array_expression. На каждой итерации значение текущего элемента присваивается значению $, а указатель внутреннего массива продвигается на один (так что на следующей итерации вы будете смотреть на следующий элемент).

Итак, в вашем первом примере у вас есть только один элемент в массиве, и когда указатель перемещается, следующий элемент не существует, поэтому после добавления новых элементов foreach заканчивается, потому что он уже «решил», что это он как последний элемент.

Во втором примере вы начинаете с двух элементов, а цикл foreach не находится в последнем элементе, поэтому он вычисляет массив на следующей итерации и, таким образом, понимает, что в массиве есть новый элемент.

Я считаю, что это все последствия на каждой итерационной части объяснения в документации, что, вероятно, означает, что foreachвся логика до этого вызывает код {}.

Прецедент

Если вы запустите это:

<?
    $array = Array(
        'foo' => 1,
        'bar' => 2
    );
    foreach($array as $k=>&$v) {
        $array['baz']=3;
        echo $v." ";
    }
    print_r($array);
?>

Вы получите этот результат:

1 2 3 Array
(
    [foo] => 1
    [bar] => 2
    [baz] => 3
)

Это означает, что он принял модификацию и прошел через нее, потому что она была изменена «во времени». Но если вы это сделаете:

<?
    $array = Array(
        'foo' => 1,
        'bar' => 2
    );
    foreach($array as $k=>&$v) {
        if ($k=='bar') {
            $array['baz']=3;
        }
        echo $v." ";
    }
    print_r($array);
?>

Ты получишь:

1 2 Array
(
    [foo] => 1
    [bar] => 2
    [baz] => 3
)

Это означает, что массив был изменен, но поскольку мы изменили его, когда он foreachуже был в последнем элементе массива, он «решил» больше не зацикливаться, и хотя мы добавили новый элемент, мы добавили его «слишком поздно», и это не зацикливался.

Подробное объяснение можно прочитать в разделе «Как работает PHP foreach»? что объясняет внутренности, стоящие за этим поведением.





php curl proxy tor