← Назад к блогу

SOCKS5 vs SOCKS5h: исправляем утечку DNS-запросов в Python, curl и Selenium

Разбираемся, почему при работе через SOCKS5 DNS-запросы уходят напрямую от вашего IP, чем отличается SOCKS5h и как закрыть эту дыру в Python, curl, Selenium и антидетект-браузерах.

📅30 октября 2026 г.

Вы настроили SOCKS5-прокси, трафик вроде бы идёт через него, IP в браузере отображается нужный — но сайты всё равно видят ваш реальный регион или провайдера начинает что-то подозревать. Причина почти всегда одна: DNS-запросы уходят напрямую с вашего компьютера, минуя прокси. В этой статье разберём, почему так происходит, чем SOCKS5 отличается от SOCKS5h и как закрыть эту утечку в коде и в готовых инструментах.

Что такое SOCKS5 и чем он отличается от SOCKS5h

SOCKS5 — это протокол прокси, который работает на уровне TCP/UDP-соединений и не разбирает содержимое пакетов, в отличие от HTTP(S)-прокси. Это делает его универсальным: через SOCKS5 можно проксировать практически любой трафик — браузер, Telegram, торрент-клиент, скрипт на Python. Но у классической реализации SOCKS5 есть важная особенность: резолвинг доменных имён (DNS) по умолчанию выполняется на стороне клиента, то есть на вашем компьютере, а не на стороне прокси-сервера.

SOCKS5h — это тот же протокол, но с модификатором «h» (hostname), который указывает клиентскому приложению не резолвить домен самостоятельно, а отправить его как есть на прокси-сервер, и уже прокси выполнит DNS-запрос от своего имени. Разница в одной букве, но последствия для анонимности и стабильности работы — принципиальные.

Важно понимать: SOCKS5h — это не отдельный протокол, а соглашение на уровне конкретной библиотеки или приложения о том, как формировать запрос к прокси. Сам прокси-сервер работает одинаково в обоих случаях, разница только в том, кто инициирует DNS-резолвинг — клиент или сервер.

Почему DNS-запросы обходят прокси

Когда вы обращаетесь к адресу вида https://example.com, перед установкой соединения приложение должно узнать IP-адрес этого домена. Этот процесс называется DNS-резолвингом. При работе через обычный SOCKS5 многие библиотеки и системные настройки выполняют резолвинг через системный DNS-сервер — тот, что прописан в настройках сети вашего провайдера или роутера.

В результате получается парадоксальная ситуация: сам HTTP/TCP-трафик уходит через прокси и выглядит так, будто запрос пришёл с IP прокси-сервера, а DNS-запрос «Какой IP у example.com?» улетает напрямую от вашего реального IP к DNS-серверу провайдера. Это и есть DNS-утечка (DNS leak). Сайт или сервис, который анализирует сетевую активность на более глубоком уровне (а такие методы детекта активно используют антифрод-системы Facebook, Google, TikTok), может увидеть несоответствие между IP соединения и источником DNS-запроса.

Причина в том, что протокол SOCKS5 изначально разрабатывался как транспортный уровень для уже готовых IP-соединений, а не для резолвинга имён. Разработчикам библиотек и утилит пришлось отдельно реализовывать функцию передачи DNS-запроса через туннель — отсюда и появился SOCKS5h как явное указание «резолви домен сам, а не я».

Чем опасна DNS-утечка на практике

Для разработчика парсера или скрипта автоматизации DNS-утечка — это не абстрактная теория, а конкретная причина блокировок и банов аккаунтов. Разберём несколько сценариев.

Парсинг маркетплейсов и сайтов. Если вы парсите Wildberries, Ozon или другой ресурс через прокси из нужного региона, но DNS-запросы уходят через провайдера, антибот-система может зафиксировать расхождение геолокации и повысить уровень подозрительности сессии — вплоть до капчи или временной блокировки IP прокси.

Мультиаккаунтинг и арбитраж трафика. При работе с Facebook Ads, TikTok Ads или Google Ads через несколько аккаунтов антифрод-системы анализируют десятки параметров, включая DNS-отпечаток. Если DNS-запросы нескольких «разных» аккаунтов внезапно идут через один и тот же DNS-сервер провайдера, это сигнал к объединению аккаунтов в один кластер — и как следствие, цепочка банов (chain-ban).

