DDoS-атаки: от теории к корпоративной практике защиты

от автора

Привет! Меня зовут Максим Рыбалко, я директор по управлению проектами в Т1 Иннотех. В современном цифровом мире DDoS-атаки превратились из теоретической угрозы в ежедневный вызов для бизнеса. В этой статье я не только расскажу о базовых принципах защиты, но и поделюсь реальными случаями из практики, распространёнными ошибками и техническими решениями, которые мы применяем.

Что такое DDoS-атака?

DDoS-атака — это кибератака, целью которой является перегрузка сервера, сети или веб-сайта огромным количеством запросов, что делает их недоступными для легитимных пользователей. Атака осуществляется с помощью множества устройств, объединённых в сеть (ботнет), которые одновременно отправляют запросы к целевой системе.

Основные характеристики DDoS-атак:

  • Распределённость: атака исходит из множества источников, что затрудняет её блокирование .

  • Массовость: количество запросов может достигать миллионов в секунду.

  • Цель: вывести систему из строя, сделав её недоступной.

Почему это опасно:

  • Финансовые потери: каждая минута простоя может стоить компаниям до $5600 (по данным Gartner).

  • Репутационные риски: клиенты теряют доверие после повторных инцидентов.

  • Маскировка других атак: часто DDoS используют как «дымовую завесу» для хищения данных.

Типы атак и реальные примеры

1. Объёмные атаки

  • Пример из практики: атака на 350 Гбит/с. через UDP-флуд.

  • Решение: фильтрация трафика на уровне провайдера + Anycast DNS.

2. Атаки на протоколы

  • Пример из практики: SYN-флуд, который «положил» API-шлюз из-за неверных настроек таймаутов.

  • Решение: Настройка tcp_syncookies в Linux и ограничение полуоткрытых соединений.

3. Атаки на приложения

  • Пример из практики: Slowloris-атака, которая обошла WAF из-за слишком «мягких» лимитов на длину заголовков.

Практика защиты от DDoS

1. Многоуровневая защита

  • Edge-фильтрация: отсекает 95 % мусорного трафика.

  • Кастомные правила WAF: например, блокировка запросов с поддельными User-Agent.

2. Ошибки, которые мы совершили (и исправили)

  • Ошибка 1: Геоблокировка всего трафика из Азии → легитимные клиенты не смогли работать.

    • Решение: Градуальная проверка через CAPTCHA + анализ сессий.

  • Ошибка 2: Отсутствие плана эскалации при атаке → 47 минут простоя.

    • Фикс: Чёткий runbook с ролями SOC, DevOps и менеджмента.

3. Мониторинг и аналитика

  • Неочевидные метрики:

    • Рост запросов к /wp-login.php (может указывать на брутфорс перед DDoS).

    • Аномальное соотношение GET/POST (1:100 — признак флуда).

  • Инструменты:

    • ELK-стек для анализа логов.

    • Кастомные дашборды в Grafana с порогами срабатывания.

Пример кода для базовой защиты от DDoS-атак

Один из способов защиты на уровне приложения — это ограничение количества запросов от одного IP-адреса за определённый промежуток времени. Это помогает снизить риск HTTP-флуда. Вот примеры кода на Python и Java.

Пример на Python с использованием Flask и Redis:

from flask import Flask, request, jsonify import redis import time  app = Flask(__name__) # Подключение к Redis для хранения счетчиков запросов redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)  # Лимит запросов и временное окно RATE_LIMIT = 100  # Максимальное количество запросов TIME_WINDOW = 60  # Временное окно в секундах (например, 60 секунд)  @app.before_request def rate_limit():     # Получаем IP-адрес клиента     client_ip = request.remote_addr      # Создаем ключ для хранения счетчика запросов     key = f"rate_limit:{client_ip}"      # Получаем текущее количество запросов     current_requests = redis_client.get(key)      if current_requests and int(current_requests) >= RATE_LIMIT:         # Если лимит превышен, возвращаем ошибку         return jsonify({"error": "Too many requests. Please try again later."}), 429      if not current_requests:         # Если ключа нет, создаем его и устанавливаем время жизни         redis_client.set(key, 1, ex=TIME_WINDOW)     else:         # Увеличиваем счетчик запросов         redis_client.incr(key)  @app.route('/') def index():     return "Welcome to the protected service!"  if __name__ == '__main__':     app.run(debug=True)

