Volver a la página principal
viernes 8 noviembre 2024
14

Cómo configurar Rate Limiting con Redis o Memcached en Nginx

El rate limiting, o limitación de tasa, es una técnica para controlar el número de solicitudes que un usuario o IP puede hacer a un servidor en un período de tiempo específico. En Nginx, se puede implementar rate limiting con el uso de Redis o Memcached como backend de almacenamiento, lo que permite almacenar los contadores de solicitudes en estos sistemas de caché y mejorar el rendimiento en configuraciones distribuidas.

¿Qué es el Rate Limiting en Nginx?

El rate limiting en Nginx es una configuración que restringe el acceso de usuarios mediante un límite de solicitudes en un intervalo de tiempo determinado. Al utilizar Redis o Memcached, los contadores de las solicitudes se almacenan en una base de datos en memoria, lo que es ideal para entornos distribuidos donde múltiples instancias de Nginx comparten el mismo límite de tasa para todos los usuarios.

Configuración básica de Rate Limiting en Nginx con Redis

Nginx puede trabajar con Redis para gestionar el rate limiting utilizando módulos adicionales, como el ngx_http_redis o lua-resty-redis de Lua, disponible con OpenResty.

Ejemplo de configuración con Lua y Redis

1. Instalar OpenResty (distribución de Nginx que soporta Lua).

2. Configurar el rate limiting en Lua:

http {
    lua_shared_dict limits 10m;

    server {
        location / {
            access_by_lua_block {
                local redis = require "resty.redis"
                local red = redis:new()
                red:set_timeout(1000)  -- 1 segundo de timeout
                local ok, err = red:connect("127.0.0.1", 6379)
                if not ok then
                    ngx.log(ngx.ERR, "failed to connect to Redis: ", err)
                    return ngx.exit(500)
                end

                local key = "rate_limit:" .. ngx.var.remote_addr
                local limit = 100  -- límite de 100 solicitudes
                local expires_in = 60  -- en 60 segundos

                local current, err = red:get(key)
                if current == ngx.null then
                    red:set(key, 1)
                    red:expire(key, expires_in)
                else
                    if tonumber(current) >= limit then
                        ngx.exit(429)
                    else
                        red:incr(key)
                    end
                end
            }
            proxy_pass http://backend;
        }
    }
}

En este ejemplo:

  • Se conecta a Redis en 127.0.0.1:6379.
  • Cada dirección IP tiene un límite de 100 solicitudes por cada 60 segundos.
  • Si se supera el límite, el usuario recibe el código de respuesta HTTP 429 Too Many Requests.

Configuración básica de Rate Limiting en Nginx con Memcached

Aunque Memcached no es comúnmente utilizado para rate limiting en Nginx, se puede implementar mediante el uso de Lua y OpenResty.

Ejemplo de configuración con Lua y Memcached

http {
    lua_shared_dict limits 10m;

    server {
        location / {
            access_by_lua_block {
                local memcached = require "resty.memcached"
                local memc = memcached:new()
                memc:set_timeout(1000)  -- 1 segundo de timeout
                local ok, err = memc:connect("127.0.0.1", 11211)
                if not ok then
                    ngx.log(ngx.ERR, "failed to connect to Memcached: ", err)
                    return ngx.exit(500)
                end

                local key = "rate_limit:" .. ngx.var.remote_addr
                local limit = 100  -- límite de 100 solicitudes
                local expires_in = 60  -- en 60 segundos

                local current, flags, err = memc:get(key)
                if not current then
                    memc:set(key, 1, expires_in)
                else
                    if tonumber(current) >= limit then
                        ngx.exit(429)
                    else
                        memc:incr(key, 1)
                    end
                end
            }
            proxy_pass http://backend;
        }
    }
}

En este ejemplo:

  • Se conecta a Memcached en 127.0.0.1:11211.
  • Cada IP tiene un límite de 100 solicitudes por cada 60 segundos.
  • Cuando el límite se alcanza, el servidor responde con el código 429 Too Many Requests.

Parámetros importantes en la configuración

Parámetro Descripción
key Clave única para identificar al usuario o IP (ej. rate_limit:remote_addr).
limit Número máximo de solicitudes permitidas en el intervalo de tiempo especificado.
expires_in Tiempo en segundos que define el intervalo para la limitación de tasa.
redis:connect() Función de Lua para conectarse a Redis.
memcached:connect() Función de Lua para conectarse a Memcached.

Ejemplos adicionales de Rate Limiting

1. Límite de tasa por usuario autenticado:

local user_id = ngx.var.cookie_user_id or ngx.var.arg_user_id
   local key = "rate_limit:" .. user_id

2. Aplicar un límite menos restrictivo (200 solicitudes):

local limit = 200

3. Límite de tasa con expiración de 120 segundos:

local expires_in = 120

Referencias

Para más detalles sobre la configuración avanzada de rate limiting en Nginx con Redis o Memcached, consulta la documentación de OpenResty y la documentación oficial de Nginx.

Etiquetas:
nginx
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer