... чтобы компенсировать сломанные DNS-серверы, которые находятся вне нашего контроля.
Наша проблема: мы внедряем встроенные устройства, которые собирают данные датчиков на различных сайтах, в основном только для IPv4. Некоторые сайты имеют плохо обслуживаемые сети, например, неправильно настроенные или иным образом поврежденные кэши DNS и / или брандмауэры, которые либо полностью игнорируют запросы AAAA, либо отвечают на них с поврежденными ответами (например, неверный IP-адрес источника!). Как внешний поставщик для отдела оборудования, мы почти не влияем на (иногда неохотно) ИТ-отделы. Вероятность того, что они исправят свои DNS-серверы / брандмауэры в ближайшее время, ничтожна.
Влияние на наше устройство состоит в том, что с каждым gethostbyname () процессы должны ждать, пока не истечет время ожидания запросов AAAA, после чего некоторые процессы уже полностью отключили свои попытки подключения.
Я ищу решения, которые ...
- общесистемный. Я не могу перенастроить десятки приложений по отдельности
- непостоянный и настраиваемый. Нам нужно (повторно) включить IPv6, где / когда он будет исправлен / развернут. Перезагрузка в порядке.
- Если для решения требуется замена базовой библиотеки, такой как glibc, пакет библиотеки для замены должен быть доступен из хорошо поддерживаемого репозитория (например, Debian Testing, Ubuntu Universe, EPEL). Самостоятельное строительство не является вариантом по многим причинам, поэтому я даже не знаю, с чего начать, поэтому я просто не перечисляю их вообще ...
Самое очевидное решение было бы настроить библиотеку распознавателя , например , с помощью / и т.д. / { Резо , NSSwitch , гаи } .conf не запрос AAAA записей. Вариант resolv.conf, no-inet6
предложенный здесь , будет именно тем , что я ищу. К сожалению, это не реализовано, по крайней мере, в наших системах (libc6-2.13-38 + deb7u4 в Debian 7; libc6-2.19-0ubuntu6.3 в Ubuntu 14.04)
Так как же тогда? Можно найти следующие методы, предложенные на SF и в других местах, но ни один из них не работает:
- Отключение IPv6 в целом, например путем внесения в черный список ipv6 LKM в /etc/modprobe.d/ или
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Из любопытства: почему распознаватель запрашивает AAAA, где IPv6 отключен? ) - Удаление
options inet6
из /etc/resolv.conf. Во-первых, его там не было,inet6
просто он включен по умолчанию. - Установка
options single-request
в /etc/resolv.conf. Это только гарантирует, что запросы A и AAAA выполняются последовательно, а не параллельно - Изменение
precedence
в /etc/gai.conf. Это не влияет на DNS-запросы, только на то, как обрабатывается несколько ответов. - Использование внешних распознавателей (или запуск демона локального распознавателя, который обходит неработающие DNS-серверы) может помочь, но, как правило, запрещено политиками брандмауэра компании. И это может сделать внутренние ресурсы недоступными.
Альтернативные уродливые идеи:
- Запустите кеш DNS на локальном хосте. Сконфигурируйте его для пересылки всех не-AAAA-запросов, но для ответа на AAAA-запросы с помощью NOERROR или NXDOMAIN (в зависимости от результата соответствующего A-запроса). Я не знаю, кэш DNS, способный сделать это, хотя.
- Используйте какое-нибудь умное соответствие iptables u32 или DNS-модуль Ондрея Калетки iptables DNS для сопоставления запросов AAAA, чтобы либо отклонить их icmp (как отреагирует на это lib lib resolver), либо перенаправить их на локальный DNS-сервер, который отвечает на запросы. все с пустым NOERROR.
Обратите внимание, что есть похожие вопросы по SE. Мой вопрос отличается тем, что он раскрывает реальную проблему, которую я пытаюсь решить, поскольку в нем перечислены явные требования, так как в нем перечислены некоторые часто предлагаемые нерабочие решения, и поскольку он не относится к конкретному приложению. После этого обсуждения я разместил свой вопрос.
источник
Ответы:
Прекратите использовать
gethostbyname()
. Вы должны использоватьgetaddrinfo()
вместо этого, и должно было быть в течение многих лет. Страница man даже предупреждает вас об этом.Вот быстрый пример программы на C, который демонстрирует поиск только записей A по имени, и захват Wireshark, показывающий, что только поиск записей A проходил по сети.
В частности, вам нужно установить
ai_family
значение,AF_INET
если вы только хотите, чтобы был произведен поиск записей. Этот пример программы печатает только возвращенные IP-адреса. См.getaddrinfo()
Справочную страницу для более полного примера того, как устанавливать исходящие соединения.В перехвате Wireshark 172.25.50.3 - локальный преобразователь DNS; захват был сделан там, так что вы также видите исходящие запросы и ответы. Обратите внимание, что была запрошена только запись А. Поиск AAAA никогда не проводился.
источник
Если вы сомневаетесь, обратитесь к исходному коду! Итак, давайте посмотрим ... gethostbyname () выглядит интересно; это точно описывает то, что мы видим: сначала попробуйте IPv6, а затем вернитесь к IPv4, если вы не получили ответ, который вам нравится. Что это за
RES_USE_INET6
флаг? Возвращаясь к нему, это происходит из res_setoptions () . Это гдеresolv.conf
читается в.И .... это я вне идей. Мне совершенно непонятно, как это происходит,
RES_USE_INET6
если не вresolv.conf
.источник
options inet6
вresolv.conf
. Я предполагаю, что моя проблема в том, что он не может быть сброшен после того, как он был установлен во время компиляции, что все основные дистрибутивы, кажется, делают в эти дни (правильно?). Поэтому запрос функции дляoptions no_inet6
этого я упомянул выше.no_inet6
опцииres_setoptions()
. Однако, как вы можете видеть из (нет)ip6-dotint
, это легко изменить. Чтобы проверить теорию, что она устанавливается по умолчанию вашим дистрибутивом, я бы взял исходные файлы пакета и скомпилировал его один раз «virgin» (чтобы убедиться, что пакет повторяет поведение), а затем добавил:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
вoptions[]
массив и посмотрел, проблема исчезнет, когда вы установите эту опцию вresolv.conf
.Вы можете использовать BIND в качестве локального распознавателя, у него есть опция для фильтрации AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
источник
Вы пытались настроить PDNS-рекурсор, установить его в /etc/resolv.conf и запретить поиск в нем "AAAA"? Используя что-то вроде
query-local-address6=
источник
query-local-address6=
делает что-то другое (с какого IPv6-адреса отправлять запросы - обратите внимание, что даже если IPv6 отключен, запросы AAAA по-прежнему будут обрабатываться через IPv4). Также я не могу определить другие параметры, которые бы фильтровали запросы AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Без этой информации ваш ответ не очень полезен :(