¿Ataque de DOS? La gran mayoría de los trabajadores de Apache en modo 'Solicitud de lectura', el sitio inactivo anoche, lento ahora

¿Ataque de DOS? La gran mayoría de los trabajadores de Apache en modo 'Solicitud de lectura', el sitio inactivo anoche, lento ahora

Entonces creo que mi servidor podría estar sufriendo un ataque de denegación de servicio.

Pingdom (monitoreo de sitios web) nos notificó que nuestro sitio web no estaba disponible a partir de las 3 a. m. Hoy temprano comenzamos a verificar los registros de errores de Apache y vimos muchos de estos errores:

AH00485: el marcador está lleno, no en MaxRequestWorkers

También vimos que nuestro grupo de procesos PHP-FPM con frecuencia necesitaba generar más servidores:

[pool www] parece ocupado (es posible que deba aumentar pm.start_servers o pm.min/max_spare_servers), generando 8 hijos

Intentamos aumentar MaxRequestWorkers en la configuración de Apache y algunas otras soluciones, pero no nos libraron del error del marcador en el registro de errores de Apache, por lo que, en contra de mi buen juicio, seguí los consejos deeste hiloy establecerMinSpareThreadsyMaxSpareThreadsigual aMaxRequestTrabajadores. Estos cambios parecen haber eliminado el error del marcador.

También incrementé considerablemente MaxRequestWorkers porque tenemos mucha RAM que evidentemente no se está utilizando. Nuestro servidor tiene 8 núcleos y, a pesar de estos valores de configuración realmente altos, no parece estar usando gran parte de su RAM:

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.8G        1.8G        2.0G         38M        4.0G        5.8G
Swap:            0B          0B          0B

Estoy bastante nervioso por estos valores altos para MaxRequestWorkers en la configuración de Apache y pm.max_children en la configuración de php-fpm.

Aquí está la configuración básica en mpm_event.conf

<IfModule mpm_event_module>
        StartServers        2
        MinSpareThreads     800
        MaxSpareThreads     800
        ThreadLimit     64
        ThreadsPerChild     25
        ServerLimit 800
        MaxRequestWorkers       800
        MaxConnectionsPerChild   0
</IfModule>

Aquí hay algunas configuraciones en un archivo de configuración php-fpm:

pm.max_children = 256
pm.start_servers = 64
pm.min_spare_servers = 64
pm.max_spare_servers = 128

Aquí hay información básica del servidor:

Server version: Apache/2.4.18 (Ubuntu)
Server built:   2019-10-08T13:31:25
Server's Module Magic Number: 20120211:52
Server loaded:  APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture:   64-bit
Server MPM:     event
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)

Y aquí están algunos de los datos de la salida del estado del servidor Apache:

Server Version: Apache/2.4.18 (Ubuntu) OpenSSL/1.0.2g
Server MPM: event
Server Built: 2019-10-08T13:31:25

Current Time: Friday, 10-Jan-2020 22:58:55 CST
Restart Time: Friday, 10-Jan-2020 22:26:32 CST
Parent Server Config. Generation: 1
Parent Server MPM Generation: 0
Server uptime: 32 minutes 22 seconds
Server load: 4.69 5.06 5.12
Total accesses: 78434 - Total Traffic: 1.5 GB
CPU Usage: u2970.53 s5037.34 cu0 cs0 - 412% CPU load
40.4 requests/sec - 0.8 MB/second - 19.7 kB/request
797 requests currently being processed, 3 idle workers

PID Connections     Threads Async connections
total   accepting   busy    idle    writing keep-alive  closing
6124    28  yes 25  0   0   0   3
6125    27  yes 25  0   0   0   2
6182    30  yes 25  0   0   1   4
6210    28  yes 25  0   0   0   3
6211    29  yes 25  0   0   0   5
6266    28  yes 25  0   0   2   1
6267    25  yes 25  0   0   0   1
6269    28  no  24  1   0   1   3
6276    28  yes 25  0   0   0   3
6378    28  yes 25  0   0   0   3
6379    31  no  24  1   0   4   3
6380    27  yes 25  0   0   0   3
6384    26  yes 25  0   0   0   2
6397    28  yes 25  0   0   2   1
6405    27  yes 25  0   0   0   2
6414    26  yes 25  0   0   1   0
6423    27  no  24  1   0   1   1
6602    27  yes 25  0   0   0   3
6603    28  yes 25  0   0   0   4
6604    26  yes 25  0   0   0   1
6617    30  yes 25  0   0   0   5
6646    26  yes 25  0   0   0   2
6676    27  yes 25  0   0   0   2
6694    30  yes 25  0   0   0   5
6705    28  yes 25  0   0   0   3
6730    29  yes 25  0   0   0   4
6765    29  yes 25  0   0   0   4
6781    27  yes 25  0   0   0   2
6805    28  yes 25  0   0   0   4
6836    28  yes 25  0   0   0   3
6858    27  yes 25  0   0   0   3
6859    27  no  25  0   0   1   1
Sum 888     797 3   0   13  86

