Ip_conntrack: table full, dropping packet

El síntoma relativo a este error de kernel o sistema se puede ver perfectamente cuando, nuestro linux es incapaz de devolver todos los paquetes TCP/IP. Si tenemos un servidor web apache, vemos lentitud en la carga de la web o incluso devuelve TimeOut. Si hacemos un ping, veremos que algunos paquetes no reciben respuesta con el típico mensaje.

“Tiempo de espera agotado para esta solicitud”

Hablando en un contexto de distribución RedHat(Fedora, CentoS) podemos intentar mejorar o incluso reparar esta incidencia modificando los valores del archivo de configuración sysctl.conf

Primero, hemos de localizar el error en cuestión. Para ello, utilizamos el comando dmesg, que muestra los últimos mensajes que genera el kernel de linux.

#dmesg | grep conntrack

También podemos encontrar este error almacenado en los ficheros log del sistema, /var/log/

#grep conntrack messages

Output ejemplo:
Aug 30 13:25:46 mailsswl kernel: ip_conntrack: table full, dropping packet.
Aug 30 13:25:50 mailsswl kernel: NET: 66 messages suppressed.
Aug 30 13:25:51 mailsswl kernel: ip_conntrack: table full, dropping packet.
Aug 30 13:25:55 mailsswl kernel: NET: 39 messages suppressed.
Aug 30 13:25:56 mailsswl kernel: ip_conntrack: table full, dropping packet.
Aug 30 13:26:01 mailsswl kernel: NET: 36 message

Nuestro host comienza a descartar paquetes con lo cual muchas solicitudes son descartadas y esto, en un entorno de servidor web significa un servicio degradado. Podemos ver el número actual de conexiones activas con:

#cat /proc/net/ip_conntrack | wc -l

Ouput ejemplo:
36007

Y compararlo con el límite que tenemos configurado:

#sysctl -a | grep conntrack_max

Output ejemplo:
net.ipv4.netfilter.ip_conntrack_max = 65536

En un caso concreto, comenzamos a experimentar problemas cuando ip_conntrack_count(que es el número de conexiones actuales) era muy próximo al ip_conntrack_max por defecto(65536). Si mal no recuerdo cuando quedaban apenas unos dos o mil “conexiones libres” todavía, el servicio empezó a degradarse.

Por lo que he leído a través del amigo Google, se pueden efectuar algunas modificaciones en el sysctl.conf para afinar un poco el rendimiento del sistema. Ahora, vamos a revisar como está configurada nuestra máquina y los valores que tienen relación con este problema.

#sysctl -a | grep conntrack

El output sería algo así:
net.ipv4.netfilter.ip_conntrack_tcp_max_retrans = 3
net.ipv4.netfilter.ip_conntrack_tcp_be_liberal = 0
net.ipv4.netfilter.ip_conntrack_tcp_loose = 3
net.ipv4.netfilter.ip_conntrack_tcp_timeout_max_retrans = 300
net.ipv4.netfilter.ip_conntrack_log_invalid = 0
net.ipv4.netfilter.ip_conntrack_generic_timeout = 600
net.ipv4.netfilter.ip_conntrack_icmp_timeout = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close = 10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 240
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 432000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 120
net.ipv4.netfilter.ip_conntrack_checksum = 1
net.ipv4.netfilter.ip_conntrack_buckets = 8192
net.ipv4.netfilter.ip_conntrack_count = 36752
net.ipv4.netfilter.ip_conntrack_max = 65536

Modificamos tres de estos valores: ip_conntrack_max, ip_conntrack_timeout_established y ip_conntrack_timeout_close_wait. El primero hace referencia como hemos dicho antes, al número total máximo de conexiones permitidas. Este número esta directamente ligado al total de RAM disponible en el sistema. Es algo que todavía no tengo claro, ¿qué número total de bytes utiliza el kernel para cada conexión? Algunos documentos hablan de 350 bytes pero, a través del dmesg buscando el error encontré lo siguiente:

Feb 3 16:35:58 ns kernel: ip_conntrack version 2.4 (8192 buckets, 65536 max) – 228 bytes per conntrack

Con lo cual, asumo que el número de bytes en memoria que consume una conexión tcp/ip varía según el kernel. Tomaré el valor de 228 bytes para hacer las modificaciones, mientras encuentro la confirmación definitiva a esta duda. Si hacemos un pequeño cálculo, tenemos que 65536 x 228 = 14.942.208 de bytes, que en MB son 14.25 MB. Un aumento razonable, teniendo en cuenta las posibilidades de repartir un recurso como la RAM podría ser los 20 MB, que representaría un total de 91980 conexiones. En los momentos de más trabajo, nunca ha estado la memoria por debajo de los 100-70 MB libres con lo cual, un aumento de tan sólo 6 MB parece bastante prudente.

ip_conntrack_timeout_established define el tiempo establecido para conexiones hasta devolver un timeout. El valor por defecto es 432000 segundos, lo cual parece un poco exagerado o al menos, susceptible de ser tuneado. Dejaremos el tiempo establecido en 8 horas, tiempo más que razonable(28800 segundos).

ip_conntrack_timeout_close_wait define el tiempo en segundos hasta devolver un timeout y cerrar la conexión. Un tiempo normal serían unos 60 segundos.

Para modificar estos valores, modificamos el /etc/sysctl.conf

##Limita en segundos el tiempo que permanecen activas las conexiones TCP/IP – por defecto 432000
#net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 28800

##Limita a 20 MB en memoria RAM (no swap) la cantidad de conexiones TCP/IP permitidas – por defecto 65536
#net.ipv4.netfilter.ip_conntrack_max = 91980

##Limita a 60 segundos el tiempo para cerrar la conexion y dar timeout
#net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

Y para recargar el archivo de configuración modificado:

#sysctl -p

Con esto, aumentamos algo la capacidad del sistema para recibir peticiones y a falta de ver como se comporta la máquina, asumimos que se puede traducir en una mejora incluso del rendimiento de la máquina, al reducir drásticamente los tiempos de Timeout. Ahora, faltará ver como se comporta la máquina. Como siempre invito a la gente, a comentar estas ideas y exponer las suyas 😉

Links
http://ubuntuforums.org/archive/index.php/t-436702.html
http://www.ecualug.org/?q=2006/12/27/forums/ip_conntrack_table_full_dropping_packet
http://support.imagestream.com/Resolving_ip_conntrack_table_full_Errors.html
http://kutxa.homeunix.org/howtos/ip_conntrack_max.html

4 thoughts on “Ip_conntrack: table full, dropping packet

Leave a Reply

Your email address will not be published. Required fields are marked *