Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумНастройка и подключение

PHP cURL и SOCKS5: рабочая связка

Слава Кудрин
Слава Кудрин
Участник
сообщений 760
с авг
8 февраля, 11:37первое сообщение

Переношу старый сборщик на сокетный туннель. Ставлю в CURLOPT_PROXY строку со схемой socks5, cURL падает на первом же запросе и пишет, что схема ему незнакома. Через обычный HTTP тот же адрес с той же парой логина с паролем отвечает нормально.

$ch = curl_init('https://example.org/catalog/1');
curl_setopt($ch, CURLOPT_PROXY, 'socks5://198.51.100.20:1080');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'login:pass');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
echo curl_error($ch);

Куда копать?

rawsocket
rawsocket
Ветеран
сообщений 2290
с фев
15 июля, 14:54#2

Схему внутри строки разбирают свежие сборки libcurl. Сборка постарше примет её частью имени хоста и пойдёт искать в сети сайт с названием socks5. Тип задавайте отдельным полем, так работает везде.

curl_setopt($ch, CURLOPT_PROXY, '198.51.100.20:1080');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);

Второе, что важнее: у сокетного туннеля два режима. CURLPROXY_SOCKS5 разбирает имя сайта на вашей машине и отдаёт в туннель готовый адрес. CURLPROXY_SOCKS5_HOSTNAME отправляет имя строкой, разбор идёт дальше по пути.

читаю байты, а потом уже документацию
Слава Кудрин
Слава Кудрин
Участник
сообщений 760
с авг
22 декабря, 17:11#3
rawsocket: разбирает имя сайта на вашей машине

Домен-то один и тот же. На что это влияет вживую?

Артур Вагнер
Артур Вагнер
Знаток
сообщений 1290
с мая
1 мая, 08:28#4

Влияет сильнее, чем кажется. Крупные сайты держат за одним именем десяток адресов и раздают их по близости к спрашивающему. Ваша машина спросила и получила тот узел, который ближе к вам. Туннель после этого лезет именно туда, хотя со стороны туннеля ближе совсем другой узел. Отклик подрастает, иногда вдвое.

Дальше веселее. Половина карточек приходит с одного узла, половина с другого, наполнение у них расходится на час-полтора. Вы потом сидите и гадаете, почему в выгрузке один товар в двух состояниях.

Третья беда бытовая: у машины внутри сети свой разборщик имён, наружу он не смотрит и про внешние домены знает ровно ничего. Тогда запрос умирает на разборе имени, ещё до открытия туннеля, и в логе вы видите ошибку, где про туннель ни слова.

С режимом HOSTNAME все три истории не возникают вовсе. У меня он стоит по умолчанию, обычный SOCKS5 включаю руками, когда надо посмотреть, что отдаёт локальный разборщик.

конфиг без комментария это загадка
veta_l
veta_l
Новичок
сообщений 210
с янв, второй сезон
8 октября, 11:45#5

а логин с паролем в сокетном варианте так же передаётся? у меня на входе ругань

rawsocket
rawsocket
Ветеран
сообщений 2290
с фев
15 марта, 14:02#6

Так же, CURLOPT_PROXYUSERPWD работает для обоих типов. Проверьте сборку: старые собирали SOCKS5 без поддержки входа по паролю, и тогда пара просто уезжает в пустоту.

Быстрее всего проверить из консоли, минуя PHP.

проверка туннеля до правки кода
проверка туннеля до правки кода

Если консоль ходит, а PHP нет, вопрос точно в опциях.

читаю байты, а потом уже документацию
hexdump
hexdump
Знаток
сообщений 940
с июн
22 августа, 17:19#7

У меня под PHP список лежит отдельно от кода. Беру приватные адреса с поддержкой SOCKS5, забираю выдачу в формате IP:PORT:LOGIN:PASS одной ссылкой, скрипт читает её при старте и раскладывает по полям. Файл руками не таскаю совсем, при обновлении пула он подтягивается сам.

[$host, $port, $user, $pw] = explode(':', trim($stroka));
curl_setopt($ch, CURLOPT_PROXY, "$host:$port");
curl_setopt($ch, CURLOPT_PROXYUSERPWD, "$user:$pw");
Слава Кудрин
Слава Кудрин
Участник
сообщений 760
с авг
1 января, 08:36#8

Поставил HOSTNAME отдельным полем, строку со схемой убрал. Пошло с первого раза, ошибка про схему исчезла.

Консольную проверку записал себе в заметки, штука полезная.

Юля Ким
Юля Ким
Знаток
сообщений 1240
с мая
8 июня, 11:53#9

Добавлю про грабли, на которые сама наступала. CURLOPT_HTTPPROXYTUNNEL сокетному варианту не нужен вовсе. Ставят его по привычке от HTTP и потом ловят странности на пустом месте. И обязательно выставьте CURLOPT_CONNECTTIMEOUT секунд на десять: без него зависший туннель держит скрипт до общего таймаута, и прогон стоит колом.

Слава Кудрин
Слава Кудрин
Участник
сообщений 760
с авг
15 ноября, 14:10#10

Таймаут поставил, спасибо. Гоняю вторые сутки, ошибок ноль.