Як відключити пошук AAAA?


35

... для компенсації пошкоджених серверів DNS, які не знаходяться під нашим контролем.

Наша проблема: ми розгортаємо вбудовані пристрої, які збирають дані сенсорів на різних, переважно IPv4-сайтах. Деякі сайти мають погано підтримувані мережі, наприклад, неправильно налаштовані або зламані кешовані файли DNS та / або брандмауери, які або взагалі ігнорують запити AAAA, або відповідають на них зламаними відповідями (наприклад, неправильний джерело IP!). Як зовнішній постачальник відділу обладнання, ми не маємо впливу на (іноді неохоче) ІТ-відділи. Шанси їх незабаром скористатися серверами / брандмауерами DNS незабаром є незначними.

Ефект на нашому пристрої полягає в тому, що з кожним gethostbyname () процесам доводиться чекати, поки очікується час запиту AAAA, після чого деякі процеси вже вичерпали спроби їх з'єднання.

Я шукаю рішення, які є ...

  • загальносистемні. Я не можу налаштувати десятки додатків окремо
  • непостійний і настроюваний. Нам потрібно (повторно) включити IPv6 там, де / коли він буде виправлений / розгорнутий. Перезавантаження в порядку.
  • Якщо рішення вимагає заміни основної бібліотеки на зразок glibc, пакет бібліотеки заміни повинен бути доступний з відомого добре підтримуваного сховища (наприклад, Debian Testing, Ubuntu всесвіт, EPEL). Самостійне будівництво не є варіантом з такої кількості причин, що я навіть не знаю, з чого почати, тому просто їх не перелічую ...

Найбільш очевидним рішенням буде налаштувати бібліотеку резолюцій, наприклад через / etc / { resolutionv , nsswitch , gai } .conf, щоб не запитувати записи AAAA. no-inet6Рекомендований тут варіант resv.conf був би саме тим , що я шукаю. На жаль, він не реалізований, принаймні, не в наших системах (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 на localhost. Налаштуйте його для переадресації всіх запитів, що не є AAAA, але відповіді на запити AAAA або NOERROR, або NXDOMAIN (залежно від результату відповідного A-запиту). Я не знаю, кеш DNS, здатний це зробити.
  • Використовуйте кілька розумних збігів iptables u32 або DNS-модуль iptables Ondrej Caletka для відповідності запитам AAAA, щоб або icmp-відхилив їх (як би реагувала lib на них?) Або перенаправляв їх на локальний сервер DNS, який відповідає на все з порожнім НОМЕРОМ.

Зауважте, що щодо SE є подібні, пов'язані питання. Моє запитання відрізняється тим, що воно розкриває актуальну проблему, яку я намагаюся вирішити, оскільки вона містить чіткі вимоги, оскільки вона містить чорні списки деяких непропонованих непрацюючих рішень, і оскільки вона не є специфічною для однієї програми. Після цієї дискусії я розмістив своє запитання.


13
PS: Всупереч поширеній думці в SF, є кілька вагомих причин відключити IPv6 / AAAA на машині в мережі, призначеній лише для IPv4, навіть там, де працює DNS: Зменшити навантаження мовлення; Зменшити навантаження на DNS-рішення на майже 50%; Скоротити час запуску з'єднання (значно там, де кеш-пам'ять DNS відстає); Дотримуйтесь найкращих практик, щоб відключити нефункціональні функції для підвищення безпеки та стабільності. Щоправда, якщо я забуду повторно включити IPv6, як тільки він стане доступним, тоді моя система стає спадковим баластом IPv4, що перешкоджає розгортанню IPv6. Слід дозволити зважити перелічені плюси проти цього протиправника.
Нільс Тодтманн

Будь-яка причина, чому ви не запускаєте повний дозвіл на localhost? Таким чином ви повністю усуваєте залежність від інших (здавалося б, ненадійних DNS-вирішальників).
Сандер Стеффан

Політика брандмауера @SanderSteffann компанії зазвичай забороняє це. Але в інших місцях це варіант. Я додам його до свого питання пізніше.
Нілс Тодтманн

3
@joeqwerty Ми не робимо жодних припущень щодо того, підтримується чи не IPv6 на сайті. Ми робимо припущення, хоча DNS-сервери відповідають стандартам. Крім того, деяким ІТ-підрозділам, на жаль, не вистачає навичок правильно налаштувати свою інфраструктуру. Вибачте за те, що ви сказали про це.
Нілс Тодтманн