Пример на Java с использованием Spring Boot и Redis:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.beans.factory.annotation.Autowired;  import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit;  @SpringBootApplication @RestController public class DDoSProtectionApplication {      @Autowired     private StringRedisTemplate redisTemplate;      private static final int RATE_LIMIT = 100; // Максимальное количество запросов     private static final int TIME_WINDOW = 60; // Временное окно в секундах      public static void main(String[] args) {         SpringApplication.run(DDoSProtectionApplication.class, args);     }      @GetMapping("/")     public ResponseEntity<String> index(HttpServletRequest request) {         String clientIp = request.getRemoteAddr();         String key = "rate_limit:" + clientIp;          ValueOperations<String, String> ops = redisTemplate.opsForValue();         String currentRequests = ops.get(key);          if (currentRequests != null && Integer.parseInt(currentRequests) >= RATE_LIMIT) {             return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("Too many requests. Please try again later.");         }          if (currentRequests == null) {             ops.set(key, "1", TIME_WINDOW, TimeUnit.SECONDS);         } else {             ops.increment(key);         }          return ResponseEntity.ok("Welcome to the protected service!");     } }

Как это работает:

  • Redis используется для хранения счётчиков запросов от каждого IP-адреса.

  • RATE_LIMIT определяет максимальное количество запросов, которые можно сделать за TIME_WINDOW (временное окно).

  • Если количество запросов от одного IP-адреса превышает лимит, сервер возвращает ошибку 429 Too Many Requests.

 Преимущества:

  • Простота реализации.

  • Эффективность против простых атак, таких как HTTP-флуд.

  • Возможность масштабирования с использованием Redis.

Ограничения:

  • Этот метод не защитит от сложных DDoS-атак, таких как SYN-флуд или UDP-флуд.

  • Для полной защиты рекомендуется использовать специализированные решения, такие как Cloudflare или AWS Shield.

Пример на Go для высоконагруженных API:

1. Кастомный rate-limiter 

package main  import ( "context" "net/http" "time" "github.com/redis/go-redis/v9" )  var rdb = redis.NewClient(&redis.Options{Addr: "localhost:6379"}) var ctx = context.Background()  func rateLimit(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ip := r.RemoteAddr key := "rate_limit:" + ip  current, err := rdb.Incr(ctx, key).Result() if err != nil { http.Error(w, "Internal error", http.StatusInternalServerError) return }  if current == 1 { rdb.Expire(ctx, key, 1*time.Minute) // TTL = 1 мин }  if current > 100 { // Лимит: 100 RPM http.Error(w, "Too many requests", http.StatusTooManyRequests) return }  next(w, r) } }

Почему Go? Он обрабатывает в три раза больше запросов в секунду, чем Python.

2. Фильтрация ботов через Nginx + Lua

http {     lua_shared_dict ip_blacklist 10m;     server {         location / {             access_by_lua_block {                 local ip = ngx.var.remote_addr                 local blacklist = ngx.shared.ip_blacklist                 if blacklist:get(ip) then                     ngx.exit(ngx.HTTP_FORBIDDEN)                 end             }         }     } }

Дополнительные меры:

  • Использование CAPTCHA для подозрительных запросов, чтобы отсечь ботов.

  • Геофильтрация: блокируйте трафик из регионов, где он не ожидается.

  • Анализ поведения: внедрите системы машинного обучения для анализа трафика и выявления аномалий.

Что почитать для углублённого изучения


DDoS-атаки — это не страшилка, а реальность. Защита от них требует:

  1. Многоуровневой фильтрации (от edge до приложения).

  2. Постоянного тестирования (например, через Red Team).

  3. Чётких процессов (кто и когда нажимает «красную кнопку»).

«Лучшая защита — это когда атака даже не заметна для бизнеса» (из нашего внутреннего мануала).


ссылка на оригинал статьи https://habr.com/ru/articles/902796/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *