1 puntos por GN⁺ 2024-09-18 | 2 comentarios | Compartir por WhatsApp
  • En Little Snitch 6.1, el cifrado DNS podía fallar en algunas situaciones, pero se acotó que no era un problema general de macOS sino de esa versión, y fue corregido en la 6.1.1
  • Para funcionar correctamente, las solicitudes DNS de macOS deben enviarse al proxy DNS de Little Snitch, y el proxy debe realizar las consultas cifradas
  • Durante la investigación se observó que algunas solicitudes hechas con API heredadas de bajo nivel no llegaban al proxy y enviaban consultas no cifradas por UDP 53 al servidor de nombres predeterminado del sistema
  • La reproducción consiste en activar el cifrado DNS en Little Snitch, ejecutar Wireshark con el filtro port 53 y luego llamar a getaddrinfo("dnsproxytest.com") en un playground de Xcode
  • Al principio parecía que las consultas basadas en API de alto nivel, como las de Safari y Chrome, no estaban afectadas, y que Firefox sí lo estaba, pero finalmente el alcance quedó acotado al proxy DNS de Little Snitch 6.1

Fallo de cifrado DNS ocurrido en Little Snitch 6.1

  • La función de cifrado DNS de Little Snitch 6 enruta las búsquedas de nombres de host a través de Little Snitch para procesarlas de forma cifrada
  • Para esto, Little Snitch registra un proxy DNS, y macOS debe enviar todas las solicitudes DNS a ese proxy
  • Se descubrió que algunas solicitudes DNS, en especial las realizadas mediante ciertas API heredadas de bajo nivel, no eran recibidas por el proxy
  • Esas solicitudes podían enviarse sin cifrar al servidor de nombres predeterminado del sistema, y en Wireshark podían verse como tráfico en el puerto UDP 53
  • En Little Snitch Network Monitor no aparecía ese tráfico de consultas, porque las búsquedas evitaban por completo el filtro de red

Pasos de reproducción y avance de las actualizaciones

  • Pasos de reproducción

    • Activar DNS encryption en la configuración de Little Snitch
    • Ejecutar Wireshark con el filtro de captura port 53
    • Ejecutar en un playground de Xcode una consulta a dnsproxytest.com con getaddrinfo
    • La consulta a dnsproxytest.com puede verse sin cifrar en UDP 53
  • Alcance inicial del impacto

    • Parecía que las consultas DNS hechas mediante API de alto nivel no estaban afectadas
    • Parecía que la navegación web en Safari y Chrome mantenía las ventajas de las consultas cifradas
    • Parecía que Firefox sí estaba afectado
  • Historial de actualizaciones

    • 2024-09-17 19:10: se confirmó que este problema podía existir desde macOS 14.5 Sonoma, y no fue posible probar sistemas 14.x más antiguos
    • 2024-09-18 12:05: se concluyó que no era un problema general del proxy DNS de macOS, sino uno que afectaba solo al proxy DNS de Little Snitch 6.1
    • 2024-09-18 15:52: el problema fue corregido en Little Snitch 6.1.1

