Вопрос: Как отключить поиск AAAA?


... для компенсации неисправных DNS-серверов, находящихся вне нашего контроля.

Наша проблема: мы внедряем встроенные устройства, которые собирают данные датчиков на различных сайтах, в основном на IPv4. Некоторые сайты имеют плохо поддерживаемые сети, например. неправильно сконфигурированные или иным образом разбитые DNS-кэши и / или брандмауэры, которые либо вообще игнорируют запросы AAAA, либо отвечают на них сломанными ответами (например, неправильный IP-адрес источника). Как внешний поставщик отделов объектов, мы не имеем никакого влияния на (иногда неохотно) ИТ-отделы. Шансы на их исправление своих DNS-серверов / брандмауэров в ближайшее время являются незначительными.

Эффект на нашем устройстве заключается в том, что с каждым gethostbyname () процессы должны ждать, пока тайм-аут AAAA не истечет, и в этот момент некоторые процессы уже полностью отключили свои попытки подключения.

Я ищу решения, которые ...

  • общесистемный. Я не могу перенастроить десятки приложений отдельно
  • непостоянные и настраиваемые. Мы должны (повторно) включить IPv6, где / когда он фиксируется / выкачивается. Перезагрузка в порядке.
  • Если для решения требуется замена базовой библиотеки, такой как glibc, пакет библиотеки замещения должен быть доступен из хранилища с хорошо сохранившимся хранилищем (например, Debian Testing, Ubuntu universe, EPEL). Само строительство не является вариантом по многим причинам, о которых я даже не знаю, с чего начать, поэтому я просто не перечисляю их вообще ...

Наиболее очевидным решением было бы настроить библиотеку резольвера, например. через / etc / {Резолв,NSSwitch,гаи} .conf, чтобы не запрашивать записи AAAA. Параметр resolv.conf no-inet6 как было предложено Вот было бы в точку что я ищу. К сожалению, он не реализован, по крайней мере, не в наших системах (libc6-2.13-38 + deb7u4 на Debian 7; libc6-2.19-0ubuntu6.3 на Ubuntu 14.04)

Так как же тогда? В СФ и в других местах предлагаются следующие методы, но они не работают:

  • Отключение 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 на localhost. Настройте его для перенаправления всех запросов, отличных от AAAA, но для ответа на запросы AAAA с помощью NOERROR или NXDOMAIN (в зависимости от результата соответствующего A-запроса). Я не знаю, что кеш DNS способен это сделать.
  • Используйте некоторые умные iptables u32 match, или Ondrej Caletka's Модуль DNS iptables чтобы соответствовать запросам AAAA, чтобы либо icmp-отклонить их (как бы реагировать на это?), либо перенаправить их на локальный DNS-сервер, который отвечает на все с помощью пустого NOERROR.

Обратите внимание, что есть похожие, связанные вопросы по SE. Мой вопрос отличается тем, что он разрабатывает фактическую проблему, которую я пытаюсь решить, поскольку в ней перечислены явные требования, так как она черничает некоторые часто предлагаемые нерабочие решения и не относится ни к одному приложению. Следующий это обсуждение, Я отправил свой вопрос.


32
2017-10-01 09:03


Источник


PS: Вопреки распространенному мнению здесь, в SF, есть несколько веских причин отключить IPv6 / AAAA на машине в сети только с IPv4, даже там, где работает DNS: уменьшить нагрузку на трансляцию; Уменьшите нагрузку на DNS-преобразователи почти на 50%; Сократите время запуска подключения (значительно, когда тайники DNS отстают); Следуйте рекомендациям по отключению нерабочих функций для повышения безопасности и стабильности. По общему признанию, если я забуду снова включить IPv6, когда он станет доступен, моя система станет устаревшим балластом IPv4, который препятствует развертыванию IPv6. Нужно иметь возможность взвесить перечисленных профи против этого конфликта. - Nils Toedtmann
Любая причина, по которой вы не запускаете полный resolver на localhost? Таким образом, вы полностью исключаете зависимость от других (по-видимому) ненадежных DNS-резонаторов других людей. - Sander Steffann
Политики брандмауэра компании @SanderSteffann обычно запрещают это. Но в другом месте это вариант. Я добавлю это к моему вопросу позже. - Nils Toedtmann
@joeqwerty Мы не делаем никаких предположений о том, поддерживается ли IPv6 на сайте. Мы делаем предположение, хотя DNS-серверы являются стандартными. Кроме того, некоторые ИТ-отделы, к сожалению, делать не хватает навыков для правильной настройки своей инфраструктуры. Извините за то, что вы прямо об этом говорите. - Nils Toedtmann
Я понимаю, что вы говорите. Вы должны сделать свою коробку работать в своей сети не наоборот, и именно об этом вы спрашиваете. Я просто немного расхохотался, когда мы в ИТ-сфере обвиняем наших клиентов и не уважаем их. Это наш хлеб и масло. Для хорошего или плохого мы должны уважать это и уважать их. Наши клиенты не являются препятствием для нашего бизнеса, они являются причиной нашего бизнеса. - joeqwerty


