Принудительно пересылать DNS-запросы в режим TCP

9

Я настроил DNS-сервер на SLES10 (в настоящее время bind 9.6) на многосетевом сервере. Этот сервер может быть запрошен из всех внутренних сетей и предоставляет ответы для всех внутренних сетей. У нас есть две отдельные DNS "основные" зоны. Каждая из этих зон обслуживается рядом авторитетных Windows-DNS-серверов.

Теперь мой linux-сервер является вторичным DNS-сервером для одной из этих зон (частная внутренняя зона) и выполняет функции пересылки для другой зоны (общедоступная внутренняя зона).

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

;; Усечено, повторная попытка в режиме TCP

Причина этого была выявлена ​​с помощью Wireshark-dump: первый запрос отправляется в режиме UDP, ответ не помещается в UDP (из-за длинного списка доверенных NS), затем повторяется в режиме TCP, обеспечивая правильный ответ.

Теперь вопрос: могу ли я настроить привязку для запроса серверов пересылки в режиме TCP без предварительной попытки UDP?

Обновление: пробую свои силы в ASCII-искусстве ...

+--------------+   +--------------+   +-----------------+
| W2K8R2 DNS   |   | SLES 10 DNS  |   | W2K8R2 DNS      |
| Zone private +---+ All internal +---+ Zone public     |
| internal 2x  |   |   Zones      |   | internal 30+ x  |
+--------------+   +-+----------+-+   +-----------------+
                     |          |
                  +--+---+   +--+---+
                  |Client|   |Client|
                  +------+   +------+
Nils
источник
Небольшая диаграмма этого была бы полезна - я изо всех сил пытаюсь выяснить, какой сервер какой из вашего описания.
Альнитак
несколько лучше, хотя до сих пор неясно, между какими именно хостами вы запускаете эту hostкоманду и каким запросом отправляется.
Альнитак
Клиенты запрашивают через SLES10 записи из зоны public internal. Зона private internal не страдает - там всего 2 NS записи.
Нильс
а клиенты просто решатели заглушки?
Альнитак
Предлагаем добавить minimal-responses: yesв конфигурацию BIND на SLES 10 - это может уменьшить размеры ответов. В любом случае, большинство обычных запросов не будут превышать 512 байт.
Альнитак

Ответы:

8

Во-первых, я бы не назвал это ошибкой, просто информационное сообщение.

Во-вторых, DNS-серверы всегда будут отвечать на запросы UDP (по крайней мере, BIND, я не могу найти варианты отключения UDP), и клиенты всегда будут (?) Сначала пытаться отправить UDP-запрос (например, в resolv.conf нет параметров, чтобы изменить это. ни в JVM) - если они помещаются в UDP-пакет (обычно это делают запросы)

Если у вас есть конкретный вариант использования, вы можете указать для использования TCP, например, в сценарии оболочки использовать 'dig + tcp' или 'host -T' для разрешения, и вы можете использовать системные вызовы 'sethostent / gethostbyname / endhostent' (см. Man страница), чтобы заставить TCP в других случаях.

Если вы действительно хотите попытаться заблокировать UDP, единственная опция, которую я вижу, - это правило iptable, но я не уверен, что эта настройка будет работать. Я ожидаю, что разрешение DNS просто не удастся.

Дэн Андреатта
источник
номинально выигрыш в производительности заключается в знании априори о том, что UDP-запрос не будет выполнен, и вначале при попытке выполнить TCP. См. RFC 5966 для некоторого обсуждения этого.
Альнитак
@Alnitak, и я хотел бы получить эту выгоду.
Нильс
1
@ Nils, поэтому нам нужно выяснить, почему EDNS, по-видимому, не работает ...
Alnitak
У меня нет особого варианта использования - клиенты будут использовать свою библиотеку распознавателя - но каждый запрос и каждый ответ будут дважды передаваться по сети - мне это не нравится.
Нильс
@ Nils, проблема в том, что клиент решает UDP / TCP, но серверу известен размер ответа.
Дэн Андреатта
4

Ваш сервер BIND должен использовать EDNS (см. RFC 2671), чтобы разрешить пакеты UDP длиннее 512 байт.

options {
    edns-udp-size 4096;
    max-udp-size 4096;
};

Это должно позволить вашему большому набору NS извлекаться по UDP, не требуя дополнительных затрат на соединение TCP для других небольших запросов.

Обратите внимание, что на самом деле это значения по умолчанию. Если EDNS не используется, либо что-то блокирует его, либо серверы, получающие параметры EDNS, не поддерживают его.

Также обратите внимание, что hostне поддерживает EDNS. Вполне возможно, что ваш сервер пересылки -> запросов уже использует EDNS, и вы просто не можете увидеть его, когда пытаетесь использовать локальный клиент.

Попробуйте dig +bufsize=4096 @server hostname Aвместо того, чтобы использовать host.

Альнитак
источник
Кто должен использовать это? Вероятно, и мой сервер, и мои серверы пересылки из зоны "public inner"?
Нильс
В чем смысл посылать полный список NS в ответе?
Нильс
@ Нил DNS-протокол требует, чтобы полный набор записей, соответствующих одному и тому же кортежу (QNAME, QTYPE и QCLASS), был неделим (иначе как «RRset»)
Альнитак
Не могли бы вы указать мне RFC относительно этого RRset?
Нильс
1
На самом деле хост использует стандартную библиотеку распознавателя, а на моей рабочей станции он поддерживает EDNS0. Чтобы проверить, указывает ли запрос EDNS0, запустите 'tcpdump -x port 53' и шестнадцатеричный дамп должен содержать (ближе к концу, в дополнительном разделе) последовательность 0029 1000 0000 8000 0000, которая является двоичным представлением OPT RR.
Дэн Андреатта