¿Qué limita el número máximo de conexiones en un servidor Linux?

90

¿Qué parámetro del kernel u otras configuraciones controlan la cantidad máxima de sockets TCP que se pueden abrir en un servidor Linux? ¿Cuáles son las desventajas de permitir más conexiones?

Mientras cargaba probando un servidor Apache con ab, noté que es bastante fácil maximizar las conexiones abiertas en el servidor. Si deja de lado la opción ab's -k, que permite la reutilización de la conexión, y hace que envíe más de aproximadamente 10,000 solicitudes, Apache atiende las primeras 11,000 solicitudes y luego se detiene durante 60 segundos. Una mirada a la salida de netstat muestra 11,000 conexiones en el estado TIME_WAIT. Aparentemente, esto es normal. Las conexiones se mantienen abiertas por defecto de 60 segundos incluso después de que el cliente haya terminado con ellas por razones de confiabilidad de TCP .

Parece que esta sería una manera fácil de hacer un servidor DoS y me pregunto cuáles son las afinaciones y precauciones habituales para ello.

Aquí está mi salida de prueba:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Aquí está el comando netstat que ejecuto durante la prueba:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab
Ben Williams
fuente

Respuestas:

64

Finalmente encontré el ajuste que fue realmente limitar el número de conexiones: net.ipv4.netfilter.ip_conntrack_max. Esto se configuró en 11,776 y lo que sea que lo configuré es la cantidad de solicitudes que puedo atender en mi prueba antes de tener que esperar tcp_fin_timeoutsegundos para que haya más conexiones disponibles. La conntracktabla es lo que usa el núcleo para rastrear el estado de las conexiones, por lo que una vez que está lleno, el núcleo comienza a soltar paquetes e imprimir esto en el registro:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

El siguiente paso fue conseguir que el núcleo reciclara todas esas conexiones en el TIME_WAITestado en lugar de descartar paquetes. Podría lograr que eso suceda activando tcp_tw_recycleo aumentando ip_conntrack_maxpara que sea mayor que el número de puertos locales disponibles para las conexiones ip_local_port_range. Supongo que una vez que el núcleo está fuera de los puertos locales, comienza a reciclar las conexiones. Esto usa más conexiones de seguimiento de memoria, pero parece ser la mejor solución que encender, tcp_tw_recycleya que los documentos implican que eso es peligroso.

Con esta configuración puedo ejecutar ab todo el día y nunca quedarme sin conexiones:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

La tcp_max_orphansconfiguración no tuvo ningún efecto en mis pruebas y no sé por qué. Creo que cerraría las conexiones en TIME_WAITestado una vez que hubiera 8192 de ellas, pero no lo hace por mí.

Ben Williams
fuente
3
¿Dónde configuramos estos parámetros?
Codevalley
2
@Codevalley Eso puede depender del sistema, pero en Ubuntu Server van a /etc/sysctl.conf
Ben Williams
24

Realmente desea ver lo que el sistema de archivos / proc tiene para ofrecerle a este respecto.

En esa última página, es posible que le interese lo siguiente:

Avery Payne
fuente
tcp_max_orphans es interesante pero parece que no está funcionando. Cuando trato de medir enchufes huérfanos durante mi prueba, veo 11,651 de ellos, mientras que tcp_max_orphans es 8,092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | corte -d '' -f 1-4,6-7 | ordenar | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams
Mira las tcp_orphan_retries de ajuste - el ser idea, los enchufes son "sacrificados" más rápido ...
Avery Payne
La sugerencia de @Jauder Ho + tcp_orphan_retries suena como una posible victoria para su situación.
Avery Payne
3

No creo que haya un sintonizable para configurarlo directamente. Esto cae dentro de la categoría de ajuste TCP / IP. Para descubrir lo que puede sintonizar, pruebe 'man 7 tcp'. El sysctl ('man 8 sysctl') se usa para configurarlos. 'sysctl -a | grep tcp 'le mostrará la mayor parte de lo que puede sintonizar, pero no estoy seguro si los mostrará a todos. Además, a menos que esto haya cambiado, los sockets TCP / IP se abren como descriptores de archivos. Entonces, esta y la siguiente sección en ese enlace podrían ser lo que está buscando.

Kyle Brandt
fuente
2

Intente configurar lo siguiente también estableciendo tcp_fin_timeout. Esto debería cerrar TIME_WAIT más rápido.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
Jauder Ho
fuente
¡Cuidado aquí! Experimentado de la manera difícil. "Esto puede causar la caída de tramas con equilibrio de carga y NAT, solo use esto para un servidor que se comunica solo a través de su red local". - wiki.archlinux.org/index.php/Sysctl
Henk
@ Henk, supongo tcp_tw_recycleque es potencialmente peligroso. tcp_tw_reusees más seguro y no veo ninguna razón para usarlos simultáneamente.
Vladislav Rastrusny
2

El stock apache (1) solía venir predefinido para admitir solo 250 conexiones simultáneas; si quería más, había un archivo de encabezado para modificar para permitir más sesiones simultáneas. No sé si esto sigue siendo cierto con Apache 2.

Además, debe agregar una opción para permitir un montón de descriptores de archivos más abiertos para la cuenta que ejecuta Apache, algo que los comentarios anteriores no señalan.

Presta atención a la configuración de tus trabajadores y a qué tipo de tiempos de espera de mantenimiento tienes dentro de Apache, cuántos servidores de repuesto tienes ejecutando a la vez y qué tan rápido se están eliminando estos procesos adicionales.

rasjani
fuente
1

Puede reducir el tiempo que pasa en el estado TIME_WAIT (Establecer net.ipv4.tcp_fin_timeout). Puede reemplazar Apache con YAWS o nginx o algo similar.

Las compensaciones de más conexiones generalmente implican el uso de memoria, y si tiene un proceso de bifurcación, muchos procesos secundarios que inundan su CPU.

Devdas
fuente
1
tcp_fin_timeout no es para configurar la caducidad de TIME-WAIT, que no se puede cambiar fuera de la reconstrucción del núcleo, sino para FIN, como su nombre indica.
Alexandr Kurilin
0

El número absoluto de sockets que se pueden abrir en una sola dirección IP es 2 ^ 16 y está definido por TCP / UDP, no por el núcleo.

Jason Tan
fuente
66
No, no lo es. Puede abrir más, ya que el puerto local no necesita ser único siempre que las direcciones remotas sean diferentes. Además, el OP dijo por servidor, y puede tener> 1 dirección por servidor.
MarkR