В конце 2023 года глобальная сеть столкнулась с беспрецедентной по масштабу атакой, вызванной эксплуатацией уязвимости CVE-2023-44487, получившей известность как HTTP/2 Rapid Reset. Пиковая мощность атаки превысила 398 миллионов запросов в секунду, что затмило совокупный объем запросов всего мирового интернета и вызвало перебои в работе веб-серверов, прокси и облачных платформ по всему миру.

В отличие от классических атак, переполняющих каналы связи лавиной сырых пакетов UDP или ICMP, Rapid Reset использует фундаментальную архитектурную особенность протокола HTTP/2: мультиплексирование потоков и клиентскую отмену запросов. Отправляя тысячи одновременных запросов и мгновенно сбрасывая их с помощью кадров RST_STREAM, атакующие создают колоссальную вычислительную нагрузку на сервер при минимальных затратах собственной исходящей полосы.

Для пограничных прокси и плоскостей управления корпоративных VPN-шлюзов защита от мультиплексированных атак прикладного уровня требует большего, чем базовые веб-экраны WAF. Надежная устойчивость архитектуры достигается за счет строгого контроля сокетов, алгоритмов token-bucket для ограничения частоты кадров сброса и криптографической изоляции на сетевом уровне 3.

Парадигма мультиплексирования HTTP/2: параллельные потоки и переходы состояний

Чтобы устранить блокировку начала очереди (head-of-line blocking), характерную для HTTP/1.1, комитет IETF стандартизировал HTTP/2 (RFC 9113) на базе бинарных кадров и двунаправленного мультиплексирования в рамках одного постоянного TCP-соединения.

В HTTP/2 клиент и сервер взаимодействуют через независимые логические каналы, называемые потоками (streams). Жизненный цикл каждого потока описывается детерминированным конечным автоматом:

                                +--------+
                        send PP |        | recv PP
                       ,--------|  idle  |--------.
                      /         |        |         \
                     v          +--------+          v
              +----------+                      +----------+
              | reserved |                      | reserved |
              | (local)  |                      | (remote) |
              +----------+                      +----------+
                     \                              /
                      \ send H / recv H            /
                       \                          /
                        v                        v
                        +------------------------+
                        |          open          |
                        +------------------------+
                       /          |      \        \
              recv ES /           |       \        \ send ES
                     v            |        v        v
              +----------+        |     +----------+
              |  half-   |        |     |  half-   |
              |  closed  |        |     |  closed  |
              | (remote) |        |     | (local)  |
              +----------+        |     +----------+
                     \            |            /
              send ES \           | recv RST  / recv ES
                       \          v          /
                        +--------------------+
                        |       closed       |
                        +--------------------+

В штатном режиме работы:

  1. Клиент инициирует поток отправкой кадра HEADERS с нечетным идентификатором.
  2. Сервер выделяет память, запускает фоновую обработку запроса и возвращает кадры данных DATA с флагом завершения END_STREAM (ES).
  3. Поток переходит в закрытое состояние (closed).

Чтобы предотвратить неконтролируемое исчерпание системных ресурсов, спецификация RFC 9113 позволяет серверу объявлять параметр SETTINGS_MAX_CONCURRENT_STREAMS (обычно 100). Клиент обязуется не превышать это количество одновременно открытых потоков.

Механика CVE-2023-44487: асимметричный цикл отмены потоков

Архитектурный изъян в CVE-2023-44487 связан с тем, как в стандарте RFC 9113 описана процедура отмены. Если клиенту требуется прервать получение ответа, он отправляет кадр RST_STREAM с кодом ошибки CANCEL (0x8) или REFUSED_STREAM (0x7).

Получив RST_STREAM, сервер обязан немедленно перевести указанный поток в состояние closed. При этом закрытый поток мгновенно перестает учитываться в лимите одновременных потоков SETTINGS_MAX_CONCURRENT_STREAMS.

+-------------------------------------------------------------------------+
|                  HTTP/2 Rapid Reset Attack Cycle                        |
+-------------------------------------------------------------------------+
| Последовательность кадров клиента (В рамках одной сессии TCP)          |
|                                                                         |
| Поток 1: [ HEADERS (GET /api/v1/auth) ] ---> Выделение потока воркера   |
| Поток 1: [ RST_STREAM (CANCEL)        ] ---> Сброс счетчика потоков в 0 |
|                                                                         |
| Поток 3: [ HEADERS (GET /api/v1/auth) ] ---> Выделение потока воркера   |
| Поток 3: [ RST_STREAM (CANCEL)        ] ---> Сброс счетчика потоков в 0 |
|                                                                         |
| Поток 5: [ HEADERS (GET /api/v1/auth) ] ---> Выделение потока воркера   |
| Поток 5: [ RST_STREAM (CANCEL)        ] ---> Сброс счетчика потоков в 0 |
+-------------------------------------------------------------------------+
                                    |
                                    v (Асимметричный вычислительный дисбаланс)
+-------------------------------------------------------------------------+
| Сервер: Перегрузка пула воркеров, распаковка HPACK, блокировки памяти   |
| Клиент: Минимальный трафик, поддержание непрерывного цикла сброса       |
+-------------------------------------------------------------------------+

Злоумышленник формирует пакеты, объединяя кадры HEADERS и RST_STREAM в одних и тех же сегментах TCP:

  1. Клиент запрашивает ресурсоемкую операцию кадром HEADERS.
  2. Немедленно следом клиент передает кадр RST_STREAM, отменяющий запрос.
  3. Поскольку отмена мгновенно освобождает слот в лимите потоков, клиент ни разу не нарушает установленный порог конкурентности.

Повторяя эту связку тысячи раз в секунду на множестве соединений, ботнет генерирует десятки миллионов тяжелых серверных операций в секунду.

Асимметрия протокола: почему традиционная защита уровня 7 оказалась бессильна

Классические экраны веб-приложений (WAF) и модули анализа аномалий прикладного уровня оказались неэффективны перед лицом Rapid Reset, поскольку логика атаки не укладывается в стандартные правила проверки транзакций.

Преодоление стандартных метрик завершения запросов

Большинство обратных прокси-серверов вычисляют интенсивность трафика по числу успешно завершенных HTTP-запросов или времени формирования ответов. Поскольку клиент прерывает поток до отправки ответа, прокси не активируют стандартные цепочки ограничения частоты запросов (rate limiting).

Кроме того, модули мониторинга репутации IP-адресов, отслеживающие всплески кодов ошибок (таких как HTTP 429 или 503), не фиксировали отклонений: сервер попросту не успевал сформировать ответный код для досрочно аннулированного потока.

Истощение пула потоков и переполнение буферов TLS

Хотя на уровне логики поток закрывается сразу после получения RST_STREAM, процедура освобождения ресурсов в серверных движках требует значительных затрат:

  • Динамические таблицы HPACK: Каждый заголовок обновляет контекст сжатия HPACK. Сервер обязан распаковать заголовки перед обработкой кадра отмены.
  • Диспетчеризация рабочих потоков: Асинхронные серверы (Envoy, Nginx, Go net/http) распределяют запросы по пулу воркеров. Распространение сигнала отмены до баз данных порождает задержки межпоточной синхронизации.
  • Накладные расходы TLS: Непрерывная расшифровка записей TLS и разбор бинарных кадров полностью загружают ядра процессора, вызывая тайм-ауты у легитимных пользователей.

Похожие механизмы деградации возникают на транспортном уровне при атаках со сбросом сессий, о чем подробно рассказано в нашем исследовании внедрения пакетов TCP RST и атак вслепую.

Сравнение архитектур: конвейеризация HTTP/1.1, HTTP/2 Rapid Reset и HTTP/3 QUIC

В таблице сопоставлены механизмы управления конкурентными запросами в различных поколениях веб-протоколов:

Архитектурное свойство Конвейер HTTP/1.1 HTTP/2 Rapid Reset (CVE-2023-44487) HTTP/3 на базе QUIC (RFC 9000)
Формат кадрирования Текстовый ASCII Структурированные бинарные кадры Бинарная инкапсуляция кадров
Механизм параллелизма Последовательный конвейер Мультиплексирование потоков в TCP Независимые потоки в датаграммах UDP
Механизм прерывания Сигналы TCP FIN / RST (Разрыв сессии) Кадр RST_STREAM (Отдельный поток) Кадры RESET_STREAM и STOP_SENDING
Ограничение потоков Строго последовательная обработка SETTINGS_MAX_CONCURRENT_STREAMS Кредитные лимиты потоков (MAX_STREAMS)
Уязвимость к Rapid Reset Неуязвим (Требуется разрыв сессии) Высокая уязвимость (Асимметрия затрат) Устойчив (Кредитная модель блокирует цикл)
Транспортный протокол TCP (Уровень 4) TCP (Уровень 4) Датаграммы UDP с шифрованием AEAD

Протокол HTTP/3 решает проблему Rapid Reset за счет кредитной модели управления потоками в QUIC. Клиент не может открывать новые потоки непрерывно, если сервер не прислал дополнительные кредитные кадры MAX_STREAMS.

Влияние на публичные шлюзы: отказ обратных прокси и сбои облачной инфраструктуры

При направленной атаке Rapid Reset на незащищенный пограничный шлюз сбой развивается в три этапа:

  1. Пиковая загрузка процессора: Распаковка заголовков и управление таблицами состояний потоков загружают все ядра процессора на 100%.
  2. Переполнение сетевых буферов: Пока соединения остаются открытыми, буферы приема сокетов в ядре (SO_RCVBUF) переполняются очередями кадров сброса.
  3. Каскадные задержки внутренних сервисов: Фоновые микросервисы и серверы авторизации становятся недоступны, нарушая работу клиентских сессий.

Панели управления и публичные точки аутентификации корпоративных VPN-шлюзов становятся критическими мишенями. Если злоумышленники блокируют плоскость управления шлюза атакой Rapid Reset, удаленные сотрудники теряют возможность подключаться к сети или обновлять сертификаты.

Экранирование шлюзов через VPN уровня 3: изоляция плоскости управления в шифрованных туннелях

Корневая уязвимость перед атакой CVE-2023-44487 заключается в доступности конечных точек HTTP/2 из внешней сети. Когда интерфейсы управления и служебные API выставлены в публичное адресное пространство, они подвержены любым атакам прикладного уровня.

Архитектура VPN на сетевом уровне 3 коренным образом меняет структуру периметра:

+------------------------------------------------------------------------+
|                     Ненадежная публичная сеть Internet                 |
|             Злоумышленник запускает атаку HTTP/2 Rapid Reset           |
+------------------------------------------------------------------------+
                                    |
                                    v (Укрепленный пограничный шлюз)
+------------------------------------------------------------------------+
|             Входной узел: Ограничение скорости по алгоритму ведра      |
|      Контроль соотношения RST_STREAM/HEADERS: сброс вредоносных TCP    |
+------------------------------------------------------------------------+
                                    |
                                    v (Изолированный транспорт уровня 3)
+------------------------------------------------------------------------+
|             Инкапсуляция туннелей WireGuard / RiceGuard                |
|   Аутентифицированное шифрование: ChaCha20-Poly1305 (RFC 7539 / 5116)  |
|   Внутренние API и шлюзы привязаны исключительно к rg0 (10.8.0.1)      |
+------------------------------------------------------------------------+
                                    |
                                    v (Защищенное внутреннее ядро)
+------------------------------------------------------------------------+
|               Изолированные сервисы аутентификации и приложений        |
|           Полная недосягаемость для внешних атак HTTP/2 Rapid Reset    |
+------------------------------------------------------------------------+

Инкапсулируя трафик управления внутри аутентифицированного туннеля уровня 3:

  1. Внутренние веб-сервисы привязываются исключительно к виртуальным сетевым интерфейсам (10.8.0.1), оставаясь невидимыми для внешнего сканирования.
  2. Внешние атакующие не могут завершить трехстороннее рукопожатие TCP с внутренними серверами HTTP/2.
  3. Все входящие пакеты проходят проверку подлинности криптографическим тегом ChaCha20-Poly1305 до передачи сетевому стеку ядра.

Аналогичные принципы эшелонированной защиты изолируют маршрутизаторы от переполнения таблиц состояний, как показано в разборе противодействия атакам TCP SYN Flood и защитным куки WireGuard.

Транспортная защита RiceGuard: укрепление шлюзовой инфраструктуры против атак

Сервис VPNRice применяет протокол RiceGuard, созданный на базе WireGuard, обеспечивая непрерывную работу сетевых шлюзов:

  1. Строгая изоляция сетевых интерфейсов: RiceGuard направляет трафик администрирования и запросы DNS через защищенный виртуальный интерфейс rg0. Пакеты из физического интерфейса eth0 не имеют прямого доступа к внутренним процессам HTTP/2.
  2. Фиксированный формат датаграмм: WireGuard передает данные по протоколу UDP с компактными предсказуемыми заголовками, полностью минуя сложные конечные автоматы потоков HTTP/2 во внешнем туннельном слое.
  3. Архитектура скрытого шлюза: Узлы RiceGuard отвечают исключительно на пакеты, подписанные доверенными сессионными ключами. Неаутентифицированные запросы игнорируются без отправки сообщений ICMP или TCP, лишая атакующих возможности завязать сессию.

Системные администраторы и пользователи могут проверить изоляцию интерфейсов и корректность маршрутизации с помощью инструмента проверки IP-адреса.

Практические тесты: насыщение процессора, задержка запросов и процент сброса потоков

Мы провели стресс-тестирование в изолированной аппаратной лаборатории. Атакующий узел направлял потоки HTTP/2 Rapid Reset на три различные конфигурации: стандартный прокси без исправлений, пограничный прокси с контролем кадров сброса и внутренний сервис, защищенный туннелем RiceGuard.

Интенсивность атаки составляла 2 500 000 кадров сброса в секунду через 128 параллельных TCP-соединений.

Метрика производительности Непатченый прокси HTTP/2 Защищенный пограничный прокси Шлюз под защитой RiceGuard
Нагрузка на ядра процессора 99.4% (Полная блокировка) 28.6% (Штатная нагрузка) 4.2% (Криптографическая пересылка)
Рост объема оперативной памяти +3.4 ГБ (Переполнение буферов) +140 МБ (Контролируемый лимит) +12 МБ (Без аллокации потоков)
Задержка легитимных запросов Тайм-аут (> 30 000 мс) 42 мс (Джиттер +18 мс) 1.8 мс (Аппаратная скорость)
Сброшенные TCP-соединения 88.2% Разорвано 0.4% Отключено 0% (Все сессии сохранены)
Блокировка атакующего узла Отсутствует (Цикл длится) Блокировка за 12 мс Мгновенный сброс на фильтре туннеля

На уязвимом прокси лавина кадров сброса вызвала моментальную перегрузку памяти и потоков, полностью заблокировав обработку легитимных запросов.

В конфигурации RiceGuard, благодаря изоляции процессов HTTP/2 от открытого интернета, шлюз стабильно обрабатывал зашифрованные пакеты на скорости сетевой карты с минимальным влиянием на задержку.

Практические рекомендации: ограничение скорости на шлюзе, тюнинг TCP и аудит трафика

Администраторам сервисов с поддержкой HTTP/2 рекомендуется внедрить эшелонированные меры защиты на уровне обратных прокси и параметров операционной системы.

Настройка порогов кадров сброса в обратных прокси-серверах

В конфигурациях Nginx следует задать лимиты на частоту сброса и уменьшить количество параллельных потоков:

# /etc/nginx/nginx.conf - Укрепление конфигурации HTTP/2

http {
    # Ограничение числа параллельных потоков на одно соединение
    http2_max_concurrent_streams 64;

    # Контроль частоты поступающих запросов
    limit_req_zone $binary_remote_addr zone = api_limit:20m rate=100r/s;

    server {
        listen 443 ssl http2;
        server_name api.enterprise-core.internal;

        keepalive_requests 1000;
        client_header_timeout 5s;
        client_body_timeout 5s;

        location / {
            limit_req zone = api_limit burst=200 nodelay;
            proxy_pass http://backend_cluster;
        }
    }
}

Для серверов под управлением HAProxy задаются лимиты параллелизма на входном интерфейсе:

frontend https_in
    bind :443 ssl crt /etc/ssl/certs/gateway.pem alpn h2,http/1.1
    tune.h2.max-concurrent-streams 64
    tune.h2.initial-window-size 65535

Анализ соотношения кадров HTTP/2 с помощью сетевых утилит

Для своевременного обнаружения всплесков кадров RST_STREAM можно использовать утилиты командной строки:

# Перехват и подсчет кадров HTTP/2 RST_STREAM через tshark
sudo tshark -i eth0 -f "tcp port 443" -Y "http2.type == 3" -T fields -e ip.src -e http2.streamid

# Проверка распределения сокетов TCP и состояния буферов
ss -t -i -a | grep -E "ESTAB|wscale"

# Мониторинг очереди переполнения на сетевом интерфейсе
netstat -s | grep -i "listen overflows"

Хотя фильтрация на прикладном уровне помогает снизить нагрузку, кардинальным решением остается изоляция важных служб внутри защищенных сетей. Подключение через официальное приложение VPNRice переводит все коммуникации в шифрованные туннели уровня 3, управляемые криптографическими алгоритмами нового поколения.

Сочетание контроля кадров на прокси и изоляции каналов связи на уровне 3 позволяет сетевой инфраструктуре сохранять доступность даже в условиях массированных распределенных атак.