Уровни анонимности прокси: прозрачный, анонимный и элитный по заголовкам запроса
Уровней анонимности три: прозрачный передаёт сайту ваш исходный адрес открытым текстом, анонимный сообщает только сам факт работы через посредника, элитный не добавляет к запросу ни одного служебного заголовка. Различие целиком сидит в наборе полей, которые прокси дописывает к HTTP-запросу перед отправкой на целевой сервер.
Проверить уровень можно своими руками за минуту: один запрос через curl на страницу-эхо, которая возвращает полученные заголовки, и всё становится видно. Ниже мы разбираем каждый уровень по составу полей, показываем команды проверки, объясняем, почему у SOCKS5 понятия заголовков нет вовсе, и перечисляем признаки посредника, которые живут за пределами HTTP.
Откуда берутся служебные заголовки
HTTP-запрос это стартовая строка и набор пар «имя: значение». Браузер отправляет Host, User-Agent, Accept, Accept-Language, Cookie и ещё десяток полей. Прокси получает этот набор, при необходимости дописывает свои поля и отправляет дальше.
Дописывать поля прокси начал по причинам эксплуатации. Корпоративные шлюзы и кэширующие серверы ставили X-Forwarded-For, чтобы веб-сервер за ними видел настоящего клиента в логах. Балансировщики нагрузки делают то же самое до сих пор, и в их случае это работает на пользу владельцу сайта. Поле прижилось, вошло в привычку администраторов и потом получило стандартизованного наследника Forwarded.
Целевой сервер никак не отличает заголовок от балансировщика внутри своей же инфраструктуры от заголовка внешнего посредника. Он видит поле, читает значение и делает вывод о цепочке. Отсюда и берётся вся классификация уровней: набор дописанных полей определяет, что именно сайт узнает о маршруте запроса.
Единого стандарта на уровни при этом нет. Деление на прозрачный, анонимный и элитный пришло из практики администрирования и закрепилось в чекерах, поэтому разные проверялки иногда расходятся в оценке одного узла на полшага. Мы ориентируемся на состав полей в сыром запросе: он однозначен и проверяется в любую минуту. Название уровня вторично, набор заголовков первичен, и разговор о настройках всегда стоит вести именно в терминах полей.
Ещё одна деталь касается регистра и порядка полей. Имена заголовков нечувствительны к регистру, поэтому X-Forwarded-For и x-forwarded-for для сервера одно и то же. Порядок полей при этом значение имеет: он входит в отпечаток клиента, и посредник, который переставляет заголовки местами, оставляет след даже без добавления новых.
| Заголовок | Что несёт | Кто обычно ставит |
|---|---|---|
Via | Список пройденных посредников с версией протокола | Кэширующие и корпоративные прокси |
X-Forwarded-For | Исходный адрес клиента, иногда цепочка через запятую | Балансировщики, шлюзы, прозрачные прокси |
Forwarded | То же самое в стандартизованном виде с полями for, by, proto | Современные обратные прокси |
X-Real-IP | Один исходный адрес без цепочки | nginx в роли обратного прокси |
Proxy-Connection | Управление соединением между клиентом и прокси | Старые браузеры и HTTP-клиенты |
X-Proxy-ID и X-Cache | Идентификатор узла и статус кэша | Кэширующие серверы вроде Squid |
Прозрачный уровень: адрес клиента уходит открытым текстом
Прозрачный прокси передаёт запрос дальше и добавляет к нему исходный адрес. Целевой сервер получает и адрес выходного узла в поле соединения, и адрес клиента в заголовке. Скрытия здесь нет никакого, задача такого узла состоит в кэшировании и учёте.
GET /page HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Via: 1.1 squid-gw (squid/5.7)
X-Forwarded-For: 198.51.100.20
X-Real-IP: 198.51.100.20
Proxy-Connection: keep-alive
Здесь 198.51.100.20 это адрес машины, с которой пошёл запрос. Сервер видит его прямо в теле запроса, пишет в логи и использует в своих правилах. Поле Via дополнительно сообщает имя и версию программы посредника, что делает картину совсем подробной.
Такие узлы стоят внутри офисных сетей и у части операторов связи, где трафик заворачивается на кэш без ведома пользователя. Для рабочих задач вроде сбора данных или разведения кабинетов уровень не подходит по очевидной причине: адрес клиента виден целевой площадке в первом же запросе.
Анонимный уровень: посредник виден, клиент нет
Анонимный прокси убирает исходный адрес из заголовков и оставляет признак своего присутствия. В типичном виде остаётся Via, иногда X-Forwarded-For со значением unknown либо с адресом самого выходного узла. Клиента за такой цепочкой не видно.
GET /page HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Via: 1.1 proxy
X-Forwarded-For: unknown
Для большинства задач этого достаточно. Целевой сервер знает, что запрос пришёл через посредника, и на этом его знание заканчивается: исходный адрес не восстанавливается ни из одного поля. Логи площадки покажут адрес выходного узла, и он же попадёт во все счётчики и ограничения.
Тонкость в том, что часть площадок относится к запросам с признаком посредника строже. Правила бывают простые: увидели Via, подняли порог проверки, показали интерактивную страницу подтверждения. Поэтому для работы с чувствительными к этому сайтами берут следующий уровень.
Встречается и промежуточный вариант, который иногда называют искажающим. Такой узел подставляет в X-Forwarded-For произвольный адрес, не имеющий отношения к клиенту. С точки зрения сервера картина выглядит как обычная цепочка посредников, и подставленное значение уходит в логи. На практике пользы от подмены немного: сам факт присутствия поля уже говорит о посреднике, а его содержимое серьёзные фильтры перепроверяют по другим признакам.
Отличить анонимный узел от искажающего просто. Отправляем запрос со своей машины, смотрим значение в X-Forwarded-For и сравниваем его с собственным адресом. Совпало, узел прозрачный. Стоит unknown или адрес самого узла, уровень анонимный. Стоит произвольный посторонний адрес, перед вами искажающий вариант.
Элитный уровень: запрос выглядит обычным
Элитный прокси передаёт запрос без единого добавленного поля. Набор заголовков остаётся тем, который сформировал ваш клиент: Host, User-Agent, Accept, Accept-Encoding, Accept-Language, Connection. Целевой сервер видит соединение с адреса выходного узла и обычный набор полей браузера.
GET /page HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Мы держим выходные узлы именно в таком режиме: серверная площадка отдаёт запрос дальше в том виде, в котором получила, и служебные поля к нему не подмешиваются. Разбор режима и состав пакета собраны на странице, где описаны анонимные прокси без служебных заголовков.
| Уровень | Via | X-Forwarded-For | X-Real-IP | Что узнаёт сервер |
|---|---|---|---|---|
| Прозрачный | Есть | Адрес клиента | Адрес клиента | Адрес узла и адрес клиента |
| Анонимный | Есть | unknown или адрес узла | Обычно нет | Адрес узла и факт посредника |
| Элитный | Нет | Нет | Нет | Только адрес узла |
Проверка уровня через curl
Самая быстрая проверка занимает одну команду. Берём публичный сервис, который возвращает полученные заголовки в виде JSON, и отправляем запрос через свой прокси. Всё, что окажется в ответе сверх обычного набора браузера, дописал посредник.
# запрос через прокси с привязкой своего адреса
curl -x http://185.24.87.14:8000 https://httpbin.org/headers
# запрос через прокси с логином и паролем
curl -x http://user5521:[email protected]:8000 https://httpbin.org/headers
# только адрес на выходе
curl -x http://185.24.87.14:8000 https://ifconfig.me
# полный протокол обмена вместе с заголовками запроса
curl -v -x http://185.24.87.14:8000 https://example.com -o /dev/null
Ответ разбирается по одному правилу: сравниваем полученный набор с тем, что отправляли. Проще всего сделать это в два прохода, сначала без прокси, потом через прокси, и посмотреть разницу.
curl -s https://httpbin.org/headers > direct.json
curl -s -x http://185.24.87.14:8000 https://httpbin.org/headers > proxied.json
diff direct.json proxied.json
Пустая разница по служебным полям означает элитный уровень. Появились Via и X-Forwarded-For со значением вашего адреса, перед вами прозрачный узел. Появился только Via либо X-Forwarded-For: unknown, уровень анонимный. Дополнительно смотрим на адрес в поле origin ответа: он должен совпадать с адресом выходного узла.
| Что видим в ответе | Уровень | Действие |
|---|---|---|
Ни одного лишнего поля, origin равен адресу узла | Элитный | Работаем без правок |
Via есть, адрес клиента отсутствует | Анонимный | Годится для большинства задач |
X-Forwarded-For содержит ваш адрес | Прозрачный | Узел из работы выводится |
origin равен адресу вашей машины | Прокси обошли | Проверяем настройки клиента |
| Ответ вернулся с кодом 407 | Авторизация не прошла | Сверяем логин, пароль и привязку |
Страница-эхо: своя проверка без внешних сервисов
Публичные сервисы удобны, но они видят весь ваш трафик проверки и иногда меняют формат ответа. Своя страница-эхо снимает эти неудобства и разворачивается за пару минут на любом сервере с PHP либо с Node.
<?php
// echo.php: возвращает все полученные заголовки и адрес соединения
header('Content-Type: application/json; charset=utf-8');
$out = ['remote_addr' => $_SERVER['REMOTE_ADDR'], 'headers' => []];
foreach ($_SERVER as $k => $v) {
if (strpos($k, 'HTTP_') === 0) {
$out['headers'][str_replace('_', '-', substr($k, 5))] = $v;
}
}
echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
Тот же смысл на Node без внешних пакетов:
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
remote: req.socket.remoteAddress,
headers: req.headers
}, null, 2));
}).listen(8080);
Поле remote_addr показывает адрес, с которого пришло соединение: там окажется выходной узел прокси. Блок headers показывает всё, что дошло до сервера. Мы проверяем свои узлы именно так, потому что страница на собственном сервере отдаёт сырую картину без чужой обработки.
Полезно повесить такую страницу на домен с сертификатом и проверять оба варианта, по HTTP и по HTTPS. Разница между ними существенная: при HTTPS прокси открывает туннель методом CONNECT и внутрь шифрованного потока не заглядывает, поэтому дописать что-либо в заголовки он физически не может. Именно по этой причине проверку уровня всегда делают по HTTP, иначе любой узел покажется элитным.
Из этого следует практический порядок замера. Сначала берём HTTP и снимаем сырой набор полей, затем повторяем по HTTPS и сверяем адрес соединения. Если по HTTP пришли лишние служебные поля, а по HTTPS картина ровная, узел работает в прозрачном либо анонимном режиме и просто не может вмешаться в шифрованный поток. Мы проводим оба замера подряд, когда разбираем чужую настройку по обращению клиента. Устройство самого туннеля и порядок работы метода CONNECT подробно описаны там, где оформляется подключение по протоколу HTTP и HTTPS.
Держать страницу-эхо стоит на отдельном домене без лишней логики. Она не должна ставить cookie, подключать сторонние скрипты и отдавать редиректы: любая из этих вещей меняет набор полей в следующем запросе и путает картину. Двадцать строк кода и статичный ответ дают ровно то, что нужно для замера.
Почему у SOCKS5 понятия заголовков нет
SOCKS работает на другом слое. Протокол занимается установкой соединения: клиент сообщает узлу адрес и порт назначения, узел открывает канал и дальше просто перекладывает байты в обе стороны. Содержимое потока для SOCKS-узла безразлично, разбирать HTTP он не умеет и не пытается.
Отсюда прямое следствие: дописать Via или X-Forwarded-For через SOCKS5 некому. Всё, что отправит ваша программа, дойдёт до сервера ровно в том виде, в котором вышло. Поэтому вопрос об уровне анонимности к SOCKS5 неприменим: заголовков на уровне протокола там попросту нет.
# обмен при установке соединения SOCKS5
клиент -> узел : 05 01 00 выбор метода авторизации
узел -> клиент : 05 00 метод принят
клиент -> узел : 05 01 00 03 0b example.com 01 bb подключить к example.com:443
узел -> клиент : 05 00 00 01 ... канал открыт
дальше идёт сырой поток байт
Второе преимущество сокетного варианта касается имён. В режиме socks5h разбор доменного имени передаётся на сторону узла, и запрос к DNS уходит оттуда же, откуда потом пойдёт соединение. Разбор запросов к службе имён вынесен в отдельный материал про утечку запросов к DNS, там показаны настройки для браузеров и парсеров.
# отличие двух схем в curl
curl -x socks5://185.24.87.14:1080 https://example.com # имя разбирает клиент
curl -x socks5h://185.24.87.14:1080 https://example.com # имя разбирает узел
В пакете доступны SOCKS4 и SOCKS5 на выбор, рекомендуем SOCKS5: он умеет авторизацию по логину, принимает доменные имена и работает с UDP. Строки подключения и порядок настройки собраны там, где оформляется покупка прокси SOCKS5 для программ.
Что ещё выдаёт работу через посредника
Заголовки закрывают первый слой картины, ниже лежат ещё четыре. Проверять их стоит вместе, потому что элитный уровень по заголовкам легко теряет смысл при промахе на любом из следующих пунктов.
Первое это запросы к службе имён. Программа резолвит домен через свой сервер, соединение идёт через прокси, и на стороне службы имён остаётся след вашей сети. Лечится переходом на socks5h либо настройкой резолвинга внутри браузера.
Второе это WebRTC в браузере. Механизм собирает адреса сетевых интерфейсов для прямого соединения между участниками и отдаёт их странице через JavaScript. Отключается флагом в настройках браузера или профилем антидетект-браузера, где нужные переключатели вынесены в интерфейс.
Третье это отпечаток клиента. Порядок заголовков, набор поддерживаемых наборов шифров при рукопожатии TLS, версия протокола, размер окна: всё это складывается в устойчивую подпись. curl и python-requests дают подпись, заметно отличающуюся от браузерной, поэтому для задач с браузерными сценариями берут настоящий браузер.
Четвёртое это поведение. Ровный интервал между запросами до сотой доли секунды, одинаковый путь обхода страниц, обращения без загрузки картинок и стилей: набор признаков читается площадкой не хуже заголовков.
| Слой проверки | Чем смотреть | Что чинить при промахе |
|---|---|---|
| Заголовки HTTP | curl на страницу-эхо | Уровень узла и настройки клиента |
| Служба имён | Лог запросов на своём сервере | Схема socks5h, настройка браузера |
| WebRTC | Страница проверки в браузере | Флаг браузера, профиль антидетекта |
| Отпечаток TLS | Сервис разбора рукопожатия | Переход на браузерный клиент |
| Поведение | Свои логи прогона | Разброс пауз, порядок обхода |
Пятый пункт стоит особняком: время ответа. Соединение через посредника добавляет к отклику несколько десятков миллисекунд, и по разнице между заявленным местом и задержкой иногда делают выводы. Серверные узлы с широким каналом держат эту прибавку небольшой, а разбор устройства таких узлов лежит на странице про серверные прокси на собственных мощностях.
Какой уровень нужен под какую задачу
Правило короткое: прозрачный уровень для рабочих задач не берут вовсе, анонимного хватает для внутренних проверок и мягких площадок, элитный берут для всего остального. Ниже раскладка по типовым сценариям.
| Задача | Достаточный уровень | Почему так |
|---|---|---|
| Проверка своего сайта из другой сети | Анонимный | Площадка своя, скрывать маршрут не требуется |
| Сбор открытых данных и прайсов | Элитный | Счётчики площадки строже к признакам посредника |
| Съём позиций в поисковой выдаче | Элитный | Выдача чувствительна к признакам автоматизации |
| Работа с несколькими кабинетами | Элитный плюс антидетект | Отпечаток браузера важнее заголовков |
| Отправка почты по SMTP | SOCKS5 | Заголовков на уровне протокола нет |
| Мониторинг доступности сервисов | Анонимный | Важен факт ответа и время отклика |
| Проверка рекламной выдачи | Элитный | Признаки посредника меняют показ |
Отдельно про сочетание с браузером. Элитный узел закрывает слой заголовков полностью, слой отпечатка при этом остаётся за клиентом. Профиль в Dolphin или другом антидетект-браузере подменяет параметры окна, шрифты и параметры графики, а прокси даёт адрес и маршрут. Работают эти два инструмента вместе, и подбирать их нужно парой. Порядок связывания профиля с адресом из пула мы разобрали на странице про прокси для антидетект-браузеров.
Ещё один сценарий про почту. Почтовые протоколы SMTP, IMAP и POP3 идут поверх обычного TCP-соединения без единого HTTP-заголовка, поэтому классификация уровней к ним неприменима целиком. Здесь работает сокетный вариант: клиент открывает канал через узел и обменивается командами протокола напрямую. Служебные поля в письме при этом формирует почтовый сервер, и смотреть нужно уже на них.
Отдельного внимания заслуживают внутренние проверки инфраструктуры. Когда команда мониторит доступность своих же сервисов из разных сетей, признак посредника ничему не мешает: важны код ответа и время отклика. Такие задачи спокойно закрываются анонимным уровнем, и переусложнять настройку смысла нет.
Наш пул состоит примерно из 12 000 активных адресов, ротация внутри пула автоматическая, список обновляется в реальном времени. Трафик безлимитный, потоки до 1000 на стандартных пакетах и до 3000 на корпоративном, включение пакета занимает примерно 5 минут. Мы выдаём список в форматах IP:PORT и IP:PORT:LOGIN:PASS, ссылкой либо файлом, и режим передачи заголовков одинаков для всех адресов пула. Подробности собраны там, где можно взять анонимные прокси под свою задачу.
Частые вопросы
Чем проверять прокси кроме curl?
Для массовой проверки списка рекомендуем чекер от Zennolab, у него есть демонстрационная версия. Он проходит список пачкой, показывает отвечающие строки, время отклика и тип прокси. Точечную проверку заголовков удобнее делать через curl на свою страницу-эхо, потому что там видно сырой набор полей без чужой обработки.
Какой тип прокси вы даёте?
В пакете доступны IPv4 и SOCKS5, внутри сокетного варианта можно выбрать SOCKS-4 или SOCKS-5, рекомендуем SOCKS-5. Протоколы HTTP и HTTPS работают на тех же адресах, менять пакет для перехода между ними не требуется: меняется только строка подключения в настройках программы.
В каком формате выдаётся список прокси?
Форматов два: IP:PORT для работы с привязкой своего адреса и IP:PORT:LOGIN:PASS для доступа по логину и паролю. Забрать список можно ссылкой или файлом, оба варианта лежат в кабинете. В пакет входит одновременная привязка 2 адресов, менять её разрешено свободно в настройках.
Подойдут ли прокси под мою задачу?
Заранее предугадать поведение каждой целевой площадки нельзя, поэтому перед покупкой доступен бесплатный тест до 2 часов под ваш запрос. За это время проверяются заголовки на своей странице-эхо, снимается время отклика и подбирается рабочее число потоков. Тест проходит на вашем софте и ваших доменах.
Тему продолжают соседние разборы основ: что такое прокси IPv4 и как устроен путь запроса, что сайт видит о вас при работе через прокси помимо адреса и заголовков, два способа доступа к прокси через логин и через привязку адреса. Пошаговый порядок замера с командами и разбором ответа описан в материале про проверку анонимности прокси.