Ir al contenido
EuroVPSEuroVPS

Conntrack: los health checks pasan, el tráfico se detiene

Un firewall stateful decide la ruta de una conexión una sola vez, al crearla, así que un flujo de larga vida puede conservar una decisión antigua mientras cada probe nuevo pasa.

Por EuroVPS EngineeringLa sala de máquinas

5 min de lectura
En este artículo 5 secciones
En resumen
  • Un firewall stateful toma la decisión de reenvío y NAT de una conexión en su primer paquete y la guarda en la tabla de estados durante toda la vida del flujo. Los cambios de routing y de política no se aplican a los flujos que ya existen.
  • Un stream continuo como syslog sobre TCP, la replicación de una base de datos, un forwarder de métricas o un túnel puede mantener una conexión durante semanas. Si la red cambia por debajo, ese flujo conserva la decisión antigua mientras los pings y las conexiones nuevas reciben la nueva, así que todas las comprobaciones pasan.
  • Monitorice lo que llega, no lo que está activo: contadores de bytes frente al volumen esperado, ocupación de la tabla de estados y una comprobación de extremo a extremo de que los datos llegaron. Un flujo congelado se arregla borrando su entrada en la tabla de estados, no reiniciando el firewall.

La decisión se toma una sola vez

El connection tracking existe para que un firewall evalúe la política una vez por flujo en lugar de una vez por paquete. El primer paquete se compara con las reglas, el resultado de reenvío y NAT se escribe en la tabla de estados, y cada paquete posterior de ese flujo es un hash lookup. El conntrack de netfilter, la tabla de estados de pf en OPNsense y la connection table de Cisco Firepower funcionan todos así. La entrada vive hasta que el flujo se cierra o expira su idle timeout, y para una conexión TCP establecida ese timeout se mide en días.

La consecuencia es fácil de pasar por alto: un cambio en el routing, en una regla NAT o en una interfaz afecta al siguiente flujo, no a los flujos que ya están en la tabla.

Dos formas en que esto descarta tráfico en silencio

La ruta obsoleta. Cambia una ruta, se mueve una interfaz, se edita un pool de NAT. Las conexiones nuevas toman la nueva ruta. Un stream de larga vida conserva su interfaz de salida o su binding NAT original, así que sus paquetes salen por el camino antiguo, hacia un next hop que ya no los reenvía o sin la traducción que el otro extremo espera ahora. La pila TCP del emisor retransmite con paciencia sobre una conexión que sigue considerando establecida, el receptor no ve nada, y ningún proceso en ninguno de los dos lados ha fallado.

La tabla llena. Se alcanza nf_conntrack_max, normalmente por un escáner, un cliente tras NAT con miles de flujos cortos o timeouts largos en una máquina muy cargada. El kernel escribe una línea en el log y empieza a descartar el primer paquete de las conexiones nuevas mientras los flujos existentes continúan. Un health check que reutiliza una conexión abierta sigue pasando. Los usuarios que abren conexiones nuevas reciben timeouts.

Ninguna de las dos aparece en la monitorización de procesos. El daemon está activo, el listener está enlazado, la regla existe.

Por qué pasan los health checks

Un ping, un probe de conexión TCP y el simulador de rutas de un firewall crean cada uno un flujo nuevo o evalúan la política desde cero, así que cada uno recibe la decisión actual y correcta. La lectura en verde es cierta sobre el objeto equivocado. La pregunta que hay que hacerle al firewall no es qué haría con un paquete nuevo, sino qué está haciendo con los flujos que ya mantiene.

TERMINAL
# the live flows from one source, with their state and NAT binding
conntrack -L -s <source>

# how full the table is
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

# the kernel's own report of a full table
journalctl -k | grep -i 'nf_conntrack: table full'

Un flujo anterior al último cambio de routing que muestre una salida o una traducción que ninguna regla actual produciría es la entrada que hay que mirar.

Qué monitorizar

Llegada, no vitalidad. Filas por minuto que aterrizan en la base de datos del collector, mensajes por minuto en el receptor de syslog, una posición de replicación que avanza. Una línea plana es la alarma, diga lo que diga el estado del proceso.

Contadores frente a expectativa. El contador de bytes de la regla que transporta un stream crece aproximadamente al ritmo del stream. Una regla que debería estar ocupada y está casi plana significa que los paquetes están coincidiendo con otra regla o no están llegando en absoluto.

Ocupación de la tabla de estados. Alerte sobre nf_conntrack_count como fracción de nf_conntrack_max mucho antes de que se llene, y sobre el mensaje de tabla llena del kernel, que de otro modo se queda en el log sin leer.

Comprobaciones sintéticas con la forma del tráfico real. Un probe que mantiene una conexión de larga vida y empuja un registro a través de ella a intervalos, verificado en el otro extremo, prueba lo que se rompe. Un ping nuevo prueba lo que no se rompe.

Después de cada cambio de routing o NAT, liste los flujos anteriores al cambio y decida a propósito si los vacía.

La corrección es un bisturí

Borre el estado del origen afectado. El siguiente paquete crea una entrada nueva con la decisión actual y el stream se reanuda.

TERMINAL
conntrack -D -s <source>

Un reinicio o un vaciado completo también funciona, y se lleva por delante todas las demás conexiones activas. Para una tabla llena, la corrección es subir nf_conntrack_max junto con el tamaño del hash, acortar el timeout de established donde no hagan falta días y encontrar el cliente que está creando los flujos.

Respuestas directas

¿Por qué el firewall dice allow pero no pasa tráfico?+

El simulador de rutas calcula lo que recibiría un paquete nuevo. Un flujo existente está ligado a la decisión tomada cuando se creó, y el simulador no lee la tabla de estados. Vuelque los flujos activos de ese origen y compare su salida y su traducción con lo que producirían las reglas actuales.

¿Por qué funciona el ping cuando el stream de la aplicación no?+

El ping crea flujos de vida corta que expiran en segundos, así que cada uno recibe una decisión nueva. El stream mantiene un único flujo de larga vida y conserva la decisión con la que nació.

¿Cómo encuentro una conexión atascada en la interfaz equivocada?+

conntrack -L filtrado por origen en netfilter, la vista de la tabla de estados en pf o Firepower. Busque flujos anteriores al último cambio de red cuya salida o binding NAT ninguna regla actual les daría.

¿Cómo lo arreglo sin reiniciar el firewall?+

Borre las entradas de estado de ese origen con conntrack -D. El siguiente paquete se evalúa desde cero. Todo lo demás en la tabla queda intacto.

¿Un stream se quedó en silencio mientras todas las comprobaciones están en verde?

Hable con un ingeniero que lee la tabla de estados, no el simulador.

Hable con un ingeniero

Ha llegado al final.

Ponga la lectura a trabajar

¿Qué está ejecutando?

Cuéntenos la carga de trabajo, el tráfico y los requisitos de recuperación. Empiece por el configurador de servidores o repase los detalles con un ingeniero.

Escrito por los ingenieros que construyen y operan la infraestructura que describe.
Hable con un ingeniero
XIn

5 min restantes