Автоматизация в Selenium/Playwright. Скрипты, которые эмулируют действия пользователя в браузере, особенно уязвимы: сам браузер может резолвить DNS через системные настройки ОС, игнорируя прокси, прописанный только для HTTP-трафика. В итоге весь остальной сетевой fingerprint выдаёт реальное местоположение.

Для большинства этих задач критично использовать резидентные прокси с корректно настроенным резолвингом DNS на стороне сервера — это значительно снижает риск детекта по сетевым признакам.

Как проверить, есть ли утечка DNS

Прежде чем чинить проблему, стоит убедиться, что она действительно есть. Вот несколько быстрых способов проверки.

  1. Откройте сайт dnsleaktest.com или ipleak.net через ваше прокси-соединение и запустите расширенный тест (Extended test).
  2. Сравните список DNS-серверов в результатах с тем, кем на самом деле является ваш интернет-провайдер. Если видите провайдера вместо дата-центра прокси — утечка подтверждена.
  3. Для командной строки используйте связку tcpdump или Wireshark, отфильтровав трафик по порту 53 (DNS) — если пакеты идут напрямую к серверу провайдера, а не через туннель прокси, проблема на вашей стороне.
  4. В Python можно быстро проверить резолвинг вручную через socket.getaddrinfo() до и после включения прокси — если IP совпадает с результатом без прокси, резолвинг идёт локально.

Исправление в Python (requests, PySocks, urllib3)

Самая частая ошибка в Python-скриптах — использование библиотеки requests совместно с PySocks без явного указания схемы socks5h. Разница в одном символе, но именно он решает, кто резолвит домен.

import requests

# ПЛОХО: DNS резолвится локально, мимо прокси
proxies_leak = {
    "http": "socks5://user:pass@proxy_host:1080",
    "https": "socks5://user:pass@proxy_host:1080",
}

# ХОРОШО: DNS резолвится на стороне прокси-сервера
proxies_safe = {
    "http": "socks5h://user:pass@proxy_host:1080",
    "https": "socks5h://user:pass@proxy_host:1080",
}

response = requests.get("https://example.com", proxies=proxies_safe, timeout=10)
print(response.status_code)
print(response.text[:200])

Для корректной работы схемы socks5h через requests понадобится установить зависимость:

pip install "requests[socks]" PySocks

Если вы используете низкоуровневый urllib3 напрямую, пример будет выглядеть так:

from urllib3.contrib.socks import SOCKSProxyManager

proxy = SOCKSProxyManager(
    "socks5h://user:pass@proxy_host:1080",
    num_pools=10
)

response = proxy.request("GET", "https://example.com")
print(response.status)

Для асинхронных скриптов на aiohttp используется библиотека aiohttp-socks, где схема прописывается точно так же:

import aiohttp
from aiohttp_socks import ProxyConnector

connector = ProxyConnector.from_url("socks5h://user:pass@proxy_host:1080")

async def fetch():
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get("https://example.com") as resp:
            print(await resp.text())

Исправление в curl

В curl тоже есть два разных флага для SOCKS5-прокси, и путаница между ними — классическая причина DNS-утечки в скриптах на bash.

# ПЛОХО: резолвинг на локальной машине
curl --socks5 proxy_host:1080 https://example.com

# ХОРОШО: резолвинг на стороне прокси-сервера
curl --socks5-hostname proxy_host:1080 https://example.com

# С авторизацией
curl --socks5-hostname user:pass@proxy_host:1080 https://example.com

Флаг --socks5-hostname — это прямой аналог socks5h в других инструментах. Он сообщает curl: «не трогай DNS, просто передай домен прокси-серверу как есть».

Исправление в Selenium и Playwright

