Debian/Ubuntu «Funciona en LAN, falla en WAN»: comprobaciones de enrutamiento y NAT que revelan la causa (caso n.º 25)

¿Te fue útil?

Todo funciona en la LAN. SSH va bien, HTTP va bien, DNS parece sano. Luego pruebas desde «afuera» (VPN, hotspot móvil, red de un socio, Internet real) y está muerto. O peor: funciona a medias, con timeouts que parecen una broma.

Este patrón de fallo rara vez es «la aplicación». Casi siempre es enrutamiento, NAT, filtrado o una discrepancia silenciosa entre lo que crees que hace la ruta y lo que realmente hacen los paquetes a las 2 a. m. La cura no es mágica. Es metódica, basada en capturas y un poco implacable con las suposiciones.

El modelo mental: por qué el éxito en LAN no demuestra casi nada

Cuando un servicio «funciona en LAN», has demostrado exactamente una cosa: algo puede llegar a él por una ruta directamente alcanzable con traducción mínima y, a menudo, con una política de firewall más simple. El tráfico LAN tiende a ser:

  • De un solo salto o con pocos saltos (el enrutamiento es más simple).
  • A menudo no sufre NAT (o el NAT se comporta de forma distinta).
  • Menos propenso a atravesar middleboxes stateful con timeouts estrictos.
  • Menos probable que tenga enrutamiento asimétrico (la ruta de retorno suele ser obvia).
  • Menos probable que active reglas de endurecimiento para acceso público.

El tráfico WAN añade capas: routers de borde, CPE del ISP, security groups, balanceadores en la nube y NAT—a veces múltiples NAT apilados como panqueques hechos de desdicha.

El truco diagnóstico es dejar de pensar en términos de «el cliente no puede conectar» y empezar a pensar en fases del paquete:

  1. Ingreso: ¿Llega el SYN/UDP a la interfaz del servidor que esperas?
  2. Política local: ¿Lo acepta Linux (firewall, rp_filter, conntrack)?
  3. Enlace del servicio: ¿Está la aplicación vinculada a la IP/puerto correctos y accesible por esa ruta?
  4. Ruta de retorno: ¿Sale la respuesta por el mismo borde (o al menos por uno enrut able)?
  5. Traducción: ¿El NAT reescribe las direcciones/puertos correctamente y mantiene el estado?

Si puedes responder esas cinco, normalmente puedes nombrar la causa raíz con confianza, no con corazonadas.

Guion de diagnóstico rápido (primero/segundo/tercero)

Primero: demuestra si los paquetes llegan al equipo

Ejecuta una captura en la interfaz pública mientras intentas una conexión desde la WAN. Si no ves paquetes entrantes, el problema está aguas arriba (NAT/port forward de borde, firewall del ISP, security group en la nube, IP pública equivocada).

Segundo: demuestra si el equipo responde y hacia dónde van las respuestas

Si ves que llega el SYN, busca inmediatamente el SYN-ACK saliente. Si sale por una interfaz distinta a la esperada, estás en terreno de enrutamiento asimétrico/policy routing. Si no sale ninguna respuesta, estás en terreno de firewall/rp_filter/vinculación de la aplicación.

Tercero: demuestra estado y traducción

Si ves respuestas salir pero el cliente nunca las recibe, revisa el estado de NAT (conntrack) y los dispositivos intermedios. Muchos casos de «falla en WAN» son tráfico de retorno siendo NATeado incorrectamente, descartado por rp_filter o fallando por problemas de MTU/MSS en el camino WAN.

Regla de opinión: No «añadas una regla y ya». Captura primero, cambia segundo. Si no, acumularás arreglos hasta que no puedas razonar sobre el sistema.

Datos interesantes y contexto histórico (9 puntos rápidos)

  1. El NAT no fue el plan original. Se popularizó en los años 1990 cuando la escasez de IPv4 se encontró con el acceso broadband de consumo.
  2. netfilter en Linux llegó en la era del kernel 2.4. Reemplazó a ipchains y convirtió el firewall stateful en algo común en Linux.
  3. conntrack es memoria de estado. NAT depende del seguimiento de conexiones; si conntrack está lleno, aparecen fallos «aleatorios» que no son aleatorios.
  4. rp_filter existe para combatir spoofing. El filtrado por ruta inversa descarta paquetes que «no deberían» llegar por una interfaz, lo cual es útil hasta que tienes enrutamiento asimétrico o policy routing.
  5. Path MTU Discovery ha sido frágil durante décadas. Filtrar ICMP «Fragmentation Needed» rompe PMTUD, provocando bloqueos solo en WAN y bugs «misteriosos» de MSS/MTU.
  6. Hairpin NAT es un tipo especial de torpeza. Acceder a un servicio por su IP pública desde dentro de la misma NAT puede fallar a menos que el router soporte reflection/hairpinning.
  7. nftables no eliminó iptables de la noche a la mañana. Muchas distribuciones ejecutan iptables como capa de compatibilidad sobre nftables, lo que puede confundir la depuración si no verificas qué está activo realmente.
  8. Las rutas por defecto son políticas. Hosts multi-homed (dos uplinks) necesitan políticas explícitas; de lo contrario Linux elige la «mejor» ruta que solo es la mejor en su propia lógica.
  9. UDP «funciona en LAN» no es lo mismo que «funciona en WAN». Los timeouts de NAT y firewalls stateful tratan UDP como un efímero.

Tareas prácticas: comandos, salidas y decisiones (14 tareas)

Todas las tareas asumen Debian/Ubuntu en el lado del servidor salvo indicación. Sustituye nombres de interfaces, IPs y puertos por tu realidad. El punto es la forma de la evidencia.

Task 1: Confirmar que el servicio escucha en la IP y puerto correctos

cr0x@server:~$ sudo ss -lntup | grep -E '(:80|:443|:22)\b'
tcp   LISTEN 0      4096         0.0.0.0:80        0.0.0.0:*    users:(("nginx",pid=1432,fd=6))
tcp   LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=911,fd=3))
tcp   LISTEN 0      4096            [::]:443          [::]:*    users:(("nginx",pid=1432,fd=7))

Qué significa: Si ves 127.0.0.1:80 o una dirección solo privada, WAN no funcionará (la app no está vinculada al camino público). Si solo ves [::]:443 y tu prueba WAN es IPv4, puede que estés escuchando solo en IPv6 o viceversa.

Decisión: Arregla las direcciones de enlace primero. No toques NAT hasta que el servicio sea accesible en la interfaz/IP que esperas.

Task 2: Verificar la política de firewall local (nftables/iptables/UFW) sin adivinar

cr0x@server:~$ sudo nft list ruleset | sed -n '1,140p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    tcp dport { 22, 80, 443 } accept
    ip protocol icmp accept
    counter drop
  }
}

Qué significa: Policy drop por defecto con permisos explícitos está bien. Que falte el puerto de tu servicio no está bien. Si usas UFW, puede estar gestionando reglas internamente, pero nft muestra lo que está activo realmente.

Decisión: Si la WAN llega directamente a este host, abre el puerto aquí. Si el tráfico se DNATea a un host interno, ábrelo también en el host de destino.

Task 3: Comprobar si iptables es en realidad nftables con disfraz

cr0x@server:~$ sudo iptables -V
iptables v1.8.9 (nf_tables)

Qué significa: Tus comandos iptables pueden estar manipulando el backend de nftables. Está bien, pero mezclar herramientas «legacy» y «nf_tables» puede producir reglas que no ves donde buscas.

Decisión: Elige una vista (preferible nft list ruleset) y mantenla mientras depuras.

Task 4: Confirmar la tabla de enrutamiento y la ruta por defecto en el servidor

cr0x@server:~$ ip route
default via 203.0.113.1 dev eth0 proto dhcp src 203.0.113.20 metric 100
10.10.0.0/24 dev eth1 proto kernel scope link src 10.10.0.10
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.20

Qué significa: El servidor cree que las respuestas a Internet salen por eth0 vía 203.0.113.1. Si tu camino WAN es en realidad otra interfaz, has encontrado un problema central.

Decisión: Si estás multi-homed, prepárate para usar enrutamiento por política (ip rule) en lugar de «esperar» que Linux elija la interfaz que prefieres.

Task 5: Inspeccionar reglas de policy routing (los reyes silenciosos)

cr0x@server:~$ ip rule show
0:      from all lookup local
100:    from 10.10.0.0/24 lookup 100
32766:  from all lookup main
32767:  from all lookup default

Qué significa: El tráfico originado en 10.10.0.0/24 usa la tabla de enrutamiento 100. Eso puede causar fallos en WAN si el tráfico de retorno para una conexión WAN usa la IP de origen equivocada o el uplink equivocado.

Decisión: Si un servicio WAN se DNATea a 10.10.0.10, asegúrate de que las respuestas vuelvan por la interfaz que el cliente puede alcanzar, normalmente el mismo gateway NAT.

Task 6: Comprobar rp_filter (filtrado por ruta inversa), el clásico asesino «solo WAN»

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.eth0.rp_filter net.ipv4.conf.eth1.rp_filter
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.eth1.rp_filter = 1

Qué significa: El modo estricto (1) descarta paquetes si el kernel piensa que la ruta de retorno no usaría la misma interfaz. El enrutamiento asimétrico o el policy routing pueden activar descartes antes de que el firewall local siquiera vote.

Decisión: Si tienes enrutamiento asimétrico por diseño (multi-uplink, VRFs, policy routing), configura rp_filter a loose (2) en las interfaces afectadas, o desactívalo con cuidado (0) donde corresponda.

Task 7: Demuestra que los paquetes llegan: tcpdump en la interfaz hacia WAN

cr0x@server:~$ sudo tcpdump -ni eth0 'tcp port 443 and (tcp[tcpflags] & (tcp-syn) != 0)'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:10.101010 IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 101 ecr 0,nop,wscale 7], length 0

Qué significa: Llega el SYN. El enrutamiento upstream y la IP pública están bien. Ahora la pelota está en tu cancha: política local, NAT o enrutamiento de retorno.

Decisión: Si no ves paquetes, deja de editar el servidor. Arregla NAT de borde, security groups, firewall upstream o la situación de «IP pública equivocada».

Task 8: Demuestra que las respuestas salen: captura SYN y SYN-ACK juntos

cr0x@server:~$ sudo tcpdump -ni eth0 'host 198.51.100.88 and tcp port 443'
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:44:10.101010 IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 101 ecr 0,nop,wscale 7], length 0
12:44:10.101200 IP 203.0.113.20.443 > 198.51.100.88.50122: Flags [S.], seq 987654321, ack 1234567891, win 65160, options [mss 1460,sackOK,TS val 202 ecr 101,nop,wscale 7], length 0

Qué significa: El servidor responde correctamente por la interfaz correcta. Si el cliente aún no puede conectar, algo entre servidor y cliente está descartando respuestas (firewall de borde, ISP, protección DDoS, estado NAT incorrecto).

Decisión: Desplaza el foco hacia afuera: dispositivo perimetral, gateway NAT, firewall en la nube o la ruta de retorno más allá de este host.

Task 9: Detectar enrutamiento de retorno asimétrico (respuesta sale por la interfaz equivocada)

cr0x@server:~$ sudo tcpdump -ni any 'host 198.51.100.88 and tcp port 443'
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
12:44:10.101010 eth0  IP 198.51.100.88.50122 > 203.0.113.20.443: Flags [S], seq 1234567890, win 64240, length 0
12:44:10.101300 eth1  IP 10.10.0.10.443 > 198.51.100.88.50122: Flags [S.], seq 987654321, ack 1234567891, win 65160, length 0

Qué significa: El SYN llegó por eth0 a la IP pública, pero el SYN-ACK sale desde la IP privada por eth1. El cliente nunca aceptará eso. Esta es la firma de selección de IP de origen equivocada, policy routing o rutas sin src.

Decisión: Arregla la selección de dirección de origen y el enrutamiento. Arreglos típicos: establecer src correcto en rutas, añadir ip rule por origen o asegurar que los servicios DNATeados respondan vía el gateway NAT.

Task 10: Validar reglas NAT en un gateway (MASQUERADE/SNAT/DNAT)

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100; policy accept;
    tcp dport 443 dnat to 10.10.0.10:443
  }
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oif "eth0" masquerade
  }
}

Qué significa: DNAT envía el 443 a un servidor interno. El postrouting masquerade asegura que las respuestas que salen por eth0 tengan una fuente pública. Si falta el masquerade, los hosts internos pueden responder con direcciones privadas que mueren en Internet.

Decisión: Si los clientes WAN no completan el handshake, confirma que tanto DNAT (entrada) como SNAT/MASQUERADE (salida) están correctos para la ruta.

Task 11: Confirmar que el reenvío está habilitado (solo relevante en gateways/routers)

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Qué significa: Si este es un gateway NAT y ip_forward es 0, puedes DNATear todo el día y nada se reenviará. Las pruebas en LAN aún pueden funcionar si estás evitando el gateway o golpeando servicios localmente.

Decisión: Si esperas que este equipo haga routing/NAT, net.ipv4.ip_forward debe ser 1 y la cadena forward debe permitir tráfico.

Task 12: Comprobar la utilización de conntrack (el problema de «funciona hasta el pico»)

cr0x@server:~$ sudo conntrack -S
cpu=0 found=120 new=42 invalid=3 ignore=0 delete=8 delete_list=8 insert=42 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cpu=1 found=115 new=38 invalid=1 ignore=0 delete=6 delete_list=6 insert=38 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cr0x@server:~$ cat /proc/sys/net/netfilter/nf_conntrack_count
51234
cr0x@server:~$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536

Qué significa: Estás cerca del máximo. Cuando la tabla se llena, las conexiones nuevas se descartan. Las pruebas LAN pueden tener éxito porque no atraviesan NAT/conntrack, o porque la ruta LAN es más simple.

Decisión: Si los contadores se acercan al máximo, incrementa nf_conntrack_max, reduce timeouts para protocolos ruidosos o deja de canalizar todo a través de una sola tabla de estado saturada.

Task 13: Detectar problemas de MTU/MSS (bloqueos en WAN, paquetes pequeños funcionan)

cr0x@server:~$ ip link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
cr0x@server:~$ ping -M do -s 1472 198.51.100.1 -c 3
PING 198.51.100.1 (198.51.100.1) 1472(1500) bytes of data.
From 203.0.113.20 icmp_seq=1 Frag needed and DF set (mtu = 1492)
From 203.0.113.20 icmp_seq=2 Frag needed and DF set (mtu = 1492)
From 203.0.113.20 icmp_seq=3 Frag needed and DF set (mtu = 1492)

--- 198.51.100.1 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2031ms

Qué significa: Tu path MTU es menor que 1500 (común con PPPoE/VPN). Si ICMP está bloqueado upstream, PMTUD se rompe y las sesiones TCP pueden colgar a mitad de camino—a menudo solo en WAN.

Decisión: Arregla la MTU en la interfaz/túnel, permite ICMP «Fragmentation needed» o aplica clamp MSS en el firewall de borde para TCP.

Task 14: Confirmar que DNS no es el verdadero culpable (split-horizon, A/AAAA equivocados)

cr0x@server:~$ dig +short app.example.internal A
10.10.0.10
cr0x@server:~$ dig +short app.example.internal @1.1.1.1 A
203.0.113.20

Qué significa: DNS interno devuelve IP privada; resolver público devuelve IP pública. Eso es normal para split-horizon. Se convierte en problema cuando clientes en «WAN-pero-no-realmente» (usuarios VPN, redes de socios) obtienen la vista equivocada.

Decisión: Decide qué clientes deben ver qué dirección. Arregla el reenvío condicional en el DNS de la VPN, o deja de usar un nombre para dos mundos a menos que puedas controlar los resolvers.

Broma #1: NAT es como la política de oficina: todo funciona hasta que alguien pregunta quién está realmente autorizado para hablar con quién.

Tres microhistorias corporativas desde las trincheras

Microhistoria 1: El outage causado por una suposición errónea

Una compañía ejecutaba un portal de clientes detrás de un reverse proxy basado en Debian. Internamente, todos accedían por el nombre del servicio, que resolvía a un VIP privado. Desde Internet, resolvía a una IP pública en un firewall de borde que reenviaba el 443 al mismo reverse proxy.

Un equipo montó un segundo uplink para «redundancia». El servidor se volvió multi-homed: eth0 hacia el firewall, eth1 hacia un nuevo appliance SD-WAN. Asumieron que Linux «haría lo correcto» y devolvería el tráfico por la interfaz por la que había entrado. Linux hizo lo que Linux hace: enrutó según sus tablas, no según las esperanzas de nadie.

Las pruebas LAN siguieron pasando porque los clientes internos golpeaban el VIP privado y el tráfico se quedaba en el lado privado. Las pruebas WAN fallaban de forma intermitente. A veces el handshake tenía éxito, a veces no, dependiendo de qué dirección de origen se seleccionara y qué regla de enrutamiento ganara en ese momento.

El avance en la depuración fue una captura tcpdump -ni any que mostró SYNs llegando por eth0 pero SYN-ACKs saliendo por eth1 con la IP de origen equivocada. Una vez que el equipo añadió reglas de enrutamiento por origen y puso rp_filter en loose en las interfaces relevantes, la ruta WAN se estabilizó.

