
Conjunto de herramientas de medición DNS, solución de problemas y auditoría de seguridad
[](https://pypi.python.org/pypi/dnsdiag/) []() [](https://pepy.tech/project/dnsdiag) [](https://pepy.tech/project/dnsdiag) []() [](https://hub.docker.com/r/farrokhi/dnsdiag) [](https://github.com/farrokhi/dnsdiag/stargazers)
Conjunto de herramientas para medición, solución de problemas y auditoría de seguridad de DNS
===============================================================
¿Alguna vez te has preguntado si tu ISP está [interceptando tu tráfico
DNS](https://medium.com/decentralize-today/is-your-isp-hijacking-your-dns-traffic-f3eb7ccb0ee7)?
¿Has notado algún comportamiento inusual en tus respuestas DNS, o has sido redirigido a
la dirección incorrecta y sospechas que algo podría estar mal con tu DNS? Ofrecemos un
conjunto de herramientas para realizar auditorías básicas de tus solicitudes y respuestas DNS, ayudándote
a asegurar que tu DNS funcione como se espera.
Con `dnsping`, puedes medir el tiempo de respuesta de cualquier servidor DNS para consultas
arbitrarias. Similar a la utilidad ping normal, dnsping ofrece una funcionalidad
comparable para solicitudes DNS, ayudándote a monitorear la capacidad de respuesta del servidor.
También puedes rastrear la ruta de tu solicitud DNS hasta su destino usando
`dnstraceroute`, verificando que no esté siendo redirigida o interceptada. Al
comparar consultas DNS enviadas al mismo servidor, `dnstraceroute` te permite
observar cualquier diferencia en las rutas tomadas, alertándote sobre posibles problemas.
`dnseval` evalúa múltiples resolutores DNS para ayudarte a elegir el mejor resolutor DNS
para tu red. Aunque se recomienda usar tu propio resolutor DNS para evitar
depender de resolutores DNS de terceros, `dnseval` puede ayudar a seleccionar el
resolutor DNS óptimo cuando sea necesario. Te permite comparar servidores DNS según
rendimiento (latencia) y confiabilidad (pérdida de paquetes), dándote una visión
integral para la toma de decisiones informadas.
# Instalación
Hay varias formas de usar este conjunto de herramientas, aunque recomendamos ejecutarlo
directamente desde el código fuente para una flexibilidad y control óptimos. Ejecutar desde
el código fuente o instalar con pip requiere Python 3.11 o superior.
## Código fuente
1. Clona el repositorio git e instala las dependencias:
```
git clone https://github.com/farrokhi/dnsdiag.git
cd dnsdiag
pip3 install -r requirements.txt
```
2. Alternativamente, puedes instalar el paquete usando pip:
```
pip3 install dnsdiag
```
## Usando uv (Recomendado)
[uv](https://docs.astral.sh/uv/) es un gestor de paquetes de Python rápido que puede ejecutar herramientas directamente sin instalación:
```bash
# Run dnsping directly without installation
uvx --from dnsdiag dnsping google.com
# Run with specific options
uvx --from dnsdiag dnsping -c 5 --tls -s 8.8.8.8 example.com
# Run dnstraceroute
uvx --from dnsdiag dnstraceroute cloudflare.com
# Run dnseval
uvx --from dnsdiag dnseval -f public-servers.txt github.com
```
Para instalar dnsdiag de forma persistente:
```bash
# Install dnsdiag tools
uv tool install dnsdiag
# Upgrade to the latest version
uv tool upgrade dnsdiag
```
## Paquete binario
De vez en cuando, se publicarán paquetes binarios para Windows, Mac OS X y Linux. Puedes obtener la última versión desde la [página de releases](https://github.com/farrokhi/dnsdiag/releases).
### Plataformas compatibles
Hay binarios precompilados disponibles para:
- Linux (x86_64, ARM64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
Windows ARM64 no es compatible actualmente debido a dependencias de compilación que requieren cadenas de herramientas de compilación nativas que no están fácilmente disponibles. Si usas Windows en ARM, puedes ejecutar dnsdiag usando el Subsistema de Windows para Linux (WSL2) o instalar directamente desde el código fuente.
## Docker
Si prefieres no instalar `dnsdiag` en tu máquina local, puedes usar la
imagen Docker para ejecutar las herramientas en un entorno contenedorizado. Por ejemplo:
```
docker run --network host -it --rm farrokhi/dnsdiag dnsping.py
```
# dnsping
`dnsping` te permite hacer "ping" a un resolutor DNS enviando una consulta DNS arbitraria varias veces. Para obtener una lista completa de las opciones de línea de comandos compatibles, usa `--help`. Aquí hay algunas opciones clave:
- Usa `--tcp`, `--tls`, `--doh`, `--quic` o `--http3` para seleccionar el protocolo de transporte (el predeterminado es UDP). Estas opciones son mutuamente excluyentes; solo se puede especificar un protocolo por comando.
- Usa `--flags` para mostrar los flags de respuesta, incluidos los flags EDNS, para cada respuesta.
- Usa `--dnssec` para solicitar validación DNSSEC, si está disponible.
- Los mensajes de Error DNS Extendido ([RFC 8914](https://www.rfc-editor.org/rfc/rfc8914)) se muestran automáticamente cuando están presentes.
- Usa `--nsid` para mostrar el Identificador del Servidor de Nombres (NSID) si está disponible ([RFC 5001](https://www.rfc-editor.org/rfc/rfc5001)).
- Usa `--ecs` para incluir información de Subred de Cliente EDNS para la optimización del enrutamiento geográfico.
- Usa `--cookie` para mostrar las cookies DNS ([RFC 7873](https://www.rfc-editor.org/rfc/rfc7873)) cuando estén presentes en las respuestas.
```shell
./dnsping.py -c 5 --dnssec --flags --tls -t AAAA -s 8.8.8.8 brokendnssec.net
```
```
dnsping.py DNS: 8.8.8.8:853, hostname: brokendnssec.net, proto: TLS, class: IN, type: AAAA, flags: [RD]
75 bytes from 8.8.8.8: seq=1 time=73.703 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=2 time=69.523 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=3 time=58.058 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=4 time=54.235 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=5 time=57.806 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
--- 8.8.8.8 dnsping statistics ---
5 requests transmitted, 5 responses received, 0% lost
min=54.235 ms, avg=22.665 ms, max=69.523 ms, stddev=38.202 ms
```
`dnsping` también proporciona estadísticas como tiempos de respuesta mínimos, máximos y
promedio, junto con jitter (desviación estándar) y pérdida de paquetes.
Aquí hay algunos casos de uso interesantes para `dnsping`:
- Comparar tiempos de respuesta entre diferentes protocolos de transporte (por ejemplo, UDP vs. DoH).
- Evaluar la confiabilidad de tu servidor DNS midiendo el jitter y la pérdida de paquetes.
- Medir tiempos de respuesta con DNSSEC habilitado usando el flag `--dnssec`.
- Probar el comportamiento de la Subred de Cliente EDNS para respuestas con reconocimiento de geolocalización:
```shell
./dnsping.py -c 3 --ecs 203.0.113.0/24 -s 94.140.14.14 google.com
```
```
dnsping.py DNS: 94.140.14.14:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
66 bytes from 94.140.14.14: seq=1 time=31.407 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=2 time=29.156 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=3 time=30.892 ms NOERROR [ECS:203.0.113.0/24/24]
--- 94.140.14.14 dnsping statistics ---
3 requests transmitted, 3 responses received, 0% lost
min=29.156 ms, avg=30.485 ms, max=31.407 ms, stddev=1.176 ms
```
- Identificar servidores DNS usando la opción NSID:
```shell
./dnsping.py -c 2 --nsid -s 8.8.8.8 google.com
```
```
dnsping.py DNS: 8.8.8.8:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
68 bytes from 8.8.8.8: seq=1 time=36.399 ms NOERROR [NSID:gpdns-ams]
68 bytes from 8.8.8.8: seq=2 time=32.156 ms NOERROR [NSID:gpdns-ams]
--- 8.8.8.8 dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=32.156 ms, avg=34.278 ms, max=36.399 ms, stddev=2.122 ms
```
- Probar cookies DNS para mayor seguridad y optimización de caché:
```shell
./dnsping.py -c 2 --cookie -s anyns.pch.net quad9.net
```
```
dnsping.py DNS: anyns.pch.net:53, hostname: quad9.net, proto: UDP, class: IN, type: A, flags: [RD]
82 bytes from anyns.pch.net: seq=1 time=30.552 ms NOERROR [COOKIE:27f609c017bb2ec4ea70de5c68eec3fc39f6a53ee49c55f8]
82 bytes from anyns.pch.net: seq=2 time=24.794 ms NOERROR [COOKIE:719631dd9fcce722d3ac859b68eec3fd2e5430b5c8a7f8cf]
--- anyns.pch.net dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=24.794 ms, avg=27.673 ms, max=30.552 ms, stddev=4.072 ms
```
## Interpretación de flags DNSSEC y relacionados con la seguridad
Al usar `--dnssec` y `--flags`, `dnsping` expone campos del protocolo DNS que son
directamente relevantes para la validación de seguridad DNS. Estos valores indican si un
resolutor es capaz de validar DNSSEC y si una respuesta fue verificada
correctamente.
Flags comunes:
- **DO (DNSSEC OK)**
Indica que el cliente está solicitando registros relacionados con DNSSEC. Su presencia
muestra que el resolutor admite consultas DNSSEC.
- **AD (Authenticated Data)**
Establecido por resolutores que validan cuando la respuesta ha sido validada
criptográficamente usando DNSSEC. Esta es una señal fuerte de que la validación DNSSEC está activa
y es exitosa.
Patrones típicos:
| Resultado | Significado |
|-------|--------|
| `NOERROR` con flag `AD` | La validación DNSSEC fue exitosa |
| `SERVFAIL` con flag `DO` | La validación DNSSEC falló (a menudo debido a firmas rotas o mala configuración) |
| Sin flag `AD` presente | El resolutor no está realizando validación DNSSEC |
Los Errores DNS Extendidos (EDE, RFC 8914) proporcionan información de diagnóstico adicional cuando
falla la validación DNSSEC. Por ejemplo:
- **EDE:10** – *DNSSEC Bogus* (datos DNSSEC inválidos o rotos)
- **EDE:6** – *DNSSEC Signature Expired*
- **EDE:7** – *DNSSEC Signature Not Yet Valid*
Estos indicadores hacen que `dnsping` sea útil no solo para pruebas de rendimiento, sino también
para validar si los resolutores aplican correctamente DNSSEC y para diagnosticar
problemas de despliegue de DNSSEC.
# dnstraceroute
`dnstraceroute` es una utilidad que rastrea la ruta de tus solicitudes DNS hasta su
destino. Es posible que quieras comparar esto con tu traceroute de red real para
asegurarte de que tu tráfico DNS no esté siendo enrutado a través de rutas no deseadas.
`dnstraceroute` admite múltiples protocolos de transporte (mutuamente excluyentes):
- UDP (predeterminado) - Consultas DNS tradicionales
- TCP (`--tcp`) - DNS sobre TCP
- DoQ (`--quic`) - DNS sobre QUIC (compatible con AdGuard DNS)
- DoH3 (`--http3`) - DNS sobre HTTP/3 (compatible con Google DNS y Cloudflare)
```shell
./dnstraceroute.py --expert --asn -C -t A -s 8.8.4.4 facebook.com
```
También puedes probar protocolos DNS modernos:
```shell
# Test DNS over QUIC with AdGuard DNS
./dnstraceroute.py --quic -s 94.140.14.14 -c 3 google.com
# Test DNS over HTTP/3 with Google DNS
./dnstraceroute.py --http3 -s 8.8.8.8 -c 3 google.com
```
```
dnstraceroute.py DNS: 8.8.4.4:53, hostname: facebook.com, rdatatype: A
1 192.168.0.1 (192.168.0.1) 1 ms
2 192.168.28.177 (192.168.28.177) 4 ms
3 192.168.0.1 (192.168.0.1) 693 ms
4 172.19.4.17 (172.19.4.17) 3 ms
5 dns.google (8.8.4.4) [AS15169 GOOGLE, US] 8 ms
=== Expert Hints ===
[*] public DNS server is next to a private IP address (possible hijacking)
```
Usar el flag `--expert` con `dnstraceroute` habilitará la visualización de pistas
expertas, incluidas advertencias sobre posibles secuestros de tráfico DNS.
# dnseval
`dnseval` es una utilidad de ping masivo que envía consultas DNS arbitrarias a una lista
especificada de servidores DNS, permitiéndote comparar sus tiempos de respuesta
simultáneamente.
Puedes usar `dnseval` para evaluar tiempos de respuesta entre diferentes protocolos de
transporte, incluidos UDP (predeterminado), TCP, DoT (DNS sobre TLS), DoH (DNS sobre
HTTPS), DoQ (DNS sobre QUIC) y DoH3 (DNS sobre HTTP/3) usando los flags `--tcp`,
`--tls`, `--doh`, `--quic` y `--http3`, respectivamente. Estas opciones de protocolo son mutuamente excluyentes; solo se puede especificar una por comando.
## Resumen de compatibilidad de protocolos
| Herramienta | UDP | TCP | TLS (DoT) | DoH | DoQ | DoH3 |
|------|-----|-----|-----------|-----|-----|------|
| `dnsping` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `dnstraceroute` | ✓ | ✓ | - | - | ✓ | ✓ |
| `dnseval` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
*DoQ: DNS sobre QUIC, DoH3: DNS sobre HTTP/3*
```shell
./dnseval.py --skip-warmup --dnssec -c10 -f public-servers.txt ripe.net
```
```
server avg(ms) min(ms) max(ms) stddev(ms) lost(%) ttl flags response
---------------------------------------------------------------------------------------------------------------------
1.0.0.1 29.01 14.15 45.36 8.60 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.1 23.90 18.14 42.07 7.83 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.2 25.90 21.36 31.58 4.26 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.2 22.68 18.36 32.15 3.96 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.3 22.53 18.98 32.52 3.94 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.3 21.70 20.25 22.97 0.77 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1001 21.70 19.13 27.50 2.28 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1111 22.63 20.42 30.18 3.13 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1002 24.97 20.89 44.63 7.16 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1112 23.24 21.37 25.87 1.48 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1003 21.68 19.28 24.88 1.65 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1113 22.61 19.86 26.09 1.73 %0 299 QR -- -- RD RA AD -- DO NOERROR
195.46.39.39 25.56 16.42 55.37 15.37 %0 300 QR -- -- RD RA -- -- -- NOERROR
195.46.39.40 19.08 16.51 23.86 2.24 %0 300 QR -- -- RD RA -- -- -- NOERROR
2a05:d014:939:3300::39 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
2a05:d014:939:3300::40 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
208.67.220.220 30.60 14.54 120.64 31.88 %0 300 QR -- -- RD RA AD -- DO NOERROR
208.67.222.222 21.78 17.42 36.45 6.06 %0 50 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccc::2 29.48 19.23 98.29 24.22 %0 299 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccd::2 22.36 17.90 30.18 3.98 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.35.35 172.53 114.46 360.87 71.47 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.36.36 187.36 118.21 324.32 59.08 %0 110 QR -- -- RD RA AD -- DO NOERROR
209.244.0.3 46.49 25.23 115.86 28.19 %0 300 QR -- -- RD RA -- -- DO NOERROR
209.244.0.4 58.33 28.09 109.18 29.20 %0 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.1 64.58 30.21 86.79 30.19 %25 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.2 40.54 22.69 74.80 20.76 %0 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.3 90.62 90.62 90.62 0.00 %50 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.4 31.53 23.80 70.93 14.51 %0 294 QR -- -- RD RA -- -- DO NOERROR
4.2.2.5 24.11 24.05 24.18 0.09 %33 294 QR -- -- RD RA -- -- DO NOERROR
80.80.80.80 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
80.80.81.81 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
8.8.4.4 28.35 20.85 39.14 7.24 %0 300 QR -- -- RD RA AD -- DO NOERROR
8.8.8.8 21.22 16.22 24.93 2.39 %0 299 QR -- -- RD RA AD -- DO NOERROR
```
También puedes guardar los resultados en formato JSONL para su posterior procesamiento. Cada línea del archivo de salida es un objeto JSON válido que contiene los resultados completos de medición para un servidor DNS.
```shell
./dnseval.py -c 5 -j results.jsonl -f public-servers.txt example.com
```
La salida se puede analizar línea por línea con herramientas JSON estándar como `jq`.
```shell
cat results.jsonl | jq -r 'select(.data.r_lost_percent == 0) | .data.resolver'
```
### Autor
Babak Farrokhi
- github: [github.com/farrokhi](https://github.com/farrokhi/)
- website: [farrokhi.net](https://farrokhi.net/)
- mastodon: [@[email protected]](https://unix.family/@farrokhi)
- twitter: [@farrokhi](https://twitter.com/farrokhi)
### Licencia
dnsdiag se publica bajo una licencia BSD de 2 cláusulas.