... para compensar servidores DNS quebrados que estão fora de nosso controle.
Nosso problema: implantamos dispositivos incorporados que coletam dados do sensor em vários sites, principalmente apenas no IPv4. Alguns sites têm redes com manutenção insuficiente, por exemplo, caches DNS e / ou firewalls mal configurados ou quebrados, que ignoram completamente as consultas AAAA ou respondem a elas com respostas quebradas (por exemplo, IP de origem incorreto!). Como fornecedor externo do departamento de instalações, quase não temos influência nos departamentos de TI (às vezes relutantes). As chances de consertar seus servidores / firewalls DNS tão cedo são mínimas.
O efeito em nosso dispositivo é que, a cada gethostbyname (), os processos precisam aguardar o tempo limite das consultas AAAA; nesse momento, alguns processos já atingiram o tempo limite de suas tentativas de conexão.
Estou procurando soluções que sejam ...
- sistema amplo. Não consigo reconfigurar dezenas de aplicativos individualmente
- não permanente e configurável. Precisamos (re) habilitar o IPv6 onde / quando ele for corrigido / implementado. Reiniciar está OK.
- Se uma solução exigir que uma biblioteca principal como o glibc seja substituída, o pacote da biblioteca de substituição deve estar disponível em um repositório conhecido por ser bem mantido (por exemplo, Debian Testing, Ubuntu universe, EPEL). Auto-construção não é uma opção por tantas razões que eu nem sei por onde começar, então simplesmente não as listo ...
A solução mais óbvia seria configurar a biblioteca do resolvedor, por exemplo, via / etc / { resolv , nsswitch , gai } .conf para não consultar registros AAAA. Uma opção resolv.conf no-inet6
como sugerida aqui seria exatamente o que estou procurando. Infelizmente não está implementado, pelo menos não em nossos sistemas (libc6-2.13-38 + deb7u4 no Debian 7; libc6-2.19-0ubuntu6.3 no Ubuntu 14.04)
Então como então? Encontramos os seguintes métodos sugeridos no SF e em outros lugares, mas nenhum deles funciona:
- Desabilitando completamente o IPv6, por exemplo, na lista negra do ipv6 LKM em /etc/modprobe.d/, ou
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Por curiosidade: por que o resolvedor está pedindo AAAA em que o IPv6 está desativado? ) - Removendo
options inet6
do /etc/resolv.conf. Não estava lá em primeiro lugar,inet6
é simplesmente ativado por padrão hoje em dia. - Configurando
options single-request
em /etc/resolv.conf. Isso garante apenas que as consultas A e AAAA sejam feitas seqüencialmente e não em paralelo - Mudando
precedence
no /etc/gai.conf. Isso não afeta as consultas DNS, apenas como várias respostas são processadas. - Usar resolvedores externos (ou executar um daemon de resolução local que contorna os servidores DNS quebrados) ajudaria, mas geralmente não é permitido pelas políticas de firewall da empresa. E isso pode tornar os recursos internos inacessíveis.
Idéias feias alternativas:
- Execute um cache DNS no host local. Configure-o para encaminhar todas as consultas que não sejam AAAA, mas para responder às consultas AAAA com NOERROR ou NXDOMAIN (dependendo do resultado da consulta A correspondente). Não estou ciente de um cache DNS capaz de fazer isso.
- Use alguma combinação inteligente de iptables u32 ou o módulo DNS de Ondrej Caletka para corresponder às consultas AAAA, para rejeitá-las pelo icmp (como a lib do resolvedor reagiria a isso?) Ou para redirecioná-las para um servidor DNS local que responda a tudo com um NOERROR vazio.
Observe que existem perguntas semelhantes e relacionadas no SE. Minha pergunta difere na medida em que elabora o problema real que estou tentando resolver, uma vez que lista requisitos explícitos, pois lista negativamente algumas soluções não funcionais frequentemente sugeridas e não é específica para um único aplicativo. Após essa discussão , postei minha pergunta.
fonte
Respostas:
Pare de usar
gethostbyname()
. Você deveria estar usandogetaddrinfo()
, e deveria ter sido por anos agora. A página do manual até avisa sobre isso.Aqui está um exemplo de programa rápido em C que demonstra a busca apenas de registros A para um nome e uma captura do Wireshark mostrando que apenas as pesquisas de registro A foram feitas na rede.
Em particular, você precisa conjunto
ai_family
paraAF_INET
se você quiser apenas uma pesquisas recordes feitas. Este programa de amostra imprime apenas os endereços IP retornados. Consulte agetaddrinfo()
página do manual para obter um exemplo mais completo de como fazer conexões de saída.Na captura do Wireshark , 172.25.50.3 é o resolvedor de DNS local; a captura foi feita lá, para que você também veja suas consultas e respostas de saída. Observe que apenas um registro A foi solicitado. Nenhuma pesquisa AAAA foi feita.
fonte
Em caso de dúvida, vá para o código fonte! Então, vamos ver ... gethostbyname () parece interessante; que descreve exatamente o que estamos vendo: tente o IPv6 primeiro e depois volte ao IPv4 se você não obtiver a resposta que deseja. O que é essa
RES_USE_INET6
bandeira? Rastreando de volta, é proveniente de res_setoptions () . É aqui queresolv.conf
é lido.E .... esse sou eu sem idéias. Não sei ao certo como
RES_USE_INET6
está sendo definido, se não estiverresolv.conf
.fonte
options inet6
inresolv.conf
. Acho que meu problema é que ele não pode ser desabilitado depois de definido em tempo de compilação, o que todas as principais distribuições parecem fazer atualmente (correto?). Portanto, o pedido de recurso para ooptions no_inet6
que eu mencionei acima.no_inet6
opção nores_setoptions()
. No entanto, como você pode ver em (não)ip6-dotint
, é uma alteração fácil de adicionar. Para testar a teoria de que ele está sendo definido por padrão pela sua distribuição, pegue os arquivos de origem do pacote e o compile uma vez "virgem" (para confirmar que o pacote replica o comportamento) e depois adicione:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
aooptions[]
array e veja se o O problema desaparece quando você define essa opçãoresolv.conf
.Você pode usar o BIND como um resolvedor local, ele tem uma opção para filtrar o AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
fonte
Você tentou configurar o PDNS-recursor, configurá-lo no seu /etc/resolv.conf e negar pesquisas "AAAA" nele? Usando algo como
query-local-address6=
fonte
query-local-address6=
faz algo diferente (de qual endereço IPv6 o qual enviar consultas - observe que, mesmo com o IPv6 desativado, as solicitações AAAA ainda serão resolvidas via IPv4). Também não consigo identificar nenhuma outra configuração que filtre as consultas AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Sem essa informação, a sua resposta não é muito útil :(