Как включить DNS поверх TCP для разрешения имен в Linux

Как мне настроить Linux для разрешения DNS поверх TCP?

Сегодня мы обнаружили, что несколько различных серверов Linux, которые мы используем, не могут разрешать DNS-имена с множеством IP-адресов в ответе. Эти ответные пакеты будут иметь размер более 512 байт, поэтому сервер отправляет обратно пакет UDP с усеченным набором битов. На этом этапе различные процессы на сервере (в данном случае Java и команда nslookup) просто перестают разрешать имя. Они не выполняют тот же запрос по TCP, я слышал, что они должны.

Эта часть относится к alpinelinux: В alpine linux я могу включить поиск DNS по TCP, установив пакет bind-utils. это заставляет другие программы в системе правильно запускать обработку усеченных ответов, переключаясь на TCP. Я не знаю, что этот конкретный пакет делает для настройки этого, и я остался с этим вопросом:

Бонусный вопрос, можно ли это включить только для java, не меняя ничего другого?

Мы видим это не только для alpine, хотя мы наткнулись на пакет, который имеет такой же эффект для alpine.

0
задан 7 November 2020 в 04:03
2 ответа

Как указано в tools.ietf.org/html/rfc5966:

In the absence of EDNS0 (Extension Mechanisms for DNS 0) (see below), the standard
behaviour of any DNS server needing to send a UDP response that would exceed the 
512-byte limit is for the server to truncate the answer so that it fits within that
limit and then set the TC flag in the response header. When the client receives such
a response, it takes the TC flag as an indication that it should retry over TCP 
instead.

Этот другой RFC https://www.ietf.org/rfc/rfc2181.txt также содержит некоторые разъяснения, которые включают использование Бит заголовка TC (усеченный):

Where TC is set, the partial RRSet that would not completely fit may be left in the
response.  When a DNS client receives a reply with TC set, it should ignore that 
response, and query again, using a mechanism, such as a TCP connection, that will 
permit larger replies.

Клиент не знает заранее, что ответ будет слишком большим, поэтому он будет запрашивать сервер через UDP, за исключением запросов на передачу зоны, которые всегда используют TCP. Сервер ответит по UDP и максимально включит и установит усеченный бит заголовка. Затем клиент должен повторно отправить запрос через TCP и получить полный ответ. Таким образом, вам не нужно ничего настраивать, чтобы заставить клиентов всегда использовать TCP для отправки DNS-запроса, потому что они просто делают это при получении ответа с установленным битом TC.

Вам просто нужно убедиться, что нет брандмауэра, который блокирует TCP-трафик на порту 53. Вы также можете убедиться, что вас не укусила какая-то ошибка.

2
ответ дан 11 November 2020 в 08:40

Возможно, вы уже решили эту проблему, но недавно я столкнулся с такой же ситуацией с Alpine Linux и рядом приложений Ruby.

Проблема здесь в том, что musl libc не реализует DNS через TCP (простите меня за терминологию). Установив такие пакеты, как bind-tools, вы получите двоичные файлы, которые поставляются со своим собственным/другим распознавателем DNS, поэтому они могут общаться с DNS через TCP.

Мы решили эту проблему, используя собственный распознаватель, который поддерживает TCP в наших приложениях Ruby (это рекомендуется Ричем Фелкером, сопровождающим musl libc). На самом деле, он поставляется со стандартной библиотекой Ruby, так что это не очень большое изменение.

В большинстве сред реализован собственный решатель, поэтому вы сможете найти его для любого используемого языка/среды.

Вот некоторые ресурсы:

1
ответ дан 4 August 2021 в 09:45

Теги

Похожие вопросы