... pour compenser les serveurs DNS cassés qui sont hors de notre contrôle.
Notre problème: nous déployons des périphériques intégrés qui collectent les données de capteurs sur divers sites, principalement IPv4. Certains sites ont des réseaux mal entretenus, par exemple des caches DNS et / ou des pare-feu mal configurés ou autrement cassés qui ignorent complètement les requêtes AAAA ou leur répondent avec des réponses cassées (par exemple, une adresse IP source incorrecte!). En tant que fournisseur externe du département des installations, nous n’avons pratiquement aucune influence sur les départements informatiques (parfois réticents). Les chances qu’ils réparent leurs serveurs / pare-feu DNS dans un proche avenir sont infimes.
L'effet sur notre périphérique est que, avec chaque gethostbyname (), les processus doivent attendre que les requêtes AAAA expirent, moment auquel certains processus ont déjà dépassé leur délai de tentative de connexion.
Je cherche des solutions qui sont ...
- à l'échelle du système. Je ne peux pas reconfigurer des dizaines d'applications individuellement
- non permanent et configurable. Nous devons (réactiver) IPv6 où / quand il est corrigé / déployé. Le redémarrage est OK.
- Si une solution nécessite le remplacement d’une bibliothèque principale telle que glibc, le package de bibliothèque de remplacement doit être disponible à partir d’un référentiel dont la maintenance est assurée (par exemple, Debian Testing, univers Ubuntu, EPEL). L'auto-construction n'est pas une option pour tant de raisons que je ne sais même pas par où commencer, alors je ne les énumère pas du tout ...
La solution la plus évidente serait de configurer la bibliothèque de résolveur, par exemple via / etc / { resolv , nsswitch , gai } .conf pour ne pas interroger les enregistrements AAAA. Une option de resolv.conf no-inet6
telle que suggérée ici serait exactement ce que je recherche. Malheureusement, il n'est pas implémenté, du moins pas sur nos systèmes (libc6-2.13-38 + deb7u4 sur Debian 7; libc6-2.19-0ubuntu6.3 sur Ubuntu 14.04)
Alors comment alors? On trouve les méthodes suivantes suggérées sur SF et ailleurs, mais aucune d'entre elles ne fonctionne:
- Désactiver complètement IPv6, par exemple en mettant en liste noire le LKM ipv6 dans /etc/modprobe.d/, ou
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Par curiosité: pourquoi le résolveur demande-t-il un AAAA lorsque IPv6 est désactivé? ) - Suppression
options inet6
de /etc/resolv.conf. Ce n'était pas là en premier lieu,inet6
est simplement activé par défaut ces jours-ci. - Configuration
options single-request
dans /etc/resolv.conf. Cela garantit uniquement que les requêtes A et AAAA sont effectuées de manière séquentielle plutôt qu'en parallèle - Changer
precedence
dans /etc/gai.conf. Cela n'affecte pas les requêtes DNS, mais seulement le traitement de plusieurs réponses. - L'utilisation de résolveurs externes (ou l'exécution d'un démon de résolveur local qui contourne les serveurs DNS cassés) serait utile, mais est généralement interdite par les stratégies de pare-feu de l'entreprise. Et cela peut rendre les ressources internes inaccessibles.
Idées alternatives laides:
- Exécuter un cache DNS sur localhost. Configurez-le pour transférer toutes les requêtes non-AAAA, mais pour répondre aux requêtes AAAA avec NOERROR ou NXDOMAIN (selon le résultat de la requête A correspondante). Je ne suis pas au courant d'un cache DNS capable de le faire cependant.
- Utilisez une correspondance intelligente iptables u32 ou le module DNS iptables d’ Ondrej Caletka pour faire correspondre les requêtes AAAA, afin de les rejeter par icmp (comment le résolver lib réagirait-il?) Ou de les rediriger vers un serveur DNS local qui répond tout avec un NOERROR vide.
Notez qu'il existe des questions similaires sur SE. Ma question diffère dans la mesure où elle élabore le problème que je tente de résoudre, car elle énonce des exigences explicites, une liste noire de solutions non fonctionnelles souvent proposées, et comme elle n'est pas spécifique à une seule application. Suite à cette discussion , j'ai posté ma question.
la source
Réponses:
Arrêtez d'utiliser
gethostbyname()
. Vous devriez utiliser à lagetaddrinfo()
place, et cela depuis des années. La page de manuel vous en avertit même.Voici un exemple de programme rapide en C qui illustre la recherche des noms A uniquement pour un nom et une capture de Wireshark indiquant que seules les recherches A ont été effectuées sur le réseau.
En particulier, vous devez définir
ai_family
surAF_INET
si vous souhaitez uniquement effectuer une recherche d'enregistrement. Cet exemple de programme imprime uniquement les adresses IP renvoyées. Voir lagetaddrinfo()
page de manuel pour un exemple plus complet sur la façon d'établir des connexions sortantes.Dans la capture Wireshark , 172.25.50.3 est le résolveur DNS local; la capture a été prise là-bas, de sorte que vous voyez également ses requêtes et réponses sortantes. Notez que seul un enregistrement A a été demandé. Aucune recherche AAAA n'a jamais été faite.
la source
En cas de doute, rendez-vous sur le code source! Voyons donc ... gethostbyname () a l' air intéressant; cela décrit exactement ce que nous voyons: essayez d’abord IPv6, puis utilisez IPv4 si vous n’obtenez pas la réponse qui vous convient. C'est quoi ce
RES_USE_INET6
drapeau? En le retraçant, cela provient de res_setoptions () . Ceci est oùresolv.conf
est lu dans.Et .... c'est moi à court d'idées. Je ne sais absolument pas comment cela se
RES_USE_INET6
passe, sinon dansresolv.conf
.la source
options inet6
inresolv.conf
. Je suppose que mon problème est qu’il ne peut pas être désactivé une fois qu’il a été défini au moment de la compilation, ce que toutes les principales distributions semblent faire ces jours-ci (correct?). Par conséquent, la demande de fonctionnalité pouroptions no_inet6
celle que j'ai mentionnée ci-dessus.no_inet6
option dansres_setoptions()
. Cependant, comme vous pouvez le voir sur (non)ip6-dotint
, c'est un changement facile à ajouter. Pour tester la théorie selon laquelle il est défini par défaut par votre distribution, saisissez les fichiers source du paquet et le compilez une fois "vierge" (pour confirmer que le paquet reproduit le comportement), puis ajoutez:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
auoptions[]
tableau et voyez si le problème disparaît lorsque vous définissez cette option dansresolv.conf
.Vous pouvez utiliser BIND en tant que résolveur local. Il existe une option pour filtrer AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
la source
Avez-vous essayé de configurer PDNS-recursor, définissez-le dans votre /etc/resolv.conf et refusez les recherches "AAAA"? En utilisant quelque chose comme
query-local-address6=
la source
query-local-address6=
fait quelque chose de différent (adresse IPv6 à partir de laquelle envoyer les requêtes - notez que même si IPv6 est désactivé, les demandes AAAA seront toujours résolues via IPv4). De plus, je ne peux identifier aucun autre paramètre filtrant les requêtes AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Sans cette information, votre réponse ne serait pas très utile :(