Diagnosticar la red en diez minutos
Un guion de seis comandos que convierte "debe de ser la red" en "es la capa X, en el tramo Y".
"Debe de ser la red" es la frase más dicha y menos verificada en los incidentes. La mayoría de las veces es el servicio. Pero se dice porque nadie en el equipo sabe comprobarlo.
Este es el guion para comprobarlo. Seis comandos, en orden, subiendo por las capas. Cada uno elimina una hipótesis.
Primero: entiende el síntoma
Antes de los comandos, el tipo de fallo ya te dice mucho:
→ Timeout total, no responde nada → capa 3 o 4. Enrutamiento, firewall, servicio caído.
→ Conecta y se cuelga → capa 4, o el servicio no está respondiendo.
→ Error de certificado → TLS.
→ Respuesta HTTP con código de error → capa 7. La red está bien; el problema es la aplicación.
→ Funciona a veces → pérdida de paquetes, un nodo malo detrás de un balanceador, o DNS con varios registros y uno de ellos roto.
Esa clasificación lleva diez segundos y ahorra muchísimo.
Paso 1: ¿resuelve el nombre?
dig api.ejemplo.com
dig +trace api.ejemplo.comSi no resuelve, es DNS. Se acabó la investigación, y ya sabes con quién hablar.
El +trace muestra la cadena completa, de la raíz al servidor autoritativo. Útil cuando la respuesta
es inconsistente entre sitios.
Fíjate en el TTL de la respuesta. Si acabas de cambiar el registro y el TTL es de 1800 segundos, la mitad de los clientes va a seguir pegándole a la IP antigua durante media hora.
Los fallos clásicos de DNS:
→ TTL alto a la hora de migrar. Bájalo con antelación.
→ Caché eterna en el proceso. Muchos lenguajes cachean DNS en el proceso e ignoran el TTL. El servidor cambia de IP y la aplicación no se entera hasta reiniciar.
→ ndots en Kubernetes. El valor por defecto es 5, lo que significa que un nombre con menos de
cinco puntos se prueba contra varios sufijos de búsqueda antes de resolver. Una llamada externa puede
convertirse en cuatro o cinco consultas. En volumen, eso tumba el DNS del clúster. Compruébalo con
cat /etc/resolv.conf dentro del pod.
Paso 2: ¿llega al destino?
mtr -rwzbc 100 api.ejemplo.comping resuelve poco, porque muchas redes bloquean o despriorizan ICMP. Prefiere mtr, que muestra
latencia y pérdida salto a salto.
Cómo leerlo: pérdida en un salto intermedio que no se propaga a los siguientes normalmente es el router despriorizando ICMP, y se puede ignorar. Pérdida que empieza en un salto y continúa hasta el destino es un problema real en ese tramo.
Paso 3: ¿abre el puerto?
nc -zv api.ejemplo.com 443Si el nombre resuelve y el puerto no abre, es firewall, security group, network policy, o el servicio no está escuchando.
En la nube, ese es el paso que más frecuentemente encuentra el problema, y la causa suele ser un security group que permite la salida pero no la entrada, o una NACL que bloquea el retorno.
Paso 4: ¿cierra el TLS?
openssl s_client -connect api.ejemplo.com:443 -servername api.ejemplo.comAquí ves la cadena de certificados, la validez y el nombre presentado.
Los problemas comunes: certificado caducado (sigue pasando, mucho); cadena incompleta, que funciona en tu navegador, con el intermedio en caché, y falla en el servidor que no lo tiene; y SNI equivocado, cuando la misma IP hospeda varios dominios.
El -servername existe justamente para probar el SNI.
Paso 5: ¿responde el HTTP, y adónde se va el tiempo?
curl -w "dns:%{time_namelookup} conn:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" -o /dev/null -s https://api.ejemplo.com/rutaEste es el comando más útil de la lista, porque descompone el tiempo por fase.
→ time_namelookup alto → DNS
→ time_connect alto → latencia de red o cola en el destino
→ time_appconnect alto → handshake TLS
→ time_starttransfer alto con los anteriores bajos → el servidor está lento. La red está bien.
Esa última línea es la que más frecuentemente termina la discusión sobre "es la red".
Ejecútalo dos veces seguidas: la segunda debe ser más rápida por la caché de DNS.
Paso 6: ¿cómo está la conexión por dentro?
ss -ti
ss -tan | awk '{print $1}' | sort | uniq -cEl primero muestra las conexiones TCP con detalle: ventana, tiempo de ida y vuelta estimado, y retransmisiones. Una retransmisión alta es pérdida de paquetes, y la pérdida de paquetes destroza el rendimiento mucho más de lo que el porcentaje sugiere, porque TCP lo interpreta como congestión y reduce la ventana.
El segundo cuenta los estados, y resuelve una confusión clásica:
→ Mucho CLOSE_WAIT = bug tuyo. El otro lado cerró y tu aplicación no llamó a close. Cada uno
retiene un descriptor.
→ Mucho TIME_WAIT = normal en un servicio de alto volumen. Aparece en el lado que cerró, dura unos 60 segundos por diseño. Se vuelve problema solo cuando se acaban los puertos efímeros, y la corrección correcta no es tocar el kernel: es dejar de abrir una conexión nueva en cada llamada.
- dig¿resuelve?Si el nombre no resuelve, es DNS y la investigación se acabó. Mira el TTL antes de migrar.
- mtr¿llega?Pérdida que empieza en un salto y sigue hasta el destino es problema real. Si no se propaga, es ICMP despriorizado.
- nc¿abre el puerto?Nombre que resuelve y puerto cerrado es firewall, security group o servicio que no escucha.
- openssl s_client¿cierra el TLS?Certificado caducado, cadena incompleta o SNI equivocado. El -servername existe para probar el último.
- curl -w¿adónde va el tiempo?Descompone por fase. TTFB alto con el resto bajo significa servidor lento, no red.
- ss -ti¿y por dentro?Retransmisión es pérdida de paquetes. CLOSE_WAIT acumulado es bug tuyo, TIME_WAIT es normal.
El bug fantasma: MTU
Un caso que merece mención porque es difícil y recurrente.
Síntoma: la conexión se establece, las peticiones pequeñas funcionan, y las grandes se cuelgan sin error.
Causa: el MTU del camino es menor que el de tu host, lo que es común con VPN, túneles y algunas redes de nube. El paquete grande necesita fragmentarse, el router envía un ICMP "fragmentación necesaria" (tipo 3, código 4), y alguien en el camino bloquea ICMP.
El remitente nunca se entera. El paquete desaparece. Y el síntoma parece de aplicación.
Corrección: MSS clamping en el router, o reducir el MTU. Diagnóstico: ping -M do -s 1400 variando el
tamaño hasta encontrar dónde deja de pasar.
Guarda el retrato de la normalidad
El consejo más útil de este artículo:
Ejecuta los seis comandos contra tu servicio más crítico mientras está sano. Guarda la salida en un archivo versionado.
La próxima vez que haya un problema, vas a tener con qué comparar, que es exactamente lo que siempre falta a las tres de la mañana.
Lee esto después
- IngenieríaPaso 18OAuth2, OIDC y JWT sin misterioLas tres siglas más confundidas de la autenticación, qué resuelve cada una, y los errores que aparecen en casi todo el código.Leer artículo
- IngenieríaPaso 17Las vulnerabilidades que aparecen de verdadLa mayoría de las filtraciones que salen en las noticias no usa técnicas sofisticadas. Usa uno de estos seis fallos, y los seis tienen corrección conocida y barata.Leer artículo
- IngenieríaPaso 15Por qué tu servicio empeora con el tiempoEl servicio arranca bien y empeora a lo largo de los días. Tres causas explican casi todos los casos, y las tres tienen señales distintas.Leer artículo