La parte del modo trabajador es la más desconcertante. Casi todos están en modo lectura:

RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRR_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
_RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRWRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR_RRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR

Y al final hay esto:

SSL/TLS Session Cache Status:
cache type: SHMCB, shared memory: 512000 bytes, current entries: 2176
subcaches: 32, indexes per subcache: 88
time left on oldest entries' objects: avg: 220 seconds, (range: 197...243)
index usage: 77%, cache usage: 99%
total entries stored since starting: 60122
total entries replaced since starting: 0
total entries expired since starting: 0
total (pre-expiry) entries scrolled out of the cache: 57946
total retrieves since starting: 3405 hit, 59594 miss
total removes since starting: 0 hit, 0 miss

Y netstat muestra más de 3000 conexiones al puerto 80 y al puerto 443:

$ netstat -n | egrep ":80|443" | wc -l
3715

¿Qué diablos está pasando? El servidor ha estado funcionando bien durante meses conajustes de configuración mucho más modestos.Algo parece haber cambiado abruptamente anoche alrededor de las 3 a.m.

Cualquier orientación sería muy apreciada. Primero busqué aquí y encontréeste otro hilopero es una versión diferente de Apache que se ejecuta en modo prefork en lugar de un evento como el mío. Tampoco entiendo cómo la pequeña información en ese hilo condujo a un diagnóstico de SlowLoris.

EDITAR Parece que tengo que formular mis preguntas con mayor precisión:

1) ¿Cómo puedo restaurar la capacidad de respuesta de mi servidor? Claramente, los trabajadores de Apache se quedaron atrapadosREl modo es un síntoma de algún problema.

2) ¿Existe alguna serie confiable de pasos que pueda seguir para identificar más específicamente el problema real?

3) ¿Hay alguna forma de confirmar que la máquina está bajo un ataque DoS?

Respuesta1

Simplemente contar el número de conexiones en el marcador no es evidencia suficiente para saber que los clientes están siendo groseros y no dan seguimiento a sus conexiones. Se trata de un aumento drástico, por lo que o la aplicación web se volvió muy popular o alguien está haciendo solicitudes tontas.

Mire la tasa de solicitudes finalizadas por segundo. Debería ser bastante alto con esa cantidad de trabajadores, suponiendo que su aplicación web esté funcionando adecuadamente. Verifique todos los aspectos del rendimiento del servidor web, incluido el ancho de banda disponible para los usuarios, la carga del servidor y el rendimiento de los componentes relacionados, como cualquier base de datos. Solucione cualquier problema de rendimiento debido a recursos insuficientes.

Hacer un análisis de la distribución de direcciones IP conectadas a los puertos web. Una IP que realiza cientos de conexiones es inusual, aunque las NAT IPv4 complican esto. Determine los ISP de las direcciones de origen. Verifique los puntajes de reputación de seguridad de las direcciones IP y si podría ser una NAT enorme.

Realice una captura de paquetes en las solicitudes entrantes, mientras sigue realizando su seguimiento. Debería ver al menos algunas solicitudes HTTP de clientes con buen comportamiento. Si los clientes simplemente se conectan y se sientan ahí, eso se parece un poco al agotamiento de recursos al estilo de SlowLoris.

Considere las recomendaciones de ajuste en la respuesta vinculada. En Linux, reducir un poco los tiempos de espera con sysctl net.ipv4.tcp_fin_timeout = 10es algo que se puede intentar.

Considere colocar este servidor web detrás de un proxy de equilibrio de carga y orientado a la seguridad. Las funciones del firewall de aplicaciones web podrían permitirle hacer cosas inteligentes para filtrar las solicitudes. Escalar horizontalmente podría permitirle manejar más solicitudes.

Respuesta2

¿Hay alguna forma de confirmar que la máquina está bajo un ataque DoS?

DoSes Denegación de Servicio.

AtaqueEs una acción hostil llevada a cabo para causar daño.

(Agresión pasivaes un oxímoron usado por personas que no entienden esopasivosignifica ausencia de una acción - inacción, por definición, yagresión(también por definición) significa acción hostil. Pero esa es otra historia, por supuesto).

Entre esos dos hay una brecha en la que se trata de DoS pero no es un ataque en términos de acción hostil. Digamos que si F5 se atasca en el teclado de un usuario puede causar DoS a menos que se tomen contramedidas, pero no es un ataque sino una acción hostil llevada a cabo con la intención de causar daño. OTOH, es un ataque si el usuario sabe que esto causaría DoS y mantiene presionada esa tecla intencionalmente.

Entonces, respondiendo a su pregunta, obviamente es imposible saberlo con certeza a menos que pueda demostrar que existe una intención. Es posible saber si se trata de un DoS si se produce una interrupción del servicio debido a la falta de recursos (sobrecarga).

información relacionada