4
Я розумію, що ти кажеш. Вам потрібно змусити вашу коробку працювати в їхній мережі не навпаки, і ось про що ви тут питаєте. Я просто трохи заплутався, коли ми в ІТ-сфері звинувачуємо своїх клієнтів і не поважаємо їх. Вони - наш хліб і масло. Для хорошого чи поганого нам потрібно це поважати та поважати. Наші клієнти не перешкоджають нашому бізнесу, вони є причиною нашого бізнесу.
joeqwerty

Відповіді:


9

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

Функції gethostbyname * (), gethostbyaddr * (), herror () та hstrerror () застаріли. Програми повинні використовувати getaddrinfo (3), getnameinfo (3) та gai_strerror (3).

Ось швидкий зразок програми на C, який демонструє пошук лише записів A для імені та Wireshark-захоплення, що показує, що лише пошук записів A пройшов по мережі.

Зокрема, необхідно встановити , ai_familyщоб , AF_INETякщо ви хочете тільки Рекордний Lookups зроблена. Цей зразок програми друкує лише повернуті IP-адреси. Дивіться getaddrinfo()довідкову сторінку для більш повного прикладу того, як встановити вихідні з'єднання.

У захваті 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);
}

Цікаво! Я вивчу, які програми запускають запити AAAA. Якщо це лише наше, то я передам вашу пропозицію нашим дияволам. Але я переконаний, що багато програмного забезпечення Debian / Ubuntu страждає від цього, і ми не збираємося їх латати.
Нілс Тодтманн

Ваша заявка, мабуть, найважливіша. Навіть якщо ви не можете виправити все інше, це може покращити ситуацію.
Майкл Хемптон

4

Якщо ви сумніваєтеся, перейдіть до вихідного коду! Отже, подивимось ... gethostbyname () виглядає цікаво; це точно описує те, що ми бачимо: спробуйте спочатку IPv6, а потім поверніться до IPv4, якщо ви не отримаєте відповідь, яка вам подобається. Що це за RES_USE_INET6прапор? Відстежуючи його, він походить від res_setoptions () . Про це resolv.confчитається в.

І .... це я не з ідей. Мені абсолютно незрозуміло, як це RES_USE_INET6встановлюється, якщо не входить resolv.conf.


RES_USE_INET6 можна встановити через options inet6в resolv.conf. Я думаю, що моя проблема полягає в тому, що вона не може бути скасована, як тільки вона була встановлена ​​під час компіляції, що, здається, роблять усі основні дистрибутиви в ці дні (правильно?). Тому запит на функцію для options no_inet6цього я згадав вище.
Нілс Тодтманн

1
На жаль, як видно з коду, no_inet6опція в res_setoptions(). Однак, як ви бачите з (ні-) ip6-dotint, це легко змінити. Щоб перевірити теорію про те, що він встановлений за замовчуванням вашим дистрибутивом, я захоплю файли вихідного пакета і компілюю його один раз "незайманим" (щоб підтвердити, що пакет повторює поведінку), а потім додаю: { STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },до options[]масиву і дивіться, чи проблема усувається, коли ви встановите цю опцію в resolv.conf.
BMDan

1
Нарешті: для чого це варто, я би вирішив це, запустивши кеш DNS на localhost (як ви посилаєтесь вище). Обслуговувати свій власний, зламаний проксі / кеш DNS було б набагато простіше, ніж було б підтримувати зламану версію основної системної бібліотеки.
BMDan

3

Ви можете використовувати BIND як локальну роздільну здатку, вона має можливість фільтрувати AAAA:

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


2
Це досить важка вага для вбудованого пристрою.
Майкл Хемптон

Дякую, мені не було відомо про фільтр AAAA Bind. Як згадує Майкл, це, мабуть, не для нас рішення через великий слід Бінда. Але для тих, хто хоче відфільтрувати відповіді AAAA в інших сценаріях, це може бути життєздатним способом. Ubuntu фактично будує зв'язування з "--enable-filter-aaaa", принаймні 14.04. Не впевнений у Debian. - Дивіться також ipamworldwide.blogspot.co.uk/2011/09/…
Nils Toedtmann

1
Я на 14.04, і не здається, що цей варіант фільтрації доступний.
Zitrax

0

Ви намагалися налаштувати PDNS-рекурсор, встановили його у вашому /etc/resolv.conf і відмовили в ньому "AAAA"? Використання чогось подібногоquery-local-address6=


1
query-local-address6=робить щось інше (з якої IPv6 адреси надсилати запити - зауважте, що навіть при відключенні IPv6, запити AAAA все одно будуть вирішені через IPv4). Також я не можу ідентифікувати жодне інше налаштування, яке б фільтрувало запити AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Без цієї інформації ваша відповідь не дуже корисна :(
Nils Toedtmann
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.