TCP/IP: encuentra la capa rota

"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: ·

01Las capas convierten una petición en paquetes

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
El modelo es una herramienta de depuraciónSi DNS no logra devolver una dirección, TCP ni empezó. Si la conexión TCP fue rechazada, HTTP ni empezó. Si TLS rechaza un certificado, cambiar una ruta REST no arregla nada. Deja de llamar "problema de la API" a fallos que ocurren antes de que exista una petición a la API.

02DNS nombra; las direcciones IP enrutan

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.

03Un puerto selecciona el proceso que escucha

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
EADDRINUSE, resuelto paso a pasoError: 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.

04El handshake TCP comprueba las dos direcciones

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.

05Conexión rechazada no es un timeout

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/
ECONNREFUSED, resuelto paso a pasoUno: verifica el host y el puerto del error, sobre todo si aparece un 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.
ETIMEDOUT, resuelto paso a pasoUno: resuelve el hostname y anota todos los resultados IPv4 e IPv6. Dos: haz una prueba específica del puerto, no solo ping. Tres: revisa la salida del cliente, las reglas de seguridad de la nube, el firewall del host, la ruta, la VPN y el camino de retorno del NAT. Cuatro: captura tráfico en el servidor: si no llega ningún SYN, el camino lo descartó; si llega SYN sin respuesta, el camino de vuelta o el firewall del servidor están mal. Reiniciar la app al azar no es un diagnóstico de timeout.

06localhost es privado; 0.0.0.0 es una instrucción de bind

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 ...
Dentro del contenedor funciona, fuera rechazaUno: entra al contenedor y haz 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.

07NAT reescribe conversaciones privadas

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.

08Los firewalls deciden por dirección, tupla y estado

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
No "desactives todos los firewalls un momentito"Eso destruye evidencia y puede dejar la máquina expuesta. Agrega una regla estrecha y con log para el origen, destino, protocolo y puerto exactos; vuelve a probar; luego quítala o formalízala. Si los contadores de paquetes siguen en cero, el tráfico nunca llegó a esa regla. Sigue hacia afuera: tablas de rutas, balanceadores y controles de la nube.

09DNS, TCP, TLS y después HTTP

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
Lee dónde se detuvo curlCould 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.

10Cheat sheet de depuración TCP/IP

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.

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.