makag Posted January 2, 2019 Report Share Posted January 2, 2019 (edited) Данная статья-обзор не претендует на 100% достоверность и является лишь попыткой систематизировать и изложить в понятном виде то, что стало известно мне самому. Критика и дополнения - приветствуются © 2019 ra.by (makag) Прокси-сервер (от англ. proxy — «представитель», «уполномоченный») — промежуточный сервер (комплекс программ), выполняющий роль посредника между пользователем и целевым сервером. Сначала клиент подключается к прокси-серверу, тот в свою очередь отправляет запрос дальше, на целевой ресурс и возвращает клиенту ответ (в неизменном либо модифицированном виде). © википедия Наглядно это можно представить в таком виде: Прокси-сервера могут использоваться в следующих целях: - кеширование внешних ресурсов прокси-сервером, с целью минимизации внешнего трафика; - контроль(ограничение) доступа к внешним ресурсам в сети интернет, учёт трафика; - обход ограничений (блокировок); - анонимизация доступа к различным ресурсам. Используя прокси для анонимизации доступа (например при использовании социальных сетей) следует знать, что не все прокси анонимны. Это означает, что даже используя прокси - нельзя быть уверенным в том, что прокси не передаёт ваш ip адрес в служебных заголовках на конечный сервер. По степени анонимности соответственно принято разделять прокси на: - прозрачные (transparent) - такой прокси передаёт ваш ip адрес дальше, т.е. об анонимности речь вообще не идёт. Такие прокси используются в тех случаях, когда нужна не анонимность, а просто обход блокировки вебсайта в локальной сети или в стране; - анонимные (anonymous) - такой прокси скрывает ваш ip адрес, но при этом не скрывает самого факта, что используется прокси сервер; - искажающие (distorting) - прокси также не скрывает факт использования прокси-сервера, но вместо вашего ip в служебных заголовках передаёт совершенно другой ip адрес; - элитные (elite) - прокси скрывают сам факт использования прокси сервера. По способу авторизации прокси можно разделить на: а) Прокси без авторизации. Такими прокси может воспользоваться любой, кому стали известны ip адрес и порт доступа к прокси б) Прокси с авторизацией по IP. Такие прокси строго привязаны к ip адресу пользователя, посторонний не сможет использовать такой прокси. в) Прокси с авторизацией по логину и паролю. Прокси запрашивает у пользователя логин и пароль и только после авторизации передаёт/принимает данные г) Возможны и иные варианты. В частности доступ по user agent (используемому браузеру), в том числе с комбинацией вариантов "б" и "в". По задачам, которые призваны решать прокси, их можно разделить их на: CGI прокси (так называемые анонимайзеры) - как правило выполнены в виде веб-сайта, который открывается в любом браузере. Далее - строка ввода адреса и окно, отображающее содержимое запрашиваемого вебсайта. Используется в офисах, где злой админ закрыл доступ на порнохаб и в странах, где запрещён фейсбук, вконтакте или твитер. Пример такого анонимайзера: noblockme.ru FTP прокси предназначен для загрузки данных на FTP сервер. SMTP, POP3 и IMAP прокси - используются для отправки, приёма и фильтрации электронной почты HTTP прокси - самый распространенный тип прокси, используется браузерами (и не только) для передачи информации по TCP протоколу. Информация при этом передаётся в открытом (не зашифрованном виде). Позволяет кешировать страницы/изображения и таким образом экономить внешний трафик. HTTPS прокси - фактически это HTTP-прокси, а загадочная буква "S" означает "secure" (защищенный) - с поддержкой защищенного соединения. Прокси-сервер соединяется с веб-сайтом и ваш трафик шифруется, в процессе шифрации и дешифрации сам прокси участия не принимает, то есть отследить какие именно данные передаются - сложнее. SOCKS4/SOCKS5 прокси - передача информации без каких-либо дополнительных модификаций (socks4 только по протоколу TCP, socks5 в том числе и по UDP). Все socks4/socks5 прокси как минимум анонимны. В socks4 не поддерживается авторизация клиента через "логин:пароль", в то время, как в socks5 такая возможность есть. Технические аспекты (переменные окружения) При соединении с веб-сервером ему в заголовках (служебная информация) передаются такие переменные: - название и версия операционной системы; - название и версия браузера; - индивидуальные настройки браузера и операционной системы (разрешение экрана, глубина цвета, поддержка javascript и т.п.); - используется ли proxy сервер; - если используется proxy, то может быть передан IP адрес конечного пользователя; - множество других данных. Примерно понять, что именно знает о вас сторонний сайт, можно заглянув по адресу: whoer.net/ru Как выглядят переменные, сообщающие веб-серверу об использовании прокси сервера. 1) Если прокси не используется то заголовки будут выглядеть так: REMOTE_ADDR = Ваш IPHTTP_VIA = не определёнHTTP_X_FORWARDED_FOR = не определён 2) При использовании прозрачного (transparent) прокси эти заголовки будут выглядеть так: REMOTE_ADDR = IP proxyHTTP_VIA = IP или имя прокси сервераHTTP_X_FORWARDED_FOR = Ваш IP 3) При использовании анонимного (anonymous) прокси эти заголовки будут выглядеть так: REMOTE_ADDR = IP proxyHTTP_VIA = IP или имя прокси сервераHTTP_X_FORWARDED_FOR = IP адрес прокси 4) При использовании искажающего (distorting) прокси эти заголовки будут выглядеть так: REMOTE_ADDR = IP proxy HTTP_VIA = не определён HTTP_X_FORWARDED_FOR = случайный IP 5) При использовании анонимного (anonymous) прокси эти заголовки будут выглядеть так: REMOTE_ADDR = IP proxy HTTP_VIA = не определёнHTTP_X_FORWARDED_FOR = не определён Определение типа прокси средствами php и curl Определить тип прокси - прозрачный, анонимный, искажающий или элитный - можно совершив запрос на заранее подготовленную страницу и проанализировав полученный ответ (в соответствии с пятью вариантами заголовков из раздела выше). Хороший вариант - использование веб-сайта proxyjudge.info Несмотря на то, что у http/https прокси порты для соединения обычно 80/8080, а у socks4/socks5 обычно порт 3128, на самом деле прокси может находится на любом порту и определить визуально (по номеру порта) конкретный тип прокси - невозможно. Определение типа прокси - http/https либо socks4/socks5/socks5 с авторизацией - возможно только лишь поочерёдно осуществляя запросы с различными параметрами. 1) Запрос curl без использования прокси $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); $data = curl_exec($ch); 2) Запрос curl по протоколу HTTP Цитата $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); 3) Запрос curl по протоколу HTTPS Цитата $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); 4) Запрос curl по протоколу SOCKS4 Цитата $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); 5) Запрос curl по протоколу SOCKS5 Цитата $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); 6) Запрос curl по протоколу SOCKS5 с авторизацией клиента по логину и паролю: Цитата curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_pass); $data = curl_exec($ch); На данный момент при проверке прокси я отправляю подряд запросы от №6 до №2 с таймаутом 7 секунд, то есть, чтобы достоверно сказать, что прокси - "не рабочий" у меня уходит на это целых 35 секунд, следующим образом: 1) изначально при добавлении прокси в базу mysql - тип прокси неясен, поле "proxy_type" оставляю пустым 2) php файл detect.php, при обращении к которому выводят служебные заголовки, следующего содержания: <?php $remote = $_SERVER['REMOTE_ADDR']; if (isset($remote)) { echo "external ip $remote"; } $via = $_SERVER['HTTP_VIA']; if (isset($via)) { echo "via $via"; } $fwd = $_SERVER['HTTP_X_FORWARDED_FOR']; if (isset($fwd)) { echo "fwd $fwd"; } ?> 3) функции для запросов к файлу посредством curl как http/https/socks4/socks5/socks5 с авторизацией, соответственно check_proxy1/check_proxy2/check_proxy4/check_proxy5/check_proxy55 function check_proxy1($page, $user_agent, $proxy_ip) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 200 && strpos($data, "via") === false) { return "1 ELIT"; } if ($http_code == 200 && strpos($data, $_SERVER['SERVER_ADDR']) === false) { return "1 ANON"; } if ($http_code <> 200) { return "http_code $http_code"; } curl_close($ch); } function check_proxy2($page, $user_agent, $proxy_ip) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 200 && strpos($data, "via") === false) { return "2 ELIT"; } if ($http_code == 200 && strpos($data, $_SERVER['SERVER_ADDR']) === false) { return "2 ANON"; } if ($http_code <> 200) { return "http_code $http_code"; } curl_close($ch); } function check_proxy4($page, $user_agent, $proxy_ip) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 200 && strpos($data, "via") === false) { return "4 ELIT"; } if ($http_code == 200 && strpos($data, $_SERVER['SERVER_ADDR']) === false) { return "4 ANON"; } if ($http_code <> 200) { return "http_code $http_code"; } curl_close($ch); } function check_proxy5($page, $user_agent, $proxy_ip) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 200 && strpos($data, "via") === false) { return "5 ELIT"; } if ($http_code == 200 && strpos($data, $_SERVER['SERVER_ADDR']) === false) { return "5 ANON"; } if ($http_code <> 200) { return "http_code $http_code"; } curl_close($ch); } function check_proxy55($page, $user_agent, $proxy_ip, $proxy_pass) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $page); curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 7); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); curl_setopt($ch, CURLOPT_PROXY, $proxy_ip); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy_pass); $data = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 200 && strpos($data, "via") === false) { return "55 ELIT"; } if ($http_code == 200 && strpos($data, $_SERVER['SERVER_ADDR']) === false) { return "55 ANON"; } if ($http_code <> 200) { return "http_code $http_code"; } curl_close($ch); } 4) И собственно попытки определить тип прокси: Цитата if ((strlen($proxy_ip) > 4) and (strlen($proxy_pass) > 4)) { $proxy_type = 55; $time_1 = microtime(1); $checker = check_proxy55($page, $user_agent, $proxy_ip, $proxy_pass); $time_2 = microtime(1); $time_3 = round($time_2 - $time_1, 2); $is55 = preg_match("/(55)( )([A-Z]{1,4})/", "$checker"); if ($is55 == 1) { $proxy_rank = 1; $query = "UPDATE vkproxy SET proxy_type = '$proxy_type', proxy_qual = '$time_3', proxy_rank = '$proxy_rank' WHERE num = '$key'"; $fill_db = mysqli_query($link, $query); } if ($is55 == 0) {$query = "DELETE FROM vkproxy WHERE (`num`='$key')"; $delete_proxy = mysqli_query($link, $query); } } if ((strlen($proxy_ip) > 4) and (strlen($proxy_pass) < 4)) { $time_1 = microtime(1); $checker = check_proxy5($page, $user_agent, $proxy_ip); $time_2 = microtime(1); $time_3 = round($time_2 - $time_1, 2); $is5 = preg_match("/(5)( )([A-Z]{1,4})/", "$checker"); if ($is5 == 1) { $proxy_type = 5; $proxy_rank = 1; $query = "UPDATE vkproxy SET proxy_type = '$proxy_type', proxy_qual = '$time_3', proxy_rank = '$proxy_rank' WHERE num = '$key'"; $fill_db = mysqli_query($link, $query); } if ($is5 == 0) { $time_1 = microtime(1); $checker = check_proxy4($page, $user_agent, $proxy_ip); $time_2 = microtime(1); $time_3 = round($time_2 - $time_1, 2); $is4 = preg_match("/(4)( )([A-Z]{1,4})/", "$checker"); if ($is4 == 1) { $proxy_type = 4; $proxy_rank = 1; $query = "UPDATE vkproxy SET proxy_type = '$proxy_type', proxy_qual = '$time_3', proxy_rank = '$proxy_rank' WHERE num = '$key'"; $fill_db = mysqli_query($link, $query); } if ($is4 == 0) { $time_1 = microtime(1); $checker = check_proxy2($page, $user_agent, $proxy_ip); $time_2 = microtime(1); $time_3 = round($time_2 - $time_1, 2); $is2 = preg_match("/(1)( )([A-Z]{1,4})/", "$checker"); if ($is2 == 1) { $proxy_type = 2; $proxy_rank = 1; $query = "UPDATE vkproxy SET proxy_type = '$proxy_type', proxy_qual = '$time_3', proxy_rank = '$proxy_rank' WHERE num = '$key'"; $fill_db = mysqli_query($link, $query); } if ($is2 == 0) { $time_1 = microtime(1); $checker = check_proxy1($page, $user_agent, $proxy_ip); $time_2 = microtime(1); $time_3 = round($time_2 - $time_1, 2); $is1 = preg_match("/(1)( )([A-Z]{1,4})/", "$checker"); if ($is1 == 1) { $proxy_type = 1; $proxy_rank = 1; $query = "UPDATE vkproxy SET proxy_type = '$proxy_type', proxy_qual = '$time_3', proxy_rank = '$proxy_rank' WHERE num = '$key'"; $fill_db = mysqli_query($link, $query); } if ($is1 == 0) { $query = "DELETE FROM vkproxy WHERE (`num`='$key')"; $delete_proxy = mysqli_query($link, $query); } } } } } Предполагаю, что используя curl_multi_init можно сократить время проверки. Но поскольку данная область мною ещё не освоена - лучше помолчу и дополню пост, когда будет что сказать. Всем спасибо за внимание. Edited January 3, 2019 by makag 2 Quote Link to comment Share on other sites More sharing options...
akterak Posted December 5, 2020 Report Share Posted December 5, 2020 Подскажите столкнулся с след. проблемой. Используя прокси паблик в скриптах php (в частности socks4), не работают post запросы - получаю пустой ответ (например если нужно где авторизоваться), get запросы проходят на ура... Это связано с самими проксями? пробывал юзать скрипты без прокси через proxyfair(сокс4) тоже самое.... Quote Link to comment Share on other sites More sharing options...
makag Posted December 5, 2020 Author Report Share Posted December 5, 2020 39 минут назад, akterak сказал: не работают post запросы - получаю пустой ответ (например если нужно где авторизоваться), get запросы проходят на ура.. 40 минут назад, akterak сказал: пробывал юзать скрипты без прокси через proxyfair(сокс4) тоже самое.... по всей видимости да, дело в проксях.. Quote Link to comment Share on other sites More sharing options...
akterak Posted December 5, 2020 Report Share Posted December 5, 2020 23 минуты назад, makag сказал: по всей видимости да, дело в проксях.. еще читал, что дело может быть в порте, якобы через стандартные работает (1080, 8080), а через другие (например 4145) уже нет...в чем тут может быть связь? может нужно что-то менять в файлах настройки/curl'a или открыть порты специально на винде ? Quote Link to comment Share on other sites More sharing options...
makag Posted December 5, 2020 Author Report Share Posted December 5, 2020 (edited) 14 минут назад, akterak сказал: еще читал, что дело может быть в порте, якобы через стандартные работает (1080, 8080), а через другие (например 4145) уже нет...в чем тут может быть связь? не, это бред, имхо через какой порт работает конкретный прокси - определяет администратор прокси сервера при его создании / конфигурации. по умолчанию традиционно http/https работают на 80, 8080 например, сокс на 1080 по факту можно установить любой порт. если гет запросы проходят, а пост запросы не проходят - дело не винде на мой взгляд варианта всего два: - конкретные прокси не работают с пост запросами (на публичных прокси такое в принципе возможно) - ошибка в коде и пост запросы не работают вообще. Второй вариант, с ошибкой в коде, маловероятен -т.к. через другие прокси (http, socks5 и без прокси) пост запросы работают точно также, независимо от вида прокси. Следовательно дело именно в конкретных прокси и их настройках. Для паблик прокси это возможно даже норма - чтобы не злоупотребляли, не нагружали проксю - разрешают только гет запросы. Edited December 5, 2020 by makag Quote Link to comment Share on other sites More sharing options...
akterak Posted December 5, 2020 Report Share Posted December 5, 2020 Понял, спасибо. Quote Link to comment Share on other sites More sharing options...
Recommended Posts