С браузерной автоматизацией ситуация сложнее: сам Chrome или Firefox по умолчанию может резолвить DNS через системные настройки, игнорируя прокси, прописанный только на уровне сетевого запроса. Для Selenium с Chrome нужно явно включить резолвинг через прокси с помощью флага запуска браузера.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--proxy-server=socks5://proxy_host:1080")
# Критически важный флаг: резолвить DNS через прокси
options.add_argument("--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE proxy_host")

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

В Playwright ситуация проще: библиотека по умолчанию резолвит DNS через прокси, если он указан в конфигурации контекста браузера.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={"server": "socks5://proxy_host:1080"}
    )
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()

Тем не менее рекомендуется всегда проверять реальное поведение через dnsleaktest.com после настройки — поведение может отличаться между версиями Chromium.

Настройка в антидетект-браузерах

Если вы не пишете код, а работаете через антидетект-браузеры вроде Dolphin Anty, AdsPower, Multilogin или GoLogin — хорошая новость в том, что большинство из них уже резолвят DNS через прокси-сервер автоматически при выборе протокола SOCKS5, без необходимости указывать «h» вручную. Это одно из их ключевых преимуществ перед самописными скриптами.

Тем не менее стоит проверить это на практике: откройте профиль в антидетект-браузере, перейдите на dnsleaktest.com и запустите расширенный тест прямо внутри профиля. Если видите DNS-серверы, соответствующие региону вашего прокси, а не вашему реальному провайдеру — настройка корректна. Если нет, обратитесь в поддержку конкретного антидетект-браузера или смените тип прокси на HTTP(S), где проблема резолвинга DNS в принципе не возникает так остро, поскольку HTTP-прокси всегда работает с полными URL.

Для фарма аккаунтов в Instagram, TikTok и ведения рекламных кабинетов в Facebook Ads хорошо показывают себя мобильные прокси — за счёт динамической ротации IP операторов сотовой связи они реже попадают под подозрение антифрод-систем, даже если где-то в цепочке произошла небольшая DNS-утечка.

Таблица сравнения протоколов проксирования

Протокол Кто резолвит DNS Риск утечки Где применять
SOCKS5 Клиент (ваш компьютер) Высокий Только если DNS не критичен (локальные тесты)
SOCKS5h Прокси-сервер Низкий Парсинг, мультиаккаунтинг, автоматизация
HTTP/HTTPS прокси Прокси-сервер (по умолчанию) Низкий Веб-трафик, браузеры, API-запросы

Если ваша задача — высокоскоростной сбор данных без привязки к конкретному региону пользователя, присмотритесь к прокси дата-центров — они дешевле в расчёте на объём трафика и отлично работают в связке с SOCKS5h для парсинга, где важна скорость, а не маскировка под жилого пользователя.

Чек-лист перед запуском проекта

  • Используете схему socks5h://, а не socks5:// во всех библиотеках и конфигурациях.
  • Для curl используете флаг --socks5-hostname, а не --socks5.
  • В Selenium добавлен флаг --host-resolver-rules или используется Playwright с встроенным прокси-резолвингом.
  • Проверили результат на dnsleaktest.com или ipleak.net после настройки, а не до.
  • В антидетект-браузере протестировали DNS-отпечаток внутри самого профиля, а не только внешний IP.
  • Для задач с высокими требованиями к анонимности рассматриваете резидентные или мобильные прокси вместо дата-центровых.

Заключение

Разница между SOCKS5 и SOCKS5h — это буквально одна буква, но она решает, кто именно резолвит DNS-запрос: ваш компьютер или прокси-сервер. Утечка DNS — одна из самых незаметных, но при этом частых причин детекта при парсинге, мультиаккаунтинге и автоматизации рекламных кабинетов. Проверка через dnsleaktest.com и явное указание схемы socks5h в коде, curl-командах или настройках браузерной автоматизации закрывает эту дыру за несколько минут.

Если вы только выбираете инфраструктуру под задачу — для парсинга и работы с API лучше подходят прокси дата-центров, для мультиаккаунтинга и соцсетей — резидентные прокси, а для максимально естественного сетевого отпечатка при работе с мобильными приложениями — мобильные прокси. В любом из этих случаев корректная настройка DNS-резолвинга через SOCKS5h остаётся обязательным шагом перед запуском проекта в продакшн.