La suposición errónea no fue «Linux está roto». Fue creer que el enrutamiento simétrico es el comportamiento por defecto en un mundo multi-homed. No lo es. Nunca lo fue.

Microhistoria 2: La optimización que salió mal

Otra organización quiso reducir latencia. Movieron NAT y firewall desde un appliance dedicado a una VM Ubuntu «cerca de la carga». Parecía genial en tests sintéticos. La VM tenía CPU de sobra y los números de iperf eran fantásticos dentro del DC.

Entonces llegó el tráfico real: muchas conexiones HTTPS de corta duración desde Internet, además de algo de UDP de monitoreo desde redes de socios. La tabla conntrack se llenó durante picos. Cuando alcanzó el techo, las conexiones nuevas se descartaron. El equipo de la app abrió un bug: «WAN inestable, LAN bien». El ticket venía con capturas de pantalla y desilusión.

La LAN estaba bien porque las peticiones internas no atravesaban ese camino NAT o generaban menos estados. WAN era un carnaval de conntrack. Habían «optimizado» colapsando roles sin dimensionar tablas de estado, timeouts y parámetros del kernel para comportamiento de Internet.

La solución no fue heroica. Midieron uso de conntrack, aumentaron nf_conntrack_max, redujeron timeouts UDP específicos donde procedía y añadieron monitorización para saturación de conntrack. Lo más importante: dejaron de tratar el NAT como un plumbing sin estado. NAT es estado, y el estado necesita planificación de capacidad.

Broma #2: Nada dice «alta disponibilidad» como una sola tabla conntrack que entra en pánico cuando marketing lanza una campaña.

Microhistoria 3: La práctica aburrida que salvó el día

Una financiera tenía una regla simple: cada cambio expuesto a Internet incluía una captura de paquetes antes y después, almacenada con el registro del cambio. No era novedoso. Suficiente para mostrar comportamiento de ingreso y egreso.

Un viernes salió una pequeña actualización de firewall. Inmediatamente, usuarios remotos reportaron que podían llegar a la página de login pero las descargas de archivos se colgaban. Dentro de la oficina, todo funcionaba. La primera intuición fue culpar la aplicación o el backend de almacenamiento porque «las descargas son grandes».

El ingeniero on-call sacó la captura «antes» de la semana pasada y tomó una captura fresca «después». La captura nueva mostró sesiones TCP estancándose tras cierto tamaño de paquete. Entonces vieron el cambio real: ICMP tipo 3 código 4 había sido bloqueado «por seguridad». PMTUD se rompió y no se estaba aplicando MSS clamping. Dolor clásico solo en WAN.

Revirtieron el bloqueo de ICMP, añadieron un allow explícito para los mensajes ICMP necesarios y documentaron cuándo usar MSS clamping en enlaces VPN. El incidente duró minutos, no horas, porque tenían evidencia base y la disciplina de comparar. Aburrido, correcto y repetible. El mejor tipo de ops.

Cita sobre fiabilidad (idea parafraseada): «No puedes mejorar lo que no mides.» — W. Edwards Deming (idea parafraseada)

Errores comunes: síntoma → causa raíz → solución

1) «Funciona desde LAN, hace timeout desde WAN»

Síntoma: No hay conexión en absoluto desde Internet; clientes LAN tienen éxito.

Causa raíz: El tráfico entrante nunca llega al host (IP pública equivocada, falta forward de puerto, security group en la nube bloquea, ISP bloquea).

Solución: Captura en la interfaz WAN. Si no llega nada, arregla NAT/firewall upstream. No toques la app.

2) «Llega SYN, no sale SYN-ACK»

Síntoma: tcpdump muestra SYN entrante, pero no hay respuesta.

Causa raíz: Drop por firewall local, servicio no escuchando en esa IP/puerto, rp_filter descartando o ruta local al cliente rota.

Solución: Comprueba ss -lntup, luego reglas de firewall (nft), después rp_filter y finalmente el enrutamiento.

3) «SYN-ACK sale pero el cliente nunca completa el handshake»

Síntoma: El servidor responde, pero el cliente sigue retransmitiendo SYN.

Causa raíz: Ruta de retorno rota más allá del servidor, IP de origen de la respuesta equivocada (enrutamiento asimétrico) o descartes upstream.

