HTTP/2 Rapid Reset: атака которая положила интернет в 2023 году.
10 октября 2023 года Cloudflare, Google и Amazon одновременно опубликовали совместное раскрытие: в августе того же года они зафиксировали DDoS-атаки мощностью в несколько раз выше всех предыдущих рекордов. Google пережил пик в 398 миллионов запросов в секунду. Cloudflare — 201 миллион. Amazon — 155 миллионов. Предыдущий рекорд Cloudflare составлял 71 миллион rps — февраль 2023 года. Все три атаки были организованы через одну уязвимость в протоколе HTTP/2.
CVE-2023-44487. CVSS 7.5 High. Атака получила название Rapid Reset.
ЧТО ТАКОЕ HTTP/2 И ЗАЧЕМ ЕМУ ПОТОКИ
HTTP/1.1 работал просто: один запрос — один ответ, последовательно. Чтобы загрузить страницу с десятью картинками браузер открывал до 6 параллельных соединений на домен — больше спецификация не разрешает. Остальные запросы стояли в очереди. Это медленно.
HTTP/2 решил проблему мультиплексированием: несколько запросов и ответов летят одновременно внутри одного TCP-соединения. Каждый запрос — это отдельный поток (stream). Браузер открывает поток для HTML, потом потоки для CSS, JS, картинок — всё параллельно, одно соединение.
Для отмены потока в HTTP/2 существует специальный фрейм — RST_STREAM. Если браузер передумал загружать картинку — он отправляет RST_STREAM и поток закрывается. Это нормальная часть протокола.
И именно здесь спрятана уязвимость.
МЕХАНИКА АТАКИ
Проблема в том что RST_STREAM — односторонняя операция. Клиент отправил фрейм и сразу считает поток закрытым. Сервер обязан обработать запрос прежде чем получит отмену — по спецификации HTTP/2 он не может отказаться от работы заранее.
Атакующий использует это так:
Шаг 1. Открывает HTTP/2-соединение с сервером.
Шаг 2. Отправляет запрос — открывает поток.
Шаг 3. Немедленно, не дожидаясь ответа, отправляет RST_STREAM — отменяет поток.
Шаг 4. Возвращается к шагу 2. Тысячи раз в секунду. В одном TCP-соединении.
Сервер получает лавину запросов которые нужно начать обрабатывать, потом лавину отмен, потом снова запросы. CPU и память уходят на создание и разрушение контекстов обработки. Реальным пользователям ничего не достаётся — сервер занят.
При этом стоимость атаки для атакующего минимальная: одно TCP-соединение, минимум трафика. Ботнет из 20 000 машин создавал нагрузку которую раньше требовала сеть из сотен тысяч или миллионов узлов — именно так Cloudflare описал этот разрыв в официальном блоге.
ПОЧЕМУ ЭТО НЕ ПРОСТО БАГ В NGINX
Rapid Reset — уязвимость в самом протоколе HTTP/2, а не в конкретной реализации. Атака затронула nginx, Apache, Tomcat, .NET, Go, Node.js — всё что реализует HTTP/2. Патчи пришлось выпускать всем одновременно.
Важный нюанс: разработчики nginx официально заявили что nginx с настройками по умолчанию не уязвим к Rapid Reset — дефолтное ограничение keepalive_requests уже ограничивает количество запросов на соединение и снижает эффект атаки. Патч в версии 1.25.3 добавляет дополнительное обнаружение вредоносных клиентов для случаев когда дефолты изменены. Именно поэтому формулировка в официальном CHANGES: «improved detection of misbehaving clients when using HTTP/2.»
Для nginx уязвимость закрыта в версии 1.25.3, вышедшей 24 октября 2023 года. Если у вас nginx старше этой версии с нестандартным keepalive_requests и включённым HTTP/2 — сервер потенциально уязвим.
Проверить версию:
nginx -v
Проверить включён ли HTTP/2 в конфиге. В nginx до 1.25.0 HTTP/2 включался в строке listen, в nginx 1.25.0+ — отдельной директивой. Команда ловит оба варианта:
grep -r "http2" /etc/nginx/sites-enabled/
Если нашлось listen 443 ssl http2 или http2 on — HTTP/2 активен.
КАК ЗАЩИТИТЬСЯ
Шаг 1 — обновить nginx
Самое главное. nginx 1.25.3 и новее содержат патч с улучшенным обнаружением вредоносных клиентов при HTTP/2 — именно такая формулировка в официальном CHANGES. При обнаружении паттерна rapid reset сервер закрывает соединение вместо продолжения обработки каждой отменённой транзакции:
# Debian/Ubuntu
sudo apt update && sudo apt upgrade nginx
# RHEL/CentOS/Fedora
sudo dnf update nginx
# Проверить после обновления
nginx -v
Шаг 2 — ограничить количество одновременных потоков
Директива http2_max_concurrent_streams ограничивает сколько параллельных потоков клиент может открыть в одном соединении. Дефолт — 128. Для большинства сайтов хватает 64 или даже 32:
http {
http2_max_concurrent_streams 64;
...
}
Меньше потоков — меньше работы при атаке. Chrome и Firefox поддерживают до 100 одновременных потоков на соединение, но для загрузки типичной страницы редко используют больше 20–30. Значение 64 не затронет реальных пользователей.
Шаг 3 — ограничить соединения с одного IP
Rapid Reset эффективнее всего при большом числе соединений. limit_conn ограничивает сколько одновременных соединений принимается с одного IP:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
limit_conn addr 10;
}
}
Один IP — не более 10 одновременных соединений. Ботнет продолжит работу через разные IP, но нагрузка на каждое соединение будет ограничена.
Шаг 4 — Cloudflare как первый эшелон
Cloudflare заблокировал Rapid Reset атаки автоматически в октябре 2023 — ещё до публичного раскрытия CVE. Если сайт стоит за Cloudflare с включённым проксированием, большая часть атаки не доходит до nginx вообще.
Проверить что Cloudflare в режиме прокси (оранжевое облако в DNS-записях), а не просто DNS. Без прокси Cloudflare не фильтрует трафик.
ТИПИЧНЫЕ ОШИБКИ
Думают что HTTP/2 можно просто отключить и проблема решена. Технически да — но HTTP/2 даёт реальный прирост производительности, и отключать его ради защиты от уязвимости которая уже запатчена нет смысла.
Обновляют nginx но не перезагружают. После apt upgrade nginx нужен systemctl reload nginx — без него процесс продолжает работать на старом коде.
Не проверяют что HTTP/2 вообще включён. Многие сайты работают на HTTP/1.1 и вообще не подвержены этой атаке — проверьте прежде чем менять конфиг.
ИТОГ
HTTP/2 Rapid Reset — редкий случай когда уязвимость затронула не конкретный продукт, а базовый интернет-протокол. Патч не мог выйти в одночасье — его координировали Google, Cloudflare, Amazon, Microsoft, nginx, Apache и десятки других одновременно.
Насторожиться стоит всем у кого nginx старше 1.25.3 и включён HTTP/2. Обновление закрывает уязвимость полностью. Ограничение http2_max_concurrent_streams и limit_conn — дополнительный уровень защиты который имеет смысл настроить независимо от версии.
Cloudflare за 201 миллион запросов в секунду устоял. Непропатченный nginx на VPS с двумя ядрами — нет.