2 comentarios

 
GN⁺ 2024-09-18
Opiniones de Hacker News
  • Se siente un poco raro que getaddrinfo() sea tratado como una “API heredada de bajo nivel”
    En macOS la situación puede ser muy distinta, pero en Linux y probablemente en *BSD es la forma estándar de hacer resolución de nombres
    La mayoría de las apps de macOS seguramente usan frameworks tipo Foundation o NetworkKit para las consultas DNS, pero también sorprende que por dentro eso no termine bajando a llamadas como getaddrinfo()
    Como GAI es bloqueante, quizá haya alguna otra llamada asíncrona de bajo nivel

    • Sí. CFNetwork es open source, así que se puede revisar la implementación, y recuerdo que cuando la vi hace tiempo usaba alguna variante como getaddrinfo_async
      Dicho eso, Apple no quiere que los usuarios finales resuelvan una IP directamente con getaddrinfo o con la variante asíncrona que expone CF, y luego hagan connect() a esa IP
      En general, te empujan a conectarte por nombre de host, para que Apple pueda encargarse internamente de su implementación de happy eyeballs
      Se puede ver por qué Apple no prefiere el modelo de getaddrinfo() en https://www.ietf.org/proceedings/72/slides/plenaryw-6.pdf. También hay notas del presentador debajo de cada diapositiva
    • No creo que getaddrinfo() se considere heredado. Me parece que ese post del blog se equivocó en esta parte
      Si es “de bajo nivel” o no depende del punto de vista
    • getaddrinfo() no es algo relacionado con Linux, es simplemente una función de glibc
      La gente asume que glibc es la forma estándar del espacio de usuario de Linux, pero no necesariamente tiene que ser así
      Por ejemplo, systemd creó su propio mecanismo resolved, y resultó ser mucho mejor que el de glibc
      Yo también estoy haciendo software independiente orientado a Linux, así que es muy probable que algún día haga algo similar por mi cuenta
    • En OpenBSD, al menos las funciones DNS tradicionales y estándar como getaddrinfo/gethostbyname son wrappers de la implementación asr de la libc de OpenBSD escrita por Eric Faurot
      https://man.openbsd.org/man3/asr_run.3
      https://github.com/openbsd/src/tree/master/lib/libc/asr
    • No sé si este caso sea exactamente eso, pero incluso con funciones del sistema que tienen el mismo nombre, la implementación interna puede variar mucho entre *Linux/BSD/macOS
      También hay diferencias entre los *BSD
      En algunos sistemas, una llamada de función se mantiene durante años y es “lo correcto”, pero en otros puede estar realmente obsoleta y no ser útil
  • El problema tratado aquí resultó no ser un problema general de macOS, sino algo específico de Little Snitch 6.1, y se corregirá con una actualización de Little Snitch más tarde hoy

    • Sería bueno que el título también pudiera actualizarse para reflejar esto
  • Tras investigar más, este bug ya existía al menos desde macOS 14.5 Sonoma
    Tal vez incluso desde antes, pero dicen que actualmente no tienen acceso a sistemas 14.x más antiguos para probar

    • Me pregunto si alguna vez probaron si realmente funcionaba con getaddrinfo
      O si solo vieron que funcionaba una vez con CFNetwork y dieron el tema por cerrado, para luego publicar un post de blog diciendo que se rompió
    • Sigue siendo absurdo que los desarrolladores tengan que conservar versiones antiguas del sistema operativo para hacer pruebas
      Hay casi cero razones técnicas para que Apple no permita hacer downgrade
    • Considerando que venden un producto y que el nuevo sistema operativo salió ayer, esto también es bastante ridículo
  • Sequoia, si el firewall de macOS está activado y una app está registrada como “bloquear conexiones entrantes”, rompe la capacidad de esa app de usar DNS, y probablemente las funciones basadas en UDP en general
    https://waclaw.blog/macos-firewall-blocking-web-browsing-aft...

    • No logro reproducirlo. Algunos dicen que está relacionado con ESET: https://www.reddit.com/r/MacOS/comments/1fievr5/updating_mad...
    • Antes de Sequoia, aunque usara OpenDNS en la VPN, iMessage y otras apps seguían funcionando mientras estaba conectado a la VPN; después de Sequoia, durante la conexión VPN ya no funcionan los mensajes de iMessage y cosas por el estilo
      Si desconecto la VPN, todo pasa
      Me pregunto si tendrá relación con esto. El firewall de macOS está activado, pero no está bloqueando todas las conexiones entrantes
    • Después de actualizar a Sequoia, no podía navegar con Safari ni Mozilla
      Entré a la configuración de DNS de la conexión Wi-Fi y agregué los servidores DNS de Google, 8.8.8.8 y 8.8.4.4, y eso lo solucionó; reemplazaron a los servidores DNS que estaban configurados automáticamente
    • Sinceramente, este comportamiento me parece bien. Las aplicaciones no deberían resolver DNS por su cuenta fuera de lo especificado en la configuración
      La razón por la que las apps hacen esto es impedir que el usuario bloquee cosas como la telemetría
      Es mi computadora, así que la decisión final sobre qué sale hacia afuera debería ser mía
  • El título sugiere que esto es intencional o que se aplica de forma privilegiada a Apple, pero en realidad parece más bien un simple bug.
    Cuando se reporta algo así, estaría bueno publicar también el número FB y los detalles del reporte.

    • Haciendo de abogado del diablo, también podrían haberlo hecho así a propósito para evitar la reacción negativa y hacer que parezca un bug que no corrigen.
      Mientras se logre el objetivo, la forma de implementarlo puede ser todo lo flexible que quieran.
    • Si hubiera sido intencional, probablemente habría sido una URL hardcodeada y cifrada.
      Algunos dispositivos ya empezaron a usar ese método para saltarse los bloqueadores de anuncios.
  • Quizá me equivoco, pero tengo un déjà vu de que cada nueva versión de iOS o Mac trae problemas de DNS que afectan a cosas como Little Snitch y Mullvad.
    Si es cierto, de verdad me pregunto qué hace Apple durante meses de pruebas para desarrolladores y betas.

  • La mención a Little Snitch me confundió, pero al leer más parece un bug de LS que ocurre solo en ciertos casos.
    Si este es el blog de LS, mi única duda es por qué lo describen como si fuera un bug de macOS.
    No digo que estén equivocados; es su área, no la mía, pero con solo el texto no parece estar bien justificado.

    • Si el SO permite registrar un proxy DNS y algunas llamadas se saltan ese proxy, eso es claramente un bug del SO.
  • Recuerdo que Apple había marcado como obsoleto para desarrolladores externos el uso de cierta API de red.
    Pero las propias apps de Apple, por ejemplo App Store, no están sujetas a la misma restricción.
    Por eso, cuando se intentaba filtrar el tráfico de red mediante un firewall de apps usando la API nueva, fallaba porque App Store usaba la API legacy.
    Podría ser parte de un bug viejo que yo creía que ya se había corregido.

    • getaddrinfo() no es una API legacy, sino una API estándar multiplataforma para consultas DNS.
  • Siempre son divertidos esos anuncios del tipo: “¡Bug encontrado en la nueva versión del SO! Corrección: en realidad era un bug que existía desde hace bastante tiempo”.

  • Uso routedns [0] como resolvedor stub local para elegir personalmente qué solicitudes enviar a dónde y con qué método de transporte.
    También permite listas de bloqueo, reescrituras, caché, balanceo de carga y manejo de solicitudes alternativas, así que da mucho control.
    Para las solicitudes locales uso un listener stub en localhost:53, y la mayoría de las solicitudes se reenvían con caché a Cloudflare 1.1.1.1 mediante UDP QUIC, es decir, TLS 0-RTT.
    Es rápido y bastante seguro.
    [0] https://github.com/folbricht/routedns

 
nearfall 2024-09-18

Gracias por la información importante.
Por lo pronto, es un alivio saber que Safari y Chrome parecen ser seguros.