Solución: Captura en any para ver qué interfaz usa la respuesta. Arregla policy routing o NAT en el gateway. Verifica reglas upstream.

4) «Usuarios VPN fallan, usuarios de Internet bien»

Síntoma: Clientes remotos por VPN no alcanzan el servicio usando el nombre público; otros sí.

Causa raíz: Desajuste de DNS por split DNS o hairpin NAT no soportado en la salida de la VPN.

Solución: Arregla la vista DNS para la VPN, o proporciona un nombre/VIP interno para usuarios VPN, o implementa hairpin NAT correctamente.

5) «Peticiones pequeñas funcionan, descargas grandes cuelgan»

Síntoma: La página de login carga, pero las transferencias de archivos se estancan en WAN.

Causa raíz: Fallo MTU/PMTUD por ICMP bloqueado o overhead de túnel; falta MSS clamping.

Solución: Permite ICMP fragmentation-needed, ajusta la MTU o clampa MSS en el borde para TCP donde haga falta.

6) «Todo se rompe en pico, luego se recupera»

Síntoma: Fallos WAN aleatorios correlacionados con carga.

Causa raíz: Exhaustión de la tabla conntrack, agotamiento de puertos de NAT o saturación de firewall stateful.

Solución: Mide contador conntrack vs max, ajusta límites/timeouts, escala NAT o reduce creación de estados innecesarios.

7) «IPv4 WAN falla pero IPv6 funciona» (o viceversa)

Síntoma: Una familia de IP funciona; la otra está muerta.

Causa raíz: Desajuste en el binding de la app, reglas de firewall distintas, falta de registro AAAA/A o ruta equivocada para una familia.

Solución: Comprueba ss para sockets v4/v6, verifica reglas de firewall por familia y valida registros DNS por familia.

8) «LAN funciona por IP, falla por hostname»

Síntoma: curl https://10.10.0.10 funciona pero curl https://app.example.internal falla.

Causa raíz: DNS apunta a una dirección distinta en WAN, o el certificado/SNI en el reverse proxy enruta diferente.

Solución: Compara DNS desde dentro y fuera, revisa vhost del reverse proxy y configuración SNI, confirma la IP de destino correcta.

Listas de verificación / plan paso a paso

Checklist A: Host único con IP pública directa (sin DNAT)

  1. Confirma socket de escucha: ss -lntup. Si está ligado a localhost/privado, arregla la configuración del servicio.
  2. Confirma firewall local: nft list ruleset. Si la policy es drop, permite explícitamente el puerto.
  3. Confirma que llegan paquetes: tcpdump -ni eth0 mientras pruebas desde WAN.
  4. Si llegan paquetes pero no hay respuesta: revisa rp_filter y rutas al subnet del cliente.
  5. Si la respuesta sale pero el cliente no la ve: involucra firewall/ISP upstream, verifica la ruta de retorno y cualquier política de scrubbing DDoS.
  6. Para «cargas grandes que cuelgan»: prueba MTU/PMTUD y la permisividad de ICMP.

Checklist B: Gateway NAT que hace port forwarding (DNAT a servidor privado)

  1. En el gateway, confirma que existe la regla DNAT y que coincide con interfaz/puerto.
  2. En el gateway, confirma que la cadena forward permite el tráfico (allow stateful es típico).
  3. En el gateway, confirma SNAT/MASQUERADE para las respuestas salientes por la interfaz WAN.
  4. En el servidor interno, confirma que ve la conexión entrante (tcpdump en la interfaz privada).
  5. En el servidor interno, confirma que su ruta por defecto apunta de vuelta al gateway (si no, las respuestas evitarán el NAT y morirán).
  6. Observa conntrack en el gateway durante pruebas; NAT necesita estado.

Checklist C: Host multi-homed (dos interfaces, dos rutas)

  1. Captura en any y verifica interfaz de ingreso y egreso para el mismo flujo.
  2. Revisa ip rule y todas las tablas de enrutamiento usadas.
  3. Pon rp_filter en loose (2) donde se espere enrutamiento asimétrico.
  4. Fija direcciones de origen usando src en rutas o policy routing por subred de origen.
  5. Vuelve a probar y verifica que la respuesta salga por el uplink correcto de forma consistente.

Checklist D: Sanidad DNS y hairpin (común en oficinas y VPNs)

  1. Compara respuestas DNS desde dentro y fuera usando dig con resolvers específicos.
  2. Si clientes internos resuelven la IP pública, prueba si el borde soporta hairpin NAT.
  3. Si no hay soporte de hairpin, deja de forzar: da a clientes internos/VPN un nombre interno o DNS condicional.
  4. Verifica que certificados y enrutamiento SNI coincidan con el hostname que usan los usuarios.

Preguntas frecuentes

1) Si funciona en LAN, ¿no demuestra eso que la app está bien?

Demuestra que la app puede responder por alguna ruta. WAN añade enrutamiento, NAT y políticas de firewall distintas. Considera el éxito en LAN como «la app no está totalmente muerta», no más que eso.

2) ¿Cuál es la prueba más rápida para evitar adivinar?

tcpdump en la interfaz WAN durante un intento de conexión desde WAN. Si no llega nada, deja de culpar al servidor.

3) ¿Por qué rp_filter rompe WAN pero no LAN?

El tráfico LAN suele usar una ruta simétrica y directa. El tráfico WAN en hosts multi-homed o redes con policy routing puede parecer «spoofeado» para rp_filter estricto, por lo que el kernel lo descarta temprano.

4) Abrí el puerto en UFW pero sigue fallando. ¿Por qué?

O bien UFW no es la capa de firewall activa que crees, o el tráfico no llega al host, o lo estás DNATeando a otro equipo que aún lo bloquea. Valida siempre las reglas activas reales con nft list ruleset y captura el tráfico.

5) ¿Cómo sé si tengo enrutamiento asimétrico?

Captura en any y observa un único flujo. Si el SYN entra por una interfaz y el SYN-ACK sale por otra, tienes asimetría. Luego revisa ip rule y las rutas por tabla.

6) ¿Por qué fallan descargas grandes pero la página de login funciona?

Ese es el patrón de fallo MTU/PMTUD. Los paquetes pequeños pasan; los más grandes requieren fragmentación o señalización PMTUD correcta. Si ICMP «fragmentation needed» está bloqueado, TCP se queda colgado.

7) ¿La saturación de conntrack realmente puede parecer «solo WAN»?

Sí. Muchos caminos LAN no atraviesan dispositivos con mucho NAT/conntrack, o crean menos estados. El tráfico expuesto a Internet es burbujeante y stateful, y encuentra los límites de tu tabla.

8) DNATeo a un host interno. ¿Por qué necesita la ruta por defecto correcta?

Porque las respuestas deben volver por el gateway NAT para ser traducidas correctamente. Si el host interno envía respuestas por otro gateway, el cliente verá IPs privadas o estados inconsistentes y la sesión morirá.

9) ¿Es IPv6 relevante para «LAN funciona, WAN falla»?

Absolutamente. Muchos entornos exponen IPv6 internamente pero no externamente (o al revés). Revisa bind addresses, registros AAAA/A y reglas de firewall por familia.

10) ¿Debería habilitar MASQUERADE en todas partes?

No. Así creas deuda de depuración y rutas sorpresa. SNAT/MASQUERADE debe ser preciso: interfaz de salida correcta, subredes de origen correctas y solo donde realmente necesites traducción.

Conclusión: siguientes pasos que deberías hacer

Si solo adoptas un hábito de esto: captura primero. «Funciona en LAN, falla en WAN» es una historia de enrutamiento/NAT/filtrado hasta que se pruebe lo contrario. Tu trabajo es probar dónde desaparece el paquete.

  1. Ejecuta tcpdump en la interfaz WAN durante un intento fallido. Decide: upstream vs local.
  2. Si es local, revisa en orden: sockets de escucha → reglas de firewall → rp_filter → enrutamiento/policy routing.
  3. Si es DNAT, verifica ambas direcciones: DNAT entrada, SNAT/MASQUERADE salida y ruta por defecto correcta en el host interno.
  4. Si es intermitente bajo carga, mide conntrack y límites de tablas de estado y deja de tratar el NAT como gratis.
  5. Si son «cargas grandes que cuelgan», arregla MTU/PMTUD y no bloquees ICMP al tuntún.

Haz eso, y «funciona en LAN, falla en WAN» dejará de ser un misterio y será más bien una lista de verificación con recibos.

← Anterior
Excel gobierna el mundo: historias aterradoras que siguen ocurriendo
Siguiente →
Docker: Escrituras lentas en overlay2 — cuándo cambiar a volúmenes y por qué

Deja un comentario