... para compensar los servidores DNS rotos que están fuera de nuestro control.
Nuestro problema: implementamos dispositivos integrados que recopilan datos de sensores en varios sitios, principalmente IPv4. Algunos sitios tienen redes mal mantenidas, por ejemplo, cachés DNS o firewalls mal configurados o rotos que ignoran las consultas AAAA por completo o responden a ellas con respuestas rotas (¡por ejemplo, IP de fuente incorrecta!). Como proveedor externo del departamento de instalaciones, casi no tenemos influencia en los departamentos de TI (a veces reacios). Las posibilidades de que arreglen sus servidores / firewalls DNS en el corto plazo son mínimas.
El efecto en nuestro dispositivo es que con cada gethostbyname (), los procesos tienen que esperar hasta que se agote el tiempo de espera de las consultas AAAA, momento en el que algunos procesos ya han agotado por completo sus intentos de conexión.
Estoy buscando soluciones que sean ...
- todo el sistema No puedo reconfigurar docenas de aplicaciones individualmente
- no permanente y configurable. Necesitamos (re) habilitar IPv6 donde / cuando se arregla / implementa. Reiniciar está bien.
- Si una solución requiere que se reemplace una biblioteca central como glibc, el paquete de la biblioteca de reemplazo debe estar disponible en un repositorio conocido por estar bien mantenido (por ejemplo, Debian Testing, Ubuntu universe, EPEL). La autoconstrucción no es una opción por tantas razones que ni siquiera sé por dónde empezar, así que simplemente no las enumero en absoluto ...
La solución más obvia sería configurar la biblioteca de resolución, por ejemplo, a través de / etc / { resolv , nsswitch , gai } .conf para no consultar registros AAAA. Una opción resolv.conf no-inet6
como se sugiere aquí sería exactamente lo que estoy buscando. Desafortunadamente no está implementado, al menos no en nuestros sistemas (libc6-2.13-38 + deb7u4 en Debian 7; libc6-2.19-0ubuntu6.3 en Ubuntu 14.04)
Entonces, ¿cómo entonces? Uno encuentra los siguientes métodos sugeridos en SF y en otros lugares, pero ninguno de ellos funciona:
- Deshabilitar por completo IPv6, por ejemplo, mediante la inclusión en la lista negra del Lvm ipv6 en /etc/modprobe.d/, o
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Por curiosidad: ¿por qué el solucionador solicita AAAA cuando IPv6 está desactivado? ) - Eliminando
options inet6
de /etc/resolv.conf. En primer lugar, no estaba allí,inet6
simplemente está habilitado de forma predeterminada en estos días. - Configuración
options single-request
en /etc/resolv.conf. Esto solo asegura que las consultas A y AAAA se realicen secuencialmente en lugar de en paralelo. - Cambiando
precedence
en /etc/gai.conf. Eso no afecta las consultas DNS, solo cómo se procesan las respuestas múltiples. - El uso de solucionadores externos (o la ejecución de un demonio de resolución local que eluda los servidores DNS dañados) ayudaría, pero generalmente no está permitido por las políticas de firewall de la compañía. Y puede hacer que los recursos internos sean inaccesibles.
Ideas feas alternativas:
- Ejecute un caché DNS en localhost. Configúrelo para reenviar todas las consultas que no sean AAAA, pero para responder a las consultas AAAA con NOERROR o NXDOMAIN (dependiendo del resultado de la consulta A correspondiente). Sin embargo, no conozco un caché DNS capaz de hacer esto.
- Utilice alguna coincidencia inteligente de iptables u32, o el módulo DNS de iptables de Ondrej Caletka para que coincida con las consultas AAAA, a fin de rechazarlas por icmp (¿cómo reaccionaría el lib de resolución a eso?), O redirigirlas a un servidor DNS local que responda a todo con un NOERROR vacío.
Tenga en cuenta que hay preguntas similares relacionadas con SE. Mi pregunta difiere en la medida en que elabora el problema real que estoy tratando de resolver, ya que enumera los requisitos explícitos, ya que incluye en la lista negra algunas soluciones no operativas sugeridas a menudo, y como no es específico de una sola aplicación. Después de esta discusión , publiqué mi pregunta.
fuente
Respuestas:
Deja de usar
gethostbyname()
. Debería usarlo en sugetaddrinfo()
lugar, y debería haberlo hecho durante años. La página del manual incluso te advierte de esto.Aquí hay un programa de muestra rápida en C que muestra cómo buscar solo registros A para un nombre, y una captura de Wireshark que muestra que solo las búsquedas de registros A pasaron por la red.
En particular, es necesario conjunto
ai_family
deAF_INET
si sólo desea una búsquedas de registros realizados. Este programa de muestra solo imprime las direcciones IP devueltas. Consulte lagetaddrinfo()
página del manual para obtener un ejemplo más completo de cómo hacer conexiones salientes.En la captura de Wireshark , 172.25.50.3 es el solucionador de DNS local; la captura se realizó allí, por lo que también verá sus consultas y respuestas salientes. Tenga en cuenta que solo se solicitó un registro A. No se realizó ninguna búsqueda AAAA.
fuente
En caso de duda, dirígete al código fuente. Entonces, veamos ... gethostbyname () parece interesante; eso describe exactamente lo que estamos viendo: primero intente con IPv6, luego recurra a IPv4 si no obtiene la respuesta que desea. ¿Qué es esta
RES_USE_INET6
bandera? Al rastrearlo, proviene de res_setoptions () . Aquí es donderesolv.conf
se lee.Y ... ese soy yo sin ideas. No estoy completamente claro cómo se está
RES_USE_INET6
configurando si no está dentroresolv.conf
.fuente
options inet6
inresolv.conf
. Supongo que mi problema es que no se puede desarmar una vez que se configuró en tiempo de compilación, lo que todas las principales distribuciones parecen hacer en estos días (¿correcto?). Por lo tanto, la solicitud de característicasoptions no_inet6
que mencioné anteriormente.no_inet6
opción enres_setoptions()
. Sin embargo, como puede ver en (no)ip6-dotint
, es un cambio fácil de agregar. Para probar la teoría de que su distribución está configurada de manera predeterminada, tomaría los archivos fuente del paquete y lo compilaría una vez "virgen" (para confirmar que el paquete replica el comportamiento) y luego agregaría:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
a laoptions[]
matriz y ver si El problema desaparece cuando configura esa opciónresolv.conf
.Puede usar BIND como un solucionador local, tiene una opción para filtrar AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
fuente
¿Intentó configurar PDNS-recursor, configurarlo en su /etc/resolv.conf y negar las búsquedas "AAAA" en él? Usando algo como
query-local-address6=
fuente
query-local-address6=
hace algo diferente (desde qué dirección IPv6 enviar consultas; tenga en cuenta que incluso con IPv6 deshabilitado, las solicitudes AAAA se resolverán a través de IPv4). Además, no puedo identificar ninguna otra configuración que filtre las consultas AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Sin esa información, su respuesta no es muy útil :(