it-swarm-es.com

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

¿Qué parámetro del núcleo u otras configuraciones controlan el número máximo de TCP sockets 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
91
Ben Williams

Finalmente encontré la configuración que realmente limitaba el número de conexiones: net.ipv4.netfilter.ip_conntrack_max. Esto se configuró en 11,776 y lo que sea que establezca es la cantidad de solicitudes que puedo atender en mi prueba antes de tener que esperar tcp_fin_timeout segundos para que haya más conexiones disponibles. La tabla conntrack 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_WAIT estado en lugar de descartar paquetes. Podría lograr que eso suceda activando tcp_tw_recycle o aumentando ip_conntrack_max será mayor que la cantidad de puertos locales disponibles para conexiones por 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 activar tcp_tw_recycle ya 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

Los tcp_max_orphans la configuración no tuvo ningún efecto en mis pruebas y no sé por qué. Creo que cerraría las conexiones en TIME_WAIT declara una vez que hubo 8192 de ellos, pero no lo hace por mí.

66
Ben Williams

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:

  • / proc/sys/net/ipv4/tcp_max_orphans , que controla el número máximo de sockets en poder del sistema ¡no conectado a algo. Elevar esto puede consumir hasta 64kbytes de memoria no intercambiable por socket Orphan.
  • / proc/sys/net/ipv4/tcp_Orphan_retries , que controla la cantidad de reintentos antes de que un socket quede huérfano y cerrado. Hay una nota específica en esa página sobre servidores web que le interesa directamente ...
24
Avery Payne

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 esto y la siguiente sección en ese enlace podría ser lo que estás buscando.

3
Kyle Brandt

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
2
Jauder Ho

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.

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

2
rasjani

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.

1
Devdas

La herramienta de evaluación comparativa del servidor Apache HTTP, ab , en la versión 2.4 tiene la opción - s timeout . Consulte también error ab (Apache Bench): apr_poll: El tiempo de espera especificado ha expirado (70007) en Windows.

Esta opción resuelve tu problema.

0
Dzwiedziu-nkg

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.

0
Jason Tan