Jump to content
RA.BY
Sign in to follow this  
makag

Какие бывают прокси и чем они различаются, определение типа прокси средствами php(curl)

Recommended Posts

Данная статья-обзор не претендует на 100% достоверность

и является лишь попыткой систематизировать и изложить 

в понятном виде то, что стало известно мне самому.

Критика и дополнения - приветствуются

© 2019 ra.by (makag)

 

 

Прокси-сервер (от англ. proxy — «представитель», «уполномоченный») — промежуточный сервер (комплекс программ), выполняющий роль посредника между пользователем и целевым сервером. 

 

Сначала клиент подключается к прокси-серверу, тот в свою очередь отправляет запрос дальше, на целевой ресурс и возвращает клиенту ответ (в неизменном либо модифицированном виде). ©

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.

 

Наглядно это можно представить в таком виде:

 

image.png.c215f14832c57fe440620b69a2994eb7.png

 


 

Прокси-сервера могут использоваться в следующих целях:

- кеширование внешних ресурсов прокси-сервером, с целью минимизации внешнего трафика;

- контроль(ограничение) доступа к внешним ресурсам в сети интернет, учёт трафика;

- обход ограничений (блокировок);

- анонимизация доступа к различным ресурсам.

 

Используя прокси для анонимизации доступа (например при использовании социальных сетей) следует знать, что не все прокси анонимны. Это означает, что даже используя прокси - нельзя быть уверенным в том, что прокси не передаёт ваш 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 адрес конечного пользователя;

- множество других данных.

 

Примерно понять, что именно знает о вас сторонний сайт, можно заглянув по адресу: 

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.

 

Как выглядят переменные, сообщающие веб-серверу об использовании прокси сервера.

 

1) Если прокси не используется то заголовки будут выглядеть так:

REMOTE_ADDR = Ваш IP
HTTP_VIA = не определён
HTTP_X_FORWARDED_FOR = не определён

 

2) При использовании прозрачного (transparent) прокси эти заголовки будут выглядеть так:

REMOTE_ADDR = IP proxy
HTTP_VIA = IP или имя прокси сервера
HTTP_X_FORWARDED_FOR = Ваш IP

 

3) При использовании анонимного (anonymous) прокси эти заголовки будут выглядеть так:

REMOTE_ADDR = IP proxy
HTTP_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

 

Определить тип прокси - прозрачный, анонимный, искажающий или элитный - можно совершив запрос на заранее подготовленную страницу и проанализировав полученный ответ (в соответствии с пятью вариантами заголовков из раздела выше).  Хороший вариант - использование веб-сайта 

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.


Несмотря на то, что у http/https прокси порты для соединения обычно 80/8080, а у socks4/socks5 обычно порт 3128, на самом деле прокси может находится на любом порту и определить визуально (по номеру порта) конкретный тип прокси  - невозможно.

 

Определение  типа прокси  - http/https либо socks4/socks5/socks5 с авторизацией -  возможно только лишь поочерёдно осуществляя запросы с различными параметрами.

 

1) Запрос curl без использования прокси

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.

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, при обращении к которому выводят служебные заголовки, следующего содержания:
 

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.

3) функции для запросов к файлу посредством curl как http/https/socks4/socks5/socks5 с авторизацией, соответственно check_proxy1/check_proxy2/check_proxy4/check_proxy5/check_proxy55

Пожалуйста, войдите или зарегистрируйтесь для просмотра скрытого контента.

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 by makag
  • Upvote 2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×