DoS-атака (Denial of Service, «отказ в обслуживании») — это атака на вычислительную систему с целью довести ее до отказа: исчерпать канал, память, процессор, соединения или другой ресурс так, чтобы обычные пользователи не могли получить услугу. DDoS-атака (Distributed DoS) — та же цель, но нагрузка идет одновременно с множества источников, обычно из ботнета.
Содержание
Если это вопрос теста с вариантами, верный ответ — «атака на вычислительную систему с целью довести ее до отказа». Остальные варианты неверны: навязывание рекламы — это adware, а не DoS; к операционной системе MS-DOS аббревиатура DoS отношения не имеет (совпадение букв); имитация сбоев ОС — это приемы вроде фальшивых сообщений об ошибке, а DoS вызывает реальный отказ.
Ниже — чем DoS отличается от DDoS, какие бывают атаки по уровням, как распознать атаку в логах и как ограничить нагрузку на примере nginx, проверенном прогоном.
Мини-словарь
- Ресурс — то, что атака исчерпывает: полоса канала, пакеты в секунду, таблица соединений, воркеры приложения, запросы к базе.
- Ботнет — сеть зараженных устройств (компьютеры, роутеры, камеры, IoT), которыми управляет злоумышленник.
- Амплификация (усиление) — атакующий шлет маленький запрос к открытому сервису с подмененным адресом отправителя, а большой ответ уходит жертве. Такой вариант называют также DRDoS (reflected).
- Скрабинг — очистка трафика: провайдер защиты пропускает поток через свои фильтры и отдает серверу только «чистые» запросы.
Чем DoS отличается от DDoS
| Признак | DoS | DDoS |
|---|---|---|
| Источники | Один или несколько узлов | Сотни и тысячи узлов, часто ботнет |
| Типичный объем | Ограничен каналом атакующего | Может превышать канал жертвы |
| Блокировка по IP | Часто помогает | Малоэффективна: адресов слишком много, при отражении это адреса честных серверов |
| Где фильтровать | Часто на своем сервере | Нередко только до сервера: у провайдера, в CDN, в центре очистки |
Граница не абсолютная. Одиночный DoS тоже бывает опасным, если бьет в уязвимость: например, «медленные» HTTP-запросы или тяжелый поиск по сайту кладут приложение без большого трафика. А DDoS не обязательно огромный: небольшой L7-флуд по дорогой странице иногда эффективнее гигабит мусора.
Виды атак по уровням
Удобно делить атаки по тому, какой ресурс они исчерпывают. Это упрощенная схема: реальные атаки часто комбинированные (multi-vector) и меняют вектор по ходу.
| Класс | Примеры | Что исчерпывает | Чем отбивают |
|---|---|---|---|
| Объемные (L3/L4) | UDP-флуд, ICMP-флуд | Полосу канала и pps | Фильтрация у провайдера, скрабинг, anycast-сеть |
| Амплификация | Через DNS, NTP, memcached, CLDAP | Полосу канала жертвы | Скрабинг; владельцам сервисов — не держать открытые резолверы и отключать устаревшие команды |
| Протокольные (L4) | SYN-флуд, флуд ACK/RST | Таблицу соединений, состояние файрвола | SYN cookies, лимиты на новые соединения, stateless-фильтры |
| Прикладные (L7) | HTTP-флуд, slowloris, тяжелые запросы (поиск, отчеты) | Воркеры, CPU, базу данных | Rate limit, кэш и CDN, WAF, таймауты, проверка клиента |
Несколько уточнений к старым описаниям, которые часто встречаются в сети:
- Ping-флуд — это поток ICMP echo-запросов. Он опасен объемом, а на сервере обычно гасится лимитом ICMP; «ожидание ответа» тут ни при чем.
- UDP-флуд бьет по случайным портам: сервер отвечает ICMP «порт недоступен» и тратит на это ресурсы, но главная проблема — забитый канал.
- Переполнение буфера — это уязвимость, а не вид DDoS. Эксплойт может уронить сервис (тогда это DoS через уязвимость), но лечится обновлением, а не фильтрацией трафика.
Порядок усиления у амплификации разный: у DNS — десятки раз, у memcached в известных атаках 2018 года — десятки тысяч. Поэтому отражение позволяет атакующему со скромным каналом забить гораздо более широкий канал жертвы.
Признаки атаки: как отличить от наплыва пользователей
Рост трафика сам по себе не доказывает атаку: рассылка, новость или распродажа тоже дают пик. Смотрят на сочетание признаков:
- резкий рост пакетов или запросов в секунду без рекламного повода;
- однотипные запросы: один путь, один User-Agent, одинаковый размер ответа;
- рост 5xx и таймаутов при нормальном числе реальных заказов и логинов;
- на сервере много полуоткрытых соединений (состояние
SYN-RECVвss -tan), исчерпан пул воркеров; - на L3/L4 — канал загружен, а сервер почти не нагружен: трафик режется еще по дороге.
Для L7-флуда первая проверка — лог веб-сервера. Минимальный рабочий пример на Python считает, какие адреса, пути и статусы преобладают в логе nginx формата combined:
import re
from collections import Counter
# Фрагмент access.log в формате nginx "combined" (адреса из документационных диапазонов)
LOG = """\
203.0.113.7 - - [24/Sep/2026:12:00:01 +0300] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0"
198.51.100.23 - - [24/Sep/2026:12:00:01 +0300] "GET /search?q=a HTTP/1.1" 200 4100 "-" "python-requests/2.32"
198.51.100.23 - - [24/Sep/2026:12:00:01 +0300] "GET /search?q=b HTTP/1.1" 200 4100 "-" "python-requests/2.32"
198.51.100.23 - - [24/Sep/2026:12:00:02 +0300] "GET /search?q=c HTTP/1.1" 429 169 "-" "python-requests/2.32"
192.0.2.44 - - [24/Sep/2026:12:00:02 +0300] "GET /search?q=d HTTP/1.1" 200 4100 "-" "Mozilla/5.0"
198.51.100.23 - - [24/Sep/2026:12:00:02 +0300] "GET /search?q=e HTTP/1.1" 429 169 "-" "python-requests/2.32"
203.0.113.7 - - [24/Sep/2026:12:00:03 +0300] "GET /about HTTP/1.1" 200 812 "-" "Mozilla/5.0"
not a log line
"""
LINE = re.compile(
r'^(?P<ip>\S+) \S+ \S+ \[.+?\] "(?P<method>[A-Z]+) (?P<path>\S+) [^"]*" (?P<status>\d{3}) '
)
by_ip, by_path, by_status = Counter(), Counter(), Counter()
bad = 0
for raw in LOG.splitlines():
m = LINE.match(raw)
if not m:
bad += 1
continue
by_ip[m["ip"]] += 1
by_path[m["path"].split("?", 1)[0]] += 1
by_status[m["status"]] += 1
total = sum(by_ip.values())
print(f"строк разобрано: {total}, пропущено: {bad}")
for ip, n in by_ip.most_common(3):
print(f"{ip:15} {n:3} {n / total:.0%}")
print("пути:", dict(by_path.most_common(3)))
print("статусы:", dict(sorted(by_status.items())))
Вывод на Python 3.14:
строк разобрано: 7, пропущено: 1
198.51.100.23 4 57%
203.0.113.7 2 29%
192.0.2.44 1 14%
пути: {'/search': 5, '/': 1, '/about': 1}
статусы: {'200': 5, '429': 2}
Картина читается сразу: один адрес с библиотечным User-Agent дает больше половины запросов, почти все — к /search, часть уже получает 429. Кривые строки не роняют разбор, а считаются отдельно. Граница метода: при распределенном флуде доля каждого адреса мала, и группировать нужно по пути, User-Agent, подсети или стране, а не по одному IP. Если сайт стоит за CDN или балансировщиком, в логе будет их адрес — нужен реальный IP клиента из доверенного заголовка.
Ограничение запросов в nginx: рабочий пример
Rate limit не защищает от объемной атаки (канал забьется раньше, чем пакеты дойдут до nginx), но хорошо срезает L7-флуд с небольшого числа адресов и защищает дорогие страницы. Конфиг проверен на nginx 1.31.6 (образ nginx:alpine):
limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
server {
listen 80;
client_body_timeout 10s;
client_header_timeout 10s;
location / {
limit_req zone=perip burst=10 nodelay;
limit_conn connperip 20;
limit_req_status 429;
limit_conn_status 429;
root /usr/share/nginx/html;
}
}
Что здесь происходит: на один IP разрешено 5 запросов в секунду, всплеск до 10 сверх нормы пропускается сразу (nodelay), остальное получает 429 вместо стандартного 503. Одновременно — не больше 20 соединений с адреса, но limit_conn считает только соединения, где заголовок запроса уже прочитан и запрос обрабатывается: медленные соединения slowloris, которые так и не дослали заголовок, под этот лимит не попадают. От них защищают короткие таймауты: client_header_timeout ограничивает время чтения всего заголовка (иначе 408), client_body_timeout — паузу между чтениями тела.
Проверка: 20 запросов подряд с одного адреса, пауза в секунду, еще 8 запросов.
for i in $(seq 1 20); do curl -s -o /dev/null -w "%{http_code} " http://127.0.0.1/; done; echo
sleep 1
for i in $(seq 1 8); do curl -s -o /dev/null -w "%{http_code} " http://127.0.0.1/; done; echo
200 200 200 200 200 200 200 200 200 200 200 429 429 429 429 429 429 429 429 429
200 200 200 200 200 429 429 429
Первые 11 прошли (1 по норме + 10 всплеска), дальше 429. За секунду «ведро» пополнилось на 5 запросов — ровно столько прошло во второй серии. В error.log nginx пишет limiting requests, excess: ... by zone "perip".
Частая ошибка: лимит, который не работает
Неверно — проверять лимит на ответе через return:
location / {
limit_req zone=perip burst=10 nodelay;
return 200 "ok\n";
}
Результат того же теста — 20 раз 200. Причина: return срабатывает на фазе rewrite, раньше фазы, где работает limit_req, поэтому до лимита дело не доходит. Исправление — отдавать ответ контентом (root, proxy_pass к приложению), как в рабочем конфиге выше, и всегда проверять лимит запросами, а не только nginx -t: тот проверяет синтаксис, но не поведение.
Еще две границы: за CDN или балансировщиком $binary_remote_addr будет адресом прокси, и лимит заблокирует всех сразу — нужен модуль realip с явным списком доверенных адресов. А пороги (5r/s, burst) — учебные: реальные подбирают по логам нормального трафика, иначе страдают пользователи за общим NAT офиса или мобильного оператора.
Защита по уровням
| Уровень | Что делает | Кто отвечает |
|---|---|---|
| Сеть провайдера, центр очистки | Фильтрует объемные и протокольные атаки до вашего канала | Хостинг или провайдер защиты от DDoS |
| CDN и anycast | Распределяет нагрузку по точкам присутствия, отдает кэш, прячет адрес сервера | Провайдер CDN |
| Сервер и ОС | SYN cookies, лимиты соединений, закрытые лишние порты | Администратор |
| Веб-сервер и WAF | Rate limit, таймауты, правила по путям и заголовкам | Администратор, DevOps |
| Приложение | Кэш тяжелых страниц, пагинация, лимиты на поиск и отчеты | Разработчики |
Важная деталь: если реальный IP сервера известен (старые DNS-записи, заголовки писем, поддомены), атакующий бьет напрямую в обход CDN. Поэтому к серверу пускают только адреса провайдера защиты, а адрес после подключения защиты меняют.
План на время атаки: подтвердить по метрикам, что это атака, а не наплыв; определить уровень (канал или приложение); связаться с хостингом или провайдером защиты; включить заранее подготовленные правила; сохранить логи для разбора и заявления.
Ответственность
В России организация DDoS-атаки может подпадать под статьи главы 28 УК РФ о преступлениях в сфере компьютерной информации (в том числе 272, 273, а для объектов критической информационной инфраструктуры — 274.1); квалификацию определяет суд по обстоятельствам дела. Нагрузочное тестирование допустимо только своей инфраструктуры или по письменному согласию владельца, и лучше предупредить хостинг заранее: для него ваш тест выглядит как атака.
Выводы
- DoS — атака на вычислительную систему с целью довести ее до отказа; DDoS — то же с множества источников. К MS-DOS и рекламе термин отношения не имеет.
- Атаки делят по исчерпываемому ресурсу: канал (объемные, амплификация), таблица соединений (SYN-флуд), приложение (HTTP-флуд, slowloris).
- Объемную атаку отбивают до сервера — у провайдера и в CDN; rate limit в nginx помогает против L7, но не спасает забитый канал.
- Лимит нужно проверять запросами:
returnв nginx обходитlimit_req, аnginx -tэтого не покажет. - Признак атаки — сочетание аномалий (однотипные запросы, рост 5xx без роста заказов), а не просто пик трафика.
Где применяется / связь с практикой
Освойте тему на практике
Разбор атак на доступность — часть работы администратора, DevOps-инженера и специалиста по ИБ: нужно понимать сетевые уровни, читать логи, настраивать фильтрацию и готовить план реагирования. Системно эти навыки, от модели угроз до сетевой защиты, дает курс «Информационная безопасность. Базовый уровень». Отдельные темы по сетям и безопасности можно посмотреть на открытых уроках Otus.
FAQ
Можно ли защититься от DDoS только файрволом на сервере?
От небольших атак на приложение — частично. Если забит канал до сервера, локальный файрвол уже не поможет: фильтровать нужно выше, у провайдера или в CDN.
Почему rate limit отдает 429, а не 503?
По умолчанию nginx отвечает 503, но 429 Too Many Requests точнее описывает ситуацию для клиентов и мониторинга: сервер жив, превышен лимит.
Считается ли DDoS-атакой наплыв посетителей после рекламы?
Нет, это легитимная нагрузка (иногда ее называют «хабраэффектом»). Последствия похожи, но лечат их масштабированием и кэшем, а не фильтрацией.



