La limitación de velocidad controla la cantidad de solicitudes que los usuarios pueden enviar a su sitio. Esto generalmente se implementa para detener bots abusivos, limitar los intentos de inicio de sesión y controlar el uso de la API, lo que puede evitar que su servidor se ralentice bajo carga.
La limitación no siempre puede salvarlo de grandes picos de tráfico, por lo que si su servidor realmente necesita protección, es una buena idea configurar un CDN completo al frente, o al menos configurar el equilibrio de carga HAProxy para dividir la carga entre múltiples servidores.
Cómo habilitar la limitación de velocidad en Nginx
Primero, necesitamos definir una «zona» de limitación de velocidad. Puede configurar varias zonas y asignar diferentes bloques de ubicaciones a cada zona. Por ahora, creemos una zona básica agregando la siguiente línea a la suya server
o http
bloque de contexto:
limit_req_zone $binary_remote_addr zone=foo:10m rate=5r/s;
los limit_req_zone
comando define una zona usando $binar_remote_addr
como identificador. Esta es la dirección IP del cliente, pero también podría usar algo como esto $server_name
para limitarlo por servidor.
los zone
flag nombra la zona (en este caso, «foo») y asigna un bloque de memoria para la zona. Nginx necesita almacenar las direcciones IP para verificar, por lo que necesita memoria para cada zona. En este caso, 10m
asigna 10 megabytes de memoria, suficiente para 160.000 conexiones por segundo (que probablemente nunca verá en un solo servidor).
La bandera final es la velocidad, que define el número predeterminado de conexiones permitidas a cada cliente. Aquí está configurado en 5 solicitudes por segundo, siendo 10 el máximo, aunque puede configurarlo más lento formateándolo como 30r/m
(para 30 solicitudes por minuto).
Una vez configurada la zona, es hora de usarla.
location { limit_req zone=foo burst=10 nodelay; //do webserver stuff }
los limit_req
La directiva hace el trabajo pesado y asigna un bloque de ubicación a una zona límite. los burst
El parámetro le da al cliente cierto margen de maniobra y le permite realizar solicitudes adicionales siempre que no superen la tarifa en promedio.
Debajo del capó, agrega solicitudes de ráfagas a una «cola» que marca cada 100 ms. Esto puede hacer que su sitio parezca lento, por lo que nodelay
El parámetro elimina este retraso en la cola. Con la configuración actual, si realizó 10 solicitudes a la vez, el nodelay
El parámetro permitiría las 10 solicitudes y luego limitaría la velocidad de las siguientes solicitudes a 5 solicitudes por segundo. Si hiciera 6 solicitudes más, permitirían 5 y rechazarían la 6, ya que está por encima del límite. Una vez que el cliente deja de realizar solicitudes, la cola disminuye a un ritmo que depende de su velocidad.
Limitación de velocidad de dos etapas
Al configurar manualmente la variable de demora, puede permitir que algunas solicitudes no tengan demoras mientras que el resto tiene que esperar en la cola. Esto constituye un límite de velocidad de dos pasos, donde desea que las solicitudes iniciales sean muy rápidas, las solicitudes de seguimiento se ralenticen ligeramente y luego se activa el límite de velocidad.
Esto se hace asignando un valor de retardo en el limit_req
directiva:
limit_req zone=ip burst=10 delay=5;
Aquí, las primeras 5 solicitudes llegarán instantáneamente. Luego, al cliente se le permiten 5 solicitudes más cada 100 ms hasta que se completa la ráfaga, después de lo cual están limitadas por la variable de tasa.
Ancho de banda con limitación de velocidad
La limitación bloqueará la mayoría de los ataques maliciosos, pero es posible que desee limitar la velocidad de descarga para que los usuarios no ralenticen su servidor al descargar muchos archivos.
Puedes hacer esto con el limit_rate
directiva, que no necesita una zona de restricción configurada para ello.
limit_rate 100k limit_rate_after 1m
Esto establece la velocidad máxima de descarga en 100 Kbps después de que se haya descargado 1 megabyte. Sin embargo, esto se mide por conexión y los usuarios pueden abrir múltiples conexiones. Para solucionar esto, deberá agregar una zona de restricción de conexión junto a la zona de restricción de solicitud:
limit_conn_zone $binary_remote_address zone=bar:10m limit_req_zone $binary_remote_addr zone=foo:10m rate=5r/s;
Esto crea una zona de 10 megabytes llamada «barra» que rastrea por dirección IP. Puedes usarlo junto con aa limit_conn
directiva para habilitar la restricción de conexión.
server { limit_conn bar 5; location /static/ { limit_conn bar 1; limit_rate 100k; limit_rate_after 1m; } }
Dado que la mayoría de los navegadores abren varias conexiones durante la navegación normal, nos gustaría establecer un límite de conexión global más alto y luego establecer el límite en 1 conexión para la descarga.