Rate Limiting и DDoS-защита
Rate Limiting — ограничение числа запросов от одного источника за единицу времени; защита от DDoS (Distributed Denial of Service) включает более широкий набор мер — CDN, WAF, anycast routing — для поддержания доступности сервиса под атакой.
Зачем нужно
Без rate limiting API уязвимо к brute force паролей, перебору OTP, scrapin'у данных и исчерпанию ресурсов сервера. DDoS-атаки могут вывести сервис из строя за секунды без соответствующей защиты на уровне сети и приложения.
Где используется
- Эндпоинты аутентификации (
/login,/forgot-password,/verify-otp) - Публичные API с лимитами использования
- Формы отправки писем и SMS-кодов
- Любые resource-intensive операции (экспорт, парсинг, загрузка файлов)
Основной контент
express-rate-limit (базовый rate limiting)
const rateLimit = require('express-rate-limit');
// Общий лимит для всего приложения
const generalLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100, // 100 запросов с одного IP
standardHeaders: true, // Добавляет RateLimit-* заголовки
legacyHeaders: false,
message: { error: 'Too many requests, please try again later.' },
});
// Строгий лимит для логина
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
skipSuccessfulRequests: true, // Не считать успешные запросы
});
app.use('/api/', generalLimiter);
app.post('/api/auth/login', loginLimiter, loginHandler);
Redis-backed rate limiting (распределённый)
const { RateLimiterRedis } = require('rate-limiter-flexible');
const redis = require('ioredis');
const limiter = new RateLimiterRedis({
storeClient: redis,
keyPrefix: 'login',
points: 5, // 5 попыток
duration: 60 * 15, // за 15 минут
blockDuration: 60 * 60, // блокировать на 1 час
});
app.post('/login', async (req, res) => {
try {
await limiter.consume(req.ip);
// продолжить авторизацию
} catch (rejRes) {
const secs = Math.round(rejRes.msBeforeNext / 1000) || 1;
res.set('Retry-After', secs);
res.status(429).json({ error: 'Too many login attempts' });
}
});
Nginx rate limiting
# В http блоке
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
# В server блоке
location /api/auth/login {
limit_req zone=login burst=2 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
DDoS-защита: уровни
L3/L4 (сеть): Cloudflare, AWS Shield — фильтрация по IP, протоколу
L7 (приложение): WAF — анализ HTTP, блокировка по паттернам
CDN: Распределение трафика, поглощение объёмных атак
Anycast: Распределение по PoP — атака "размывается"
Частые ошибки
- Rate limiting только по IP — обходится через Tor/VPN/botnet
- Отсутствие
Retry-Afterзаголовка — клиенты ретраят немедленно - In-memory rate limiter на несколько серверов — каждый считает независимо
- Rate limiting на load balancer вместо application level — теряется контекст пользователя
Связанные темы
- _MOC Безопасность
- WAF -- Web Application Firewall
- Двухфакторная аутентификация (2FA)
- Логирование безопасности