← Назад к вопросам

Почему DNS иногда переключается на TCP?

2.0 Middle🔥 171 комментариев
#Сети и протоколы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему DNS использует TCP вместо UDP

DNS (Domain Name System) — это распределённая система, которая преобразует доменные названия в IP-адреса. Исторически и в большинстве случаев DNS работает на **UDP** (User Datagram Protocol), потому что это быстрее и эффективнее для небольших запросов. Однако существует несколько критических ситуаций, когда DNS **переключается на TCP** (Transmission Control Protocol).


Основные причины перехода на TCP

  1. Размер сообщения превышает 512 байт

    • По спецификации RFC 1035, DNS-пакеты по UDP ограничены 512 байтами (без поддержки EDNS0).
    • Если ответ (например, с большим количеством записей A, MX или TXT) превышает этот лимит, сервер обрезает его и устанавливает TC-флаг (Truncation flag).
    • Клиент, увидев TC-флаг, должен повторно выполнить запрос через TCP, который поддерживает большие пакеты.
    # Пример запроса с большим ответом (может вызвать truncation)
    dig @ns1.example.com example.com ANY
    
  2. Трансфер зон (Zone Transfer)

    • Передача всей зоны DNS (например, между primary и secondary серверами) всегда использует TCP, потому что это большой объём данных, требующий надёжной доставки.
    • Протокол AXFR (полный трансфер) и IXFR (инкрементный трансфер) работают только на TCP.
    # Запрос трансфера зоны (обычно блокируется для безопасности)
    dig @secondary.example.com example.com AXFR
    
  3. Надёжность и целостность данных

    • TCP обеспечивает контроль соединения, подтверждение доставки и повторную передачу при потере пакетов.
    • Для важных операций (например, обновление записей через Dynamic DNS) TCP гарантирует, что данные не будут потеряны.
  4. Поддержка EDNS0 (Extension Mechanisms for DNS)

    • EDNS0 позволяет увеличить размер пакета UDP (до 4096 байт и больше), но не все клиенты/серверы его поддерживают.
    • Если EDNS0 не поддерживается или блокируется (например, firewall), TCP становится fallback-механизмом.
  5. Блокировка UDP-пакетов

    • Некоторые сети или firewall-правила могут блокировать UDP-трафик для DNS из соображений безопасности или контроля.
    • TCP (обычно порт 53) иногда разрешён, что позволяет обойти ограничения.

Как происходит переключение на TCP

Когда клиент DNS (например, резолвер glibc, unbound, или браузер) получает ответ с TC-флагом, он выполняет следующее:

  1. Открывает TCP-соединение к DNS-серверу на порт 53.
  2. Пересылает оригинальный запрос в рамках TCP-сессии.
  3. Получает полный ответ без обрезания.
  4. Закрывает соединение.
# Пример логики клиента (упрощённый)
def resolve_dns(domain):
    udp_response = send_udp_query(domain)
    if udp_response.truncated:  # Проверка TC-флага
        tcp_response = send_tcp_query(domain)
        return tcp_response
    return udp_response

Примеры и диагностика

  • Запрос большого домена:

    # Запрос может вернуть truncation
    dig google.com ANY
    # Ответ: ;; Truncated, retrying in TCP mode.
    
  • Проверка поддержки EDNS0:

    dig +edns=0 example.com
    # Если ответ не содержит OPT-record, EDNS0 не поддерживается.
    
  • Логирование TCP-запросов:

    tcpdump -i any port 53 and tcp
    # Покажет все DNS-TCP соединения.
    

Проблемы и оптимизация

  • Производительность: TCP требует трёхэтапного handshake (SYN-SYN/ACK-ACK) и создания соединения, что медленнее UDP.
  • Нагрузка на сервер: Множество TCP — соединений увеличивает нагрузку на серверы DNS.
  • Решение: Использовать EDNS0 для увеличения размера UDP-пакетов и минимизировать переходы на TCP.

Вывод

DNS переключается на TCP при необходимости передачи больших данных, обеспечения надёжности или при ограничениях сети. Это резервный механизм, который гарантирует работоспособность системы даже в нестандартных условиях. Для современных систем важно поддерживать EDNS0 и оптимизировать размеры ответов, чтобы уменьшить частоту таких переходов и сохранить высокую скорость работы DNS.