Зачем внедрять сетевой разрыв: модель угроз и векторы атак
Каждый разговор о логическом разрыве упирается в один вопрос: «А зачем? У нас есть firewall, WAF, TLS и патч-менеджмент». Вопрос правильный — разрыв стоит денег, добавляет задержку и усложняет архитектуру.
Короткий ответ
Все традиционные средства — firewall, WAF (Web Application Firewall), IPS (Intrusion Prevention System) — исходят из того, что сквозной путь от недоверенной зоны к доверенной существует, и ставят на этом пути фильтр. Само существование этого пути имеет три конкретных последствия:
- Байты атакующего доходят до кода доверенного сегмента. Их разбирают прошивка NIC, драйверы, сетевой стек ядра, TLS-библиотека — и всё это до того, как приложение проверит хоть один токен. Любая ошибка памяти в этой цепочке эксплуатируется удалённо и без аутентификации.
- Безопасность равна корректности каждого элемента на пути. Ошибка в фильтре, уязвимость в самом фильтре или одна лишняя строка в правиле — и путь открыт целиком. Это цепочка условий, которая со временем только удлиняется.
- Любой скомпрометированный узел на пути уже имеет доступ внутрь. Ему не нужно пробивать периметр — он его часть.
Разрыв убирает сам путь: пакет из недоверенной зоны не маршрутизируется к доверенному сегменту, соединение всегда инициирует доверенная сторона. Все три последствия исчезают одновременно, потому что исчезает их общая предпосылка.
Периметр: три источника уязвимостей
Типовая схема публикации внутреннего API:
Здесь два источника уязвимостей, и ни один из них не является ошибкой конфигурации — оба следуют из архитектуры:
- Достижимость доверенного кода. Пакет клиента доезжает до сетевого интерфейса внутреннего сервиса. Значит, вся цепочка разбора на этой машине — от прошивки карты до парсера прикладного протокола — становится pre-auth-поверхностью атаки, доступной снаружи.
- Слушающий порт как готовая точка входа. Внутренний сервис принимает входящие соединения из DMZ. Скомпрометированному узлу DMZ не нужно искать вход — он открыт и разрешён правилом, которое нельзя убрать, потому что оно нужно приложению.
Разрыв в терминах каталога вариантов убирает оба: пакет извне не доезжает до доверенного сегмента, а входящих соединений в него нет вообще. Посредник остаётся, но через него проходит не трафик, а узкое сообщение фиксированной схемы, и соединение внутрь всегда открывает доверенная сторона.
Настоящая атакуемая поверхность: всё, что разбирает пакет до приложения
Когда мы говорим «входящий запрос», мы представляем обработчик в приложении: он проверит токен, валидирует тело, отклонит лишнее. Но до первой строки прикладного кода пакет проходит длинную цепочку программ, и каждая из них разбирает недоверенные байты до любой аутентификации.
Голое железо — минимальный случай: Прошивка сетевой карты (разбор кадров, offload вроде TSO/LRO и контрольных сумм), драйвер в ядре с DMA и кольцевыми буферами, сетевой стек ОС — ARP, IP с фрагментацией и сборкой, ICMP, конечный автомат TCP с опциями и расширениями, — затем conntrack и netfilter, TLS-библиотека и парсер прикладного протокола: HTTP/1.1, у HTTP/2 — мультиплексор кадров и сжатие заголовков HPACK, у gRPC — ещё и десериализация protobuf до перехватчиков авторизации, у WebSocket — разбор фреймов и маскирования, у HTTP/3 — весь транспорт QUIC, переехавший в user space. Сотни тысяч строк преимущественно C-кода, и все они трогают байты атакующего раньше, чем приложение узнаёт о существовании запроса.
Виртуализация удлиняет цепочку: Пакеты обрабатывают драйвер, стек и виртуальный коммутатор хоста, затем виртуальное устройство гипервизора — virtio-net, vmxnet3 или эмуляция e1000, — и только потом начинается путь по гостевой ОС: снова драйвер, снова стек. Каждый слой — отдельная, независимо написанная реализация разбора одних и тех же байтов.
Худший и при этом самый типовой случай: Docker на виртуалке:
Закрытый код больше не сокращает эту поверхность. Возражение «у нас проприетарный стек, исходников нет, искать там уязвимости слишком дорого» держалось на одной экономике: ручной реверс-инжиниринг бинарника — это месяцы работы редкого специалиста. Именно эту цену и убирают инструменты автоматического и AI-анализа: языковая модель поверх декомпилятора восстанавливает из машинного кода структуры, форматы и логику разбора, а дальше связка «символьное исполнение плюс фаззинг с направляющей моделью» ищет ошибку без единой строки исходников. Закрытость меняет не наличие уязвимости, а только то, кто найдёт её первым и станет ли находка публичной.
Уязвимости находят машины, и уже не в лабораторных условиях:
- ноябрь 2024 — агент Big Sleep (Google Project Zero и DeepMind) самостоятельно нашёл ранее неизвестный stack buffer underflow в SQLite; Google описал это как первый публичный случай, когда ИИ-агент обнаружил ранее неизвестную уязвимость памяти в широко используемом ПО. В июле 2025 тот же агент нашёл в SQLite CVE-2025-6965 — повреждение памяти, о котором, по оценке Google, на тот момент знали только атакующие;
- октябрь 2024 — OSS-Fuzz с фаззинг-таргетами, сгенерированными языковой моделью, нашёл в OpenSSL CVE-2024-9143: выход за границы буфера в низкоуровневом API эллиптических кривых
GF(2^m), пролежавший в открытом и годами аудируемом коде около двух десятилетий; - август 2025 — в финале DARPA AI Cyber Challenge автономные системы нашли около трёх четвертей специально внедрённых уязвимостей и вдобавок 18 ранее неизвестных в реальных open-source-проектах, причём сами же сгенерировали к ним патчи;
- бинарники — не исключение: ещё на DARPA Cyber Grand Challenge в 2016 году машины находили и эксплуатировали уязвимости в бинарниках без исходников в реальном времени, на скорости соревнования. Сегодня к бинарному фаззингу и символьному исполнению добавились языковые модели, работающие с декомпилированным кодом.
Для схемы выше это значит, что закрытые слои — прошивка NIC, management-движок, виртуальное устройство гипервизора — не «безопаснее по умолчанию», а всего лишь хуже освещены: там меньше публичных CVE, а не меньше ошибок. Broadpwn в прошивке Broadcom (CVE-2017-9417) и обход аутентификации в Intel AMT (CVE-2017-5689) добыли ручным реверсом закрытых бинарников ещё до всякого AI — просто это стоило месяцев работы редкого специалиста. Теперь дешевле и дешевеет дальше, а значит, ставка «нас не будут ковырять, там же нет исходников» перестала быть ставкой на что-либо. Не зависит от стоимости анализа только одно: если байты до слоя не доходят, разбирать его нечем и незачем.
Лаг обновлений — вторая половина проблемы. Против 0-day патч-менеджмент не работает по определению, но и после выхода патча гонка не заканчивается:
- цепочку в Ivanti Connect Secure эксплуатировали с начала декабря 2023-го, патчи начали выходить в конце января 2024-го — окно в недели;
- патч ядра или гипервизора — это перезагрузка или миграция ВМ, а окно обслуживания в 24/7-инфраструктуре планируют неделями;
- прошивки сетевых карт и BMC на практике не обновляются годами;
- ESXiArgs в феврале 2023-го массово шифровал серверы через CVE-2021-21974 — патч к ней вышел двумя годами ранее.
Что здесь меняет разрыв. У всей цепочки — от прошивки NIC до парсера прикладного протокола — одно общее условие эксплуатации: атакующий должен доставить свой пакет к машине. В контуре с разрывом у машин доверенного сегмента такой достижимости нет: маршрута из недоверенной зоны к ним не существует, исходящее соединение к шлюзу открывает сам исполнитель. Цепочка разбора перестаёт быть pre-auth-поверхностью — не потому, что уязвимости кончились, а потому, что байты до них не долетают. Гонка «эксплойт против патча» остаётся только на шлюзе — узле, спроектированном как расходный: минимальная поставка, нет секретов, нет маршрута внутрь.
Да, конечно, остется еще "клиентский код исполнителя" и там тоже могут быть уязвимости, об этом будет позже в "Остаточный риск: клиентский код исполнителя".
Модель угроз
Что защищаем. Доверенный сегмент: внутренние API, базы данных, технологические сети АСУ ТП, системы с персональными данными или гостайной — всё, компрометация чего стоит несоизмеримо дороже недоступности.
Ключевая способность противника, вокруг которой строится модель, — доставить байты до кода доверенного сегмента. Именно её даёт сквозной путь и именно её убирает разрыв.
| Противник | Возможности | Цель |
|---|---|---|
| Внешний атакующий | Сканирование, эксплуатация периметра, 0-day в сетевом стеке и гипервизоре, переиспользование одного эксплойта на однотипных узлах пути | Первичный доступ и продвижение хоп за хопом |
| Закрепившийся в DMZ | Полный контроль над узлом DMZ, произвольный трафик и украденные креды из него | Продвижение внутрь |
| Внутри доверенного сегмента | Контроль над внутренним узлом | Канал C2, эксфильтрация |
| Цепочка поставок | Закладка в периметровом ПО или устройстве | Скрытый доступ через «доверенный» компонент |
Допущения. Сетевые стеки, гипервизоры и контейнерная сеть содержат неизвестные уязвимости — это статистика, а не пессимизм. Конфигурации содержат ошибки. Сигнатурные средства не детектируют то, чего ещё нет в сигнатурах.
Если этих допущений в вашей модели нет — например, вы готовы принять риск 0-day в сетевом стеке доверенной машины — разрыв вам, скорее всего, не нужен.
Три вектора, которые закрывает только разрыв
1. RCE в сетевом стеке ОС — до всякой аутентификации
Как выполняется. Атакующий отправляет серию специально сформированных пакетов на IP-адрес машины. Пример — CVE-2024-38063 в tcpip.sys: ошибка обработки IPv6-фрагментов срабатывает в коде ядра, разбирающем заголовки. Ни рукопожатия, ни аутентификации, ни даже открытого порта не требуется — обработчик в ядре читает заголовки раньше, чем решается, кому отдать пакет. Того же класса SACK Panic и Bad Neighbor (CVE-2020-16898).
Что даёт. Исполнение кода в контексте ядра, то есть полный контроль над машиной доверенного сегмента, минуя все прикладные проверки. Логи приложения при этом пусты: приложение запроса не видело.
Почему периметр не спасает. Firewall обязан пропускать трафик к опубликованному сервису — пакет доходит до интерфейса, а этого достаточно. WAF разбирает L7 и до L3-эксплойта не доходит. Host-based фильтр в этой цепочке — ещё один потребитель тех же байтов, стоящий над уязвимым кодом.
Как защищает разрыв. Условие эксплуатации — доставить пакет к интерфейсу машины. В контуре с разрывом машины доверенного сегмента нет ни в одной таблице маршрутизации со стороны недоверенной зоны: отдельная адресация, отсутствие маршрута и трансляции, интерфейс не смотрит наружу. Единственный сетевой обмен — исходящая TCP-сессия исполнителя к шлюзу; ответные пакеты принимаются только в рамках уже установленной сессии (conntrack ESTABLISHED), инициированной изнутри. Эксплойт остаётся рабочим, но недоставляемым: у атакующего нет ни одного пути отправить байты в стек ядра доверенной машины.
2. Разведка и lateral movement по разрешённому правилу
Как выполняется. Атакующий на узле DMZ пользуется правилом, которое там есть по определению: DMZ → internal-api:443. Через него он сканирует внутренний диапазон, снимает баннеры и версии, эксплуатирует внутренние сервисы (патчатся реже периметра) или переиспользует украденный у прокси токен и клиентский сертификат mTLS. Для файрвола весь этот трафик легитимен — он соответствует разрешающему правилу.
Что даёт. Точку входа в доверенный сегмент и карту целей внутри него.
Почему периметр не спасает. Правило нужно приложению, поэтому его нельзя убрать — можно только сузить. Микросегментация уменьшает список целей, но разрешённые ей потоки остаются сквозными путями. IDS замечает аномалию постфактум и не всегда.
Как защищает разрыв. Pull-модель: в доверенном сегменте нет ни одного слушающего порта, доступного из недоверенной зоны, а inbound-политика — deny all без исключения «для приложения». Исполнитель сам держит исходящий long-poll к шлюзу и получает задачи в ответах этой сессии. Для узла DMZ это означает: SYN в сторону сегмента не имеет маршрута, сканирование не возвращает ни одного открытого порта, украденный токен бесполезен — им нельзя инициировать соединение туда, куда нет пути. Класс атак «нашёл порт → определил версию → проэксплуатировал» не затрудняется, а исчезает: у него нет первого шага.
3. Цепочка hop-by-hop: одна уязвимость доводит до доверенного сегмента
Как выполняется. У атакующего есть 0-day в компоненте, который стоит на каждой машине контура: сетевой стек ядра, TLS-библиотека, реализация HTTP/2. Это типично — узлы разворачивают из одного образа, с одной сборкой ядра и одним base image. Дальше он идёт по цепочке достижимости, и каждый шаг разрешён потому, что предыдущий узел обязан общаться с последующим:
- эксплойт против внешнего балансировщика — получен код на узле, смотрящем в интернет;
- с него тот же эксплойт против прокси/WAF в DMZ — узел достижим, балансировщик обязан к нему обращаться;
- с прокси тот же эксплойт против внутреннего сервиса — правило
DMZ → internal-api:443существует по построению.
Что даёт. Три хопа, один эксплойт, ни одного украденного пароля — и RCE на машине доверенного сегмента. Ни на одном шаге не понадобилось обходить аутентификацию: уязвимый код лежит ниже неё.
Почему периметр не спасает. Каждый рубеж — это ещё одна машина с тем же уязвимым слоем, то есть ещё один хоп, а не барьер. Разные вендоры помогают только если уязвимость не в общем слое; ядро, libc и TLS общие почти всегда. Правила не мешают: атакующий использует ровно те потоки, которые разрешены для работы приложения.
Как защищает разрыв. Цепочка обрывается на последнем узле недоверенной зоны — на шлюзе. Следующего хопа просто нет: у шлюза нет маршрута в доверенный сегмент, нет его адресов и нет права инициировать соединение; сессию всегда открывает исполнитель изнутри и сам забирает задачи.
Эксплойт остаётся рабочим, но работает только до границы: захвачен расходный узел без секретов и без пути внутрь.
Остаточный риск: клиентский код исполнителя. Ноля здесь нет. Захватив шлюз, атакующий контролирует ответы, которые получает исполнитель, и может атаковать его клиентскую часть — TLS-клиент, HTTP-клиент, десериализатор JSON или protobuf. Но риск не тот же самый, и разница измеримая:
- Инициативу теряет атакующий. Он не может обратиться к исполнителю: адреса нет, слушающих портов нет, сканирование ничего не возвращает. Он может только отвечать на запрос, который исполнитель сделал сам, — нет выбора момента, нет параллельных попыток по всем машинам сегмента, нет повторного захода после падения процесса.
- Поверхность у клиента меньше. Сервер разбирает запрос произвольной формы от произвольного отправителя: слушающий сокет и accept, конкурентные соединения, маршрутизацию, состояние сессий, таблицы HPACK и стримы, апгрейды протокола. Отсюда и класс серверных ошибок — request smuggling, CONTINUATION flood, десинхронизация. Клиент разбирает ответ на собственный запрос: один известный эндпоинт, ожидаемый content-type, лимиты длины и таймаута, схема, по которой ответ можно провалидировать до использования.
- Серверный код исследуют несравнимо активнее. Его может фаззить любой в интернете, поэтому туда направлены сканеры, bug bounty и массовая эксплуатация, и подавляющая часть pre-auth RCE — про серверные компоненты. Клиентскую часть исполнителя в этой позиции способен атаковать только тот, кто уже захватил шлюз, — а значит, и цена, и заметность атаки другие.
Поэтому pull не убирает риск, а меняет его класс: вместо pre-auth RCE, доступного любому в интернете и продолжаемого хоп за хопом, остаётся post-compromise атака на узкий клиентский парсер, доступная только тому, кто уже потратил 0-day на расходный шлюз. Снижается она обычными средствами: минимальный клиент, жёсткие лимиты на размер и время ответа, строгая валидация ответа по схеме.
От чего разрыв не защищает
- Атаки через валидный запрос. Сам по себе разрыв контролирует форму обмена, а не смысл содержимого: SQL-инъекция, укладывающаяся в схему моста, будет доставлена и выполнена. Если в точке разрыва вся полезная нагрузка разобрана в структуру и её можно проверить до попадания внутрь, если в этой точке реализован строгий форматно-логический контроль (ФЛК) — allow-list операций и полей, типы, длины, диапазоны, регулярные выражения и перечисления значений, отказ по умолчанию для всего неописанного, — то запросы с инъекциями, обходом путей и неожиданными полями не проходят границу вообще. Также, ФЛК не спасает от нагрузки, валидной по схеме, но опасной по смыслу (например, легитимного по формату идентификатора чужого объекта): это уровень авторизации в приложении.
- Компрометацию доверенного сегмента изнутри. Инсайдер, флешка, закладка в зависимости — разрыв сузит каналы наружу, но не предотвратит компрометацию.
- Компрометацию самого исполнителя. Его целостность обеспечивают поставка и контроль среды, а не архитектура разрыва.
- Уязвимости посредника и средств защиты. Шлюз в недоверенной зоне — такая же программа, разбирающая недоверенный ввод, как firewall или WAF, и у него есть свой интерфейс управления. Разрыв не делает его неуязвимым; он лишь ограничивает, что даёт его захват.
- Отказ в обслуживании. Шлюз доступен извне и может быть перегружен: разрыв защищает изоляцию, а не доступность.
- Социальную инженерию и всё, что не проходит через сетевую границу.
Когда разрыв оправдан, а когда избыточен
| Признак контура | Разрыв оправдан | Разрыв избыточен |
|---|---|---|
| Цена компрометации | КИИ, АСУ ТП, гостайна, финансовое ядро, ПДн | обычное веб-приложение, потери восполнимы |
| Модель угроз | 0-day, закрепление в DMZ | массовые автоматические атаки |
| Главный риск | достижимость сегмента извне | уязвимости самого приложения |
| Комплаенс | требуется отсутствие прямой связности сегментов | достаточно стандартной сегментации |
| Характер обмена | конечный набор операций, описываемых схемой | произвольный трафик, WebSocket, стриминг |
| Требования к задержке | десятки миллисекунд допустимы | критична минимальная задержка |
| Приоритет | изоляция важнее доступности | доступность важнее изоляции |
Практический маркер в пользу разрыва — регуляторное требование об отсутствии прямой связности: разрыв закрывает его архитектурно, а не компенсирующими мерами. Против — если основной риск лежит в коде приложения: тогда бюджет разумнее вложить в безопасную разработку, а разрыв только добавит задержку и эксплуатационную сложность (её я измерял в исследовании MVP).
Итог
- Атакуемая поверхность опубликованного сервиса — не его код, а девять слоёв разбора недоверенных байтов под ним: прошивка NIC, драйверы, стек ОС, гипервизор, контейнерная сеть, TLS, парсер прикладного протокола (HTTP/1.1, HTTP/2, gRPC, WebSocket, QUIC). Все они pre-auth, во всех регулярно находят RCE, патчи доходят с лагом от недель до лет.
- Единственное общее условие эксплуатации всей этой цепочки — достижимость машины по сети. Разрыв убирает именно её, а не фильтрует трафик: маршрута нет, слушающих портов нет, соединение открывает доверенная сторона.
- Поэтому разрыв закрывает то, до чего фильтры структурно не дотягиваются: 0-day в сетевом стеке и гипервизоре, разведку, lateral movement из DMZ. Главное следствие — цепочка «хоп за хопом одним эксплойтом» обрывается на шлюзе: дальше нет ни маршрута, ни слушающего порта. Остаточный риск смещается в клиентский код исполнителя — поверхность меньше, инициатива не у атакующего, и добраться до неё можно только после захвата шлюза.
- Всё остальное — WAF, патчи, сегментация, безопасная разработка — по-прежнему нужно.
Как этот паттерн реализуется и во что обходится — в каталоге вариантов, посте о направлениях развития и небольшом исследовании MVP.