Ответы:


Прекратить использование gethostbyname(), Вы должны использовать getaddrinfo() вместо этого, и должно было быть годами. Эта страница даже предупреждает вас об этом.

Функции gethostbyname * (), gethostbyaddr * (), herror () и hstrerror () устарели. Приложения должны использовать getaddrinfo (3), getnameinfo (3) и gai_strerror (3).

Вот краткая примерная программа на C, которая демонстрирует поиск только Записи для имени и захват Wireshark, показывающий, что только По сети просматривались записи.

В частности, вам необходимо установить ai_family в AF_INET если вы хотите, чтобы результаты поиска были выполнены. Эта примерная программа печатает только возвращенные IP-адреса. См. getaddrinfo() man для более полного примера того, как делать исходящие соединения.

в Захват Wireshark, 172.25.50.3 - это локальный DNS-преобразователь; захват был сделан там, поэтому вы также видите его исходящие запросы и ответы. Обратите внимание, что только была запрошена запись A. Никакой запрос AAAA не был сделан.

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdio.h>

int main(void) {
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int s;
    char host[256];

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;

    s = getaddrinfo("www.facebook.com", NULL, &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        getnameinfo(rp->ai_addr, rp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
        printf("%s\n", host);
    }
    freeaddrinfo(result);
}

8
2017-07-25 17:34



Интересно! Я буду исследовать, какие приложения запускают запросы AAAA. Если это только наша, я передам ваше предложение нашим разработчикам. Но у меня есть сильная догадка о том, что многие из Debian / Ubuntu-упакованного программного обеспечения страдают от этого, и мы не собираемся исправлять их. - Nils Toedtmann
Ваше приложение, вероятно, самое важное. Даже если вы не можете исправить все остальное, это может улучшить ситуацию. - Michael Hampton♦


Если у вас есть сомнения, перейдите к исходному коду! Итак, давайте посмотрим ... gethostbyname () выглядит интересно; который точно описывает, что мы видим: сначала попробуйте IPv6, затем вернитесь к IPv4, если вы не получите ответ, который вам нравится. Что это RES_USE_INET6 флаг? Отслеживая это, он исходит из res_setoptions (), Это где resolv.conf читается.

И ... это я из идей. Я совершенно не понимаю, как это RES_USE_INET6 устанавливается, если не в resolv.conf,


3
2017-10-02 20:40



RES_USE_INET6 Можно установить через options inet6 в resolv.conf, Я думаю, моя проблема в том, что она не может быть снята с охраны после того, как он был установлен во время компиляции, и все основные дистрибутивы, похоже, работают в эти дни (правильно?). Поэтому запрос функции для options no_inet6 что я упомянул выше. - Nils Toedtmann
К сожалению, как видно из кода, не существует no_inet6 в res_setoptions(), Однако, как вы можете видеть из (no-)ip6-dotint, это легко изменить. Чтобы проверить теорию о том, что он задан по умолчанию вашим дистрибутивом, я бы взял исходные файлы пакета и скомпилировал его один раз «virgin» (чтобы убедиться, что пакет реплицирует поведение), а затем добавьте: { STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 }, к options[] массива и посмотреть, не исчезнет ли проблема, когда вы установите этот параметр в resolv.conf, - BMDan
Наконец: для чего это стоит, я бы решил это, запустив кеш DNS на localhost (как вы ссылаетесь, выше). Было бы намного проще сохранить свой собственный, взломанный прокси-сервер / кеш DNS, чем будет поддерживать взломанную версию базовой системной библиотеки. - BMDan


Вы можете использовать BIND в качестве локального резольвера, он имеет возможность фильтровать AAAA:

https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html


3
2017-07-25 21:09



Это довольно тяжелый для встроенного устройства. - Michael Hampton♦
Спасибо, я не знал о фильтре AAAA Bind. Как упоминает Майкл, это, вероятно, не решение для нас из-за большого следа Бинда. Но для тех, кто хочет отфильтровать ответы AAAA в других сценариях, это может быть жизнеспособным способом. Ubuntu фактически строит привязку с «--enable-filter-aaaa», по крайней мере, на 14.04. Не уверен в Debian. - Смотрите также ipamworldwide.blogspot.co.uk/2011/09/... - Nils Toedtmann
Я нахожусь на 14.04, и похоже, что этот вариант фильтрации недоступен. - Zitrax


Вы пытались настроить PDNS-recursor, установить его в файле /etc/resolv.conf и запретить поиск «AAAA» в нем? Используя что-то вроде query-local-address6=


0
2017-10-02 10:22



query-local-address6=делает что-то другое (какой IPv6-адрес для отправки запросов - обратите внимание, что даже при отключенном IPv6 запросы AAAA все равно будут разрешены через IPv4). Также я не могу определить какие-либо другие настройки, которые будут фильтровать запросы AAAA (doc.powerdns.com/html/built-in-recursor.html). Без этой информации ваш ответ не очень помогает :( - Nils Toedtmann