"La red está caída" no es un diagnóstico. Una conexión atraviesa resolución de nombre, enrutamiento, un puerto de destino, TCP, normalmente TLS y por fin un protocolo de aplicación. Pruébalos en ese orden y la caída difusa se convierte en un solo paso fallido.
🎙️ Publicado y grabado: ·
Tu aplicación escribe bytes en un socket. TCP parte ese flujo de bytes en segmentos, controla el orden y retransmite lo que falta. IP mete esos segmentos en paquetes y mueve cada paquete hacia una dirección de destino. Ethernet o Wi-Fi transporta tramas por el enlace actual. A los routers les importa IP; no entienden tu error en JSON.
HTTP request bytes
↓ application
TLS records # when HTTPS is used
↓
TCP segments # ordered, reliable byte stream
↓
IP packets # source and destination addresses
↓
Ethernet / Wi-Fi frames # one local hop at a time
DNS traduce un hostname a una o más direcciones IP. IPv4 se ve como cuatro números decimales; IPv6 es hexadecimal y mucho más grande. Después de resolver, el enrutamiento IP elige un camino hacia la dirección. Un mismo hostname puede devolver direcciones distintas según región, red u hora, así que anota la dirección que realmente recibió el cliente que falla.
# Resolve without making a TCP connection
nslookup api.example.com
# or
dig api.example.com A +short
dig api.example.com AAAA +short
# Inspect the route, not the application
tracert api.example.com # Windows
traceroute api.example.com # Linux/macOS
No escribas una IP de producción dentro de una URL HTTPS y llames a eso una prueba limpia de DNS. La selección del certificado TLS y los virtual hosts de HTTP necesitan el hostname. Usa curl --resolve para fijar una dirección sin perder el nombre real del host.
Una dirección IP lleva el tráfico a una máquina o interfaz de red. Un puerto lo lleva a un servicio. Un socket en escucha está enlazado a una dirección local y un puerto. Un socket TCP conectado se identifica por dirección de origen, puerto de origen, dirección de destino y puerto de destino, así que miles de clientes pueden hablar con el mismo puerto del servidor a la vez.
client 192.0.2.44:53182 → 203.0.113.10:443 server
temporary port HTTPS listener
# See listeners
ss -lntp # Linux
netstat -ano | findstr LISTEN # Windows
lsof -nP -iTCP -sTCP:LISTEN # macOS/Linux
Error: listen EADDRINUSE: address already in use 0.0.0.0:3000. Uno: inspecciona el puerto tres mil con ss, lsof o netstat -ano. Dos: asocia el PID a un proceso. Tres: detén con calma la instancia zombi, o configura otro puerto. Cuatro: reinicia y verifica que exista exactamente un listener esperado. Matar todos los procesos llamados Node esconde bugs de supervisión y puede tumbar apps que no tenían nada que ver.Antes de que fluyan bytes de aplicación, el cliente envía SYN, el servidor responde SYN-ACK y el cliente contesta ACK. Eso negocia los números de secuencia iniciales y confirma que hay camino en ambos sentidos. Después, TCP presenta un flujo ordenado de bytes. No tiene mensajes: dos escrituras pueden llegar como una sola lectura, y una escritura puede requerir varias lecturas.
client server
| -------- SYN, seq=x --------------> |
| <----- SYN-ACK, seq=y, ack=x+1 ---- |
| -------- ACK, ack=y+1 ------------> |
| ===== application byte stream ===== |
| -------- FIN ---------------------> | # orderly close
La fiabilidad de TCP no es paciencia infinita. Las retransmisiones ocurren por debajo de tu app, pero la aplicación sigue necesitando deadlines de conexión, de lectura y totales. Un handshake exitoso solo demuestra que algo aceptó TCP en esa dirección y puerto. No demuestra que TLS, la autenticación o la ruta HTTP pedida funcionen.
Rechazo es una respuesta rápida: el host de destino o una regla de rechazo activa dijo que nada acepta esa conexión. Timeout es silencio: los paquetes se descartaron, se enrutaron a ninguna parte útil o las respuestas no pudieron volver. Tratar ambos como "servidor caído" desperdicia la información que la red ya te dio.
Error: connect ECONNREFUSED 127.0.0.1:5432
Error: connect ETIMEDOUT 203.0.113.10:443
# Test only TCP reachability to the destination port
Test-NetConnection api.example.com -Port 443 # PowerShell
nc -vz api.example.com 443 # Linux/macOS
curl -v --connect-timeout 5 https://api.example.com/
127.0.0.1 por accidente. Dos: en el servidor, confirma que el servicio está corriendo. Tres: inspecciona la dirección y el puerto a los que está enlazado el listener. Cuatro: prueba localmente en el servidor y luego desde el cliente. Si local funciona y remoto es rechazado, revisa la dirección de bind, la publicación de puertos del contenedor y las reglas de rechazo activas.127.0.0.1 y ::1 son direcciones de loopback. El tráfico nunca sale de ese namespace de red. Un servidor enlazado a loopback solo acepta clientes locales. Enlazar a 0.0.0.0 significa escuchar en todas las interfaces IPv4; no es un destino que los clientes deban usar. Dentro de un contenedor, localhost significa ese contenedor, no el host y no otro contenedor.
# Reachable only inside the same host or container
server.listen(3000, "127.0.0.1")
# Reachable on the container's interfaces; publish separately
server.listen(3000, "0.0.0.0")
docker run -p 8080:3000 my-app
# Verify the actual bind
ss -lntp | grep :3000
LISTEN 0 511 127.0.0.1:3000 ...
curl http://127.0.0.1:3000. Dos: mira ss -lnt; si muestra 127.0.0.1:3000, cambia el bind de la app a 0.0.0.0. Tres: verifica que el contenedor publique el puerto, por ejemplo el ocho mil ochenta del host al tres mil del contenedor. Cuatro: prueba el puerto del host. Cinco: solo entonces revisa firewalls del host o de la nube. Exponer el puerto no puede arreglar una app enlazada al loopback del contenedor.Los rangos IPv4 privados se reutilizan dentro de las redes y no se enrutan por internet público. Un gateway NAT reescribe direcciones y puertos de origen privados a una dirección pública para las conexiones salientes, y luego mapea las respuestas de vuelta. El tráfico entrante no solicitado no tiene mapeo, salvo que agregues port forwarding o un balanceador de carga.
10.0.0.24:53182 → NAT → 198.51.100.7:62014 → internet
private host public mapping
Private IPv4:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
# Public-looking address from outside
curl https://ifconfig.example # use a trusted endpoint you control
NAT no es una política de seguridad. Los mapeos con estado bloquean de casualidad casi todo el tráfico entrante no solicitado, pero la autorización pertenece a un firewall y a la aplicación. Recuerda también el NAT de operador: dos routers pueden traducir la conexión, y eso vuelve imposible el port forwarding doméstico sin apoyo del proveedor, IPv6, un túnel o un relay.
Una regla de firewall normalmente considera protocolo, origen, destino, puerto, sentido, interfaz y estado de la conexión. Las redes en la nube agregan security groups y ACLs de red antes del firewall del host. Kubernetes agrega Services y NetworkPolicies. Una regla en verde en un panel demuestra muy poco si otra capa descarta el mismo paquete.
# Minimum question, stated precisely
Allow TCP from 198.51.100.0/24
to 10.0.2.15 destination port 443
with return traffic for established connections
# Linux host checks vary by system
sudo nft list ruleset
sudo ufw status verbose
# Windows
Get-NetFirewallProfile
Get-NetFirewallRule -Enabled True
Una petición HTTPS es una pila de dependencias. DNS devuelve una IP. TCP conecta a un puerto. TLS autentica el hostname y crea el cifrado. HTTP envía método, ruta, headers y cuerpo. Prueba en ese orden. Mi opinión firme: ping es una prueba de disponibilidad débil. Muchos servidores sanos bloquean ICMP, y una máquina que responde ping puede no tener ninguna aplicación funcionando.
# 1. DNS
nslookup api.example.com
# 2. TCP port
Test-NetConnection api.example.com -Port 443
# 3 and 4. TLS plus HTTP, with verbose evidence
curl -v --connect-timeout 5 https://api.example.com/health
# Bypass DNS while preserving hostname for TLS and HTTP
curl -v --resolve api.example.com:443:203.0.113.10 \
https://api.example.com/health
# Listener ownership
ss -lntp | grep :443
netstat -ano | findstr :443
lsof -nP -iTCP:443 -sTCP:LISTEN
Could not resolve host es DNS. Failed to connect es TCP. certificate verify failed es identidad o confianza de TLS. Un 404 de HTTP demuestra que DNS, TCP y normalmente TLS funcionaron; ahora revisa el header Host y la ruta. Nunca uses -k como solución de producción para un fallo de certificado.Ejecuta la prueba desde la máquina o el contenedor que realmente falla. Una petición exitosa desde tu laptop demuestra el camino de tu laptop, no el del worker de producción.
1. Record exact HOST:PORT and failing client location
2. Resolve A and AAAA; note the returned addresses
3. Test TCP to that exact port with a short deadline
4. On server: verify process + bound address + listener
5. Check container/service port publication
6. Check route, NAT, cloud rules, and host firewall
7. Test TLS with the real hostname
8. Send the smallest HTTP request; read status and headers
ECONNREFUSED → host answered; no listener or active reject
ETIMEDOUT → dropped path, wrong route, or missing return path
EADDRINUSE → another socket already owns address and port
404 → network stack worked; inspect host/path/routing
TLS error → TCP worked; inspect name, chain, date, trust
localhost → this network namespace only
0.0.0.0 → listen on all IPv4 interfaces; not a client address
ping works → only ICMP replied
ping fails → server may still be healthy
Best evidence: timestamp, client, resolved IP, HOST:PORT,
listener output, curl -v trace, and firewall packet counters.
La regla que vale la pena guardar es simple: nombra la capa que falló antes de cambiar nada. Resuelve el nombre, alcanza la dirección, conecta al puerto, verifica TLS y después habla HTTP. "Las redes" se vuelven manejables cuando cada prueba hace una sola pregunta y la siguiente acción sale de la respuesta exacta.