... aby zrekompensować uszkodzenie uszkodzonych serwerów DNS, które są poza naszą kontrolą.
Nasz problem: wdrażamy urządzenia osadzone, które zbierają dane z czujników w różnych witrynach, głównie IPv4. Niektóre witryny mają źle utrzymywane sieci, np. Źle skonfigurowane lub w inny sposób uszkodzone pamięci podręczne DNS i / lub zapory ogniowe, które albo całkowicie ignorują zapytania AAAA, albo odpowiadają na nie zepsutymi odpowiedziami (np. Błędne IP źródłowe!). Jako zewnętrzny dostawca działu obiektów nie mamy prawie żadnego wpływu na (czasem niechętne) działy IT. Szanse na naprawienie serwerów DNS / zapór ogniowych w najbliższym czasie są znikome.
Wpływ na nasze urządzenie jest taki, że przy każdym gethostbyname () procesy muszą czekać, aż upłynie limit czasu zapytań AAAA, w którym to momencie niektóre procesy już całkowicie przekroczyły limit czasu prób połączenia.
Szukam rozwiązań, które są ...
- w całym systemie. Nie mogę indywidualnie konfigurować dziesiątek aplikacji
- niestałe i konfigurowalne. Musimy (ponownie) włączyć IPv6, gdzie / kiedy zostanie naprawiony / wdrożony. Ponowne uruchomienie jest w porządku.
- Jeśli rozwiązanie wymaga zastąpienia biblioteki podstawowej, takiej jak glibc, pakiet biblioteki zastępczej powinien być dostępny z dobrze znanego repozytorium (np. Debian Testing, Ubuntu Universe, EPEL). Samodzielne budowanie nie jest opcją z tak wielu powodów, że nawet nie wiem od czego zacząć, więc po prostu ich nie wymieniam ...
Najbardziej oczywistym rozwiązaniem byłoby skonfigurowanie biblioteki resolvera, np. Przez / etc / { resolv , nsswitch , gai } .conf, aby nie wyszukiwała rekordów AAAA. no-inet6
Sugerowana tutaj opcja resolv.conf byłaby dokładnie tym , czego szukam. Niestety nie jest zaimplementowany, przynajmniej nie w naszych systemach (libc6-2.13-38 + deb7u4 w Debian 7; libc6-2.19-0ubuntu6.3 w Ubuntu 14.04)
Jak więc? Można znaleźć następujące metody sugerowane na SF i gdzie indziej, ale żadna z nich nie działa:
- Całkowite wyłączenie IPv6, np. Przez umieszczenie na czarnej liście LKM ipv6 w /etc/modprobe.d/ lub
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Z ciekawości: Dlaczego resolver prosi o AAAA, gdy IPv6 jest wyłączony? ) - Usuwanie
options inet6
z /etc/resolv.conf. Po pierwsze, nie było go, obecnieinet6
jest po prostu domyślnie włączone. - Ustawienie
options single-request
w /etc/resolv.conf. Zapewnia to tylko, że zapytania A i AAAA są wykonywane sekwencyjnie, a nie równolegle - Zmiana
precedence
w /etc/gai.conf. Nie wpływa to na zapytania DNS, a jedynie na sposób przetwarzania wielu odpowiedzi. - Korzystanie z zewnętrznych programów tłumaczących (lub uruchamianie lokalnego demona tłumaczącego, który omija uszkodzone serwery DNS) pomógłby, ale zwykle jest to zabronione przez zasady zapory firmy. I może uniemożliwić dostęp do zasobów wewnętrznych.
Alternatywne brzydkie pomysły:
- Uruchom pamięć podręczną DNS na localhost. Skonfiguruj go, aby przekazywał wszystkie zapytania inne niż AAAA, ale odpowiadał na zapytania AAAA za pomocą NOERROR lub NXDOMAIN (w zależności od wyniku odpowiedniego zapytania A). Nie znam jednak pamięci podręcznej DNS, która mogłaby to zrobić.
- Użyj sprytnego dopasowania u32 iptables lub modułu DNS iptables Ondreja Caletki, aby dopasować zapytania AAAA, w celu ich odrzucenia przez icmp (jak zareaguje na to biblioteka tłumacząca?) Lub przekierowania ich na lokalny serwer DNS, który odpowiada na wszystko z pustym NOERROR.
Zauważ, że podobne pytania dotyczą SE. Moje pytanie różni się tym, że opisuje rzeczywisty problem, który próbuję rozwiązać, ponieważ zawiera wyraźne wymagania, ponieważ zawiera listę często sugerowanych niedziałających rozwiązań i nie jest specyficzny dla pojedynczej aplikacji. Po tej dyskusji opublikowałem swoje pytanie.
źródło
Odpowiedzi:
Przestań używać
gethostbyname()
. Powinieneś używaćgetaddrinfo()
zamiast tego i powinieneś być od lat. Strona podręcznika ostrzega cię nawet przed tym.Oto szybki przykładowy program w C, który pokazuje wyszukiwanie tylko rekordów A dla nazwy, i przechwycenie Wireshark pokazujące, że tylko wyszukiwania rekordów A przebiegały przez sieć.
W szczególności trzeba ustawić
ai_family
, abyAF_INET
jeśli tylko chcą wyszukiwań protokołem sporządzonym. Ten przykładowy program drukuje tylko zwrócone adresy IP. Zobaczgetaddrinfo()
stronę podręcznika, aby uzyskać pełniejszy przykład wykonywania połączeń wychodzących.W przechwytywaniu Wireshark 172.25.50.3 to lokalny program rozpoznawania nazw DNS; przechwytywanie zostało tam zrobione, więc można zobaczyć także wychodzące zapytania i odpowiedzi. Zauważ, że zażądano tylko rekordu A. Nigdy nie przeprowadzono wyszukiwania AAAA.
źródło
W razie wątpliwości przejdź do kodu źródłowego! Zobaczmy więc ... gethostbyname () wygląda interesująco; to dokładnie opisuje to, co widzimy: najpierw wypróbuj IPv6, a następnie wróć do IPv4, jeśli nie otrzymasz odpowiedzi, którą lubisz. Co to za
RES_USE_INET6
flaga? Śledząc to, pochodzi z res_setoptions () . To jest gdzieresolv.conf
jest czytane.I .... to ja z pomysłów. Nie jestem całkowicie pewien, jak to
RES_USE_INET6
się dzieje, jeśli nie jestresolv.conf
.źródło
options inet6
wresolv.conf
. Wydaje mi się, że moim problemem jest to, że nie można go rozbroić po ustawieniu go w czasie kompilacji, co wydaje się obecnie robić wszystkie główne dystrybucje (prawda?). Dlatego prośba o funkcję, ooptions no_inet6
której wspomniałem powyżej.no_inet6
opcji wres_setoptions()
. Jednak, jak widać z (nie-)ip6-dotint
, jest to łatwa zmiana do dodania. Aby przetestować teorię, że jest domyślnie ustawiana przez twoją dystrybucję, złapałbym pliki źródłowe pakietu i skompilowałem je raz „dziewicą” (aby potwierdzić, że pakiet replikuje zachowanie), a następnie dodałem:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
dooptions[]
tablicy i sprawdziłem, czy problem zniknie po ustawieniu tej opcji wresolv.conf
.Możesz użyć BIND jako lokalnego resolvera, ma opcję filtrowania AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
źródło
Czy próbowałeś skonfigurować rekursor PDNS, ustawić go w pliku /etc/resolv.conf i odmówić wyszukiwania w nim „AAAA”? Używanie czegoś podobnego
query-local-address6=
źródło
query-local-address6=
robi coś innego (z którego adresu IPv6 wysyłane są zapytania - zauważ, że nawet przy wyłączonym IPv6 żądania AAAA będą nadal rozpatrywane przez IPv4). Nie mogę też zidentyfikować żadnego innego ustawienia, które odfiltrowałoby zapytania AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Bez tych informacji twoja odpowiedź nie jest zbyt pomocna :(