
На мероприятиях по сетевой безопасности всё чаще обсуждают, как правильно соотносить показатели производительности сетевых средств защиты информации (СЗИ) с потребностями организации. Новые функции и продукты в условиях импортозамещения появляются с умопомрачительной скоростью. И с такой же скоростью для них разрабатываются новые методики, показатели, измерительные средства. Но эта гонка касается не только потребителей и интеграторов. Разработчикам нужно как успевать создавать и модернизировать продукты на уровне конкурентов, так и качественно проверять, отлаживать свои решения.
Особенно остро этот вопрос стоит для NGFW — самого сложного и полнофункционального продукта в линейке сетевых СЗИ. Наши коллеги уже делились опытом в этой области. Мы расскажем о своём подходе: как мы сопровождали разработку и тестировали режимы работы сетевых СЗИ с помощью собственного генератора трафика.
Содержание
Почему мы не стали покупать готовый генератор трафика
Всё началось с потребности сопровождать разработку высокопроизводительного решения — кластера NGFW active-active. А для этого нужно было генерировать разнообразные потоки данных. Можно было купить готовое решение от IXIA или Xinertel, но такой подход имеет недостатки:
Цена. Специализированное решение дорого, особенно если речь о сотнях гигабит.
Функциональность. NGFW сложен, и чтобы тестировать конкретную функцию, генератор должен быть не менее гибким и полнофункциональным (что снова влияет на цену).
Геополитические ограничения. Зарубежные продукты сложно или невозможно приобрести.
Мы искали более гибкое решение: универсальное, масштабируемое, интегрируемое в процесс разработки. Так родился наш генератор трафика.
Как мы поняли, что без автоматизации не обойтись
Первая из причин — широкий функционал NGFW. Антивирус, DDoS-защита, контроль DGA-доменов, миллионы SIP-сессий — всё это соседствует в одном продукте. За этим стоят миллионы строк кода и бесчисленные интеграционные сценарии, которые нужно воспроизводить с минимальными усилиями.
Производительность NGFW сильно зависит от конфигурации. Нам требовалась библиотека сценариев работы в различных режимах, которую можно постоянно пополнять.
Вторая причина — многообразие методик тестирования: RFC 9411, подходы NSS Labs, и находящаяся в разработке «Методика тестирования производительности NGFW» от ФСТЭК. Если применять разные методики, можно получить сильно отличающиеся результаты. Нам нужна была возможность быстро воспроизводить любые методики испытаний.
Третья причина — сложность встраивания сетевых СЗИ в существующую инфраструктуру. Поскольку такие системы становятся неотъемлемым элементом сети заказчика, возникает обоюдное влияние: сетевой трафик воздействует на работу СЗИ, а СЗИ модифицируют сетевые процессы. При выборе решений и оценке их эффективности необходимо дополнительно учитывать сценарии и способы интеграции.
Наша задача звучала так: нужен генератор трафика, который позволит разработчикам создавать интеграционные стенды и выполнять в автоматическом режиме набор сценариев. Сценарии должны фокусироваться на работе конкретных функций NGFW, генерируя различные потоки данных и управляющие команды. Генератор должен быть высокоавтоматизированным, масштабируемым и готовым к постоянным изменениям. Конечно, не стоит забывать о том, что разработка — процесс динамический, и генератор трафика должен меняться вместе с ней.
Разработка архитектуры
Разработка генератора трафика стартовала с мозгового штурма команды, которая заложила первые концепции. Уже на старте мы столкнулись с двумя ключевыми вопросами. Во-первых, какое оборудование — физическое или виртуальное — будет служить платформой для генератора? Во-вторых, насколько глубоко пользователь должен погружаться в архитектуру системы, иначе говоря, кто наша целевая аудитория?
И пока проект не отягощён обязательствами на старте, были приняты ещё два важных решения:
Минимальные требования к платформам: Debian 12, от 8 ГБ ОЗУ на сокет CPU, сетевая карта от 1 Гбит/с. Это позволяет использовать разнородное оборудование, которое есть в командах.
Целевая аудитория — разработчики СЗИ. Они лучше всех знают, что и как тестировать.
Следует пояснить, что в любой команде есть пул разнородного оборудования, которое потенциально можно задействовать для решения задачи. Поэтому мы намеренно не стали завышать требования к платформе — генератор должен работать на большинстве оборудования, которое есть в командах. Но данный подход имеет и слабые стороны:
сложнее подключать новое и незнакомое оборудование к системе
система неоднородна, нужна балансировка задач
и ещё всем этим «зверинцем» необходимо управлять.
Когда мы сложили весь этот пазл из причин, требований и свойств, стало понятно: нам нужен Kubernetes!
Архитектура решения
Kubernetes — система с двухуровневой иерархией: управляющий мастер-узел и узлы-работники. На каждом узле могут разворачиваться поды-генераторы.

Узлу-мастеру по-прежнему делегируются основные функции управления, которые реализованы в виде трёх программных примитивов:
Registry — реестр и поставщик поддерживаемых генераторов. Предназначен для хранения Docker-образов генераторов трафика с метаданными для их запуска (необходимые ресурсы для развёртывания, параметры генератора и т.д.).
Discovery управляет «железным зоопарком». Добавляет, настраивает и удаляет узлы, устанавливает ПО, сертификаты, конфигурирует виртуальные интерфейсы и выделяет hugepages.
Crux — оператор всей системы. Обрабатывает пользовательские команды по REST API, управляет ресурсами кластера k8s, создаёт и настраивает группы генераторов, запускает тесты (синхронно и асинхронно).
И перейдём к основному элементу нашей системы — генератору трафика. Что он представляет из себя в нашем кластере k8s?
Это логическое объединение ПО, выполняющую работу по генерации и обработки тестового трафика. В нашей платформе генераторы — это несколько приложений, обычно клиенты и серверы. Каждый элемент генератора размещается в своём контейнере — изолированном пространстве нагрузчика.
Элемент генератора оперирует следующими параметрами:
количество ресурсов, которыми он должен оперировать
его роль в работе по генерации трафика (клиент, сервер, клиент-сервер).

Типы генераторов
В нашей системе есть несколько видов контейнеров:
Cisco-Trex — один из самых популярных генераторов с открытым исходным кодом. С его помощью можно создавать условия для:
o предельной нагрузки по пропускной способности (Throughput)
o скорости открытия соединений (CPS, connection per second)
o большего количества одновременно обслуживаемых сессий (CC, concurrent connections).
Он включает множество профилей трафика (L3–L7), имеет два режима работы — stateless (без сохранения состояний) и stateful (с сохранением), гибок в настройках и поддаётся модификациям. Шаблоны трафика описываются кодом, что позволяет адаптировать генератор под большинство задач. А ещё он умеет размечать потоки с помощью DSCP-меток — а значит, сценарии дополняются возможностями маневрирования и QoS-режимами. Это особенно важно, когда СЗИ устанавливается в большой сети. Кстати, наш читатель безопасник или сетевик (см. рис. 3)?

SIP-генератор (на основе SIPp) — генератор с открытым исходным кодом, предназначенный для эмуляции протокола SIP. IP-телефония — один из самых сложных сценариев для СЗИ, поэтому мы добавили его в виде отдельного контейнера. SIPPp разворачивается как клиент-серверное приложение и умеет воспроизводить базовые сценарии: регистрацию, вызов и звонок. Поддерживаются UDP и TCP, а также TLS для шифрованных соединений. Генератор позволяет конфигурировать собственные сценарии (вплоть до эмуляции сбоев) и обладает обширным набором метрик для анализа звонков. А главное — он способен генерировать множество звонков одновременно, создавая реалистичную нагрузку.
FTP-генератор (на основе pyftpdlib и aioftp). Добавлен по той же причине, что и SIP: сложность обработки этого протокола СЗИ требует отдельного внимания. Генератор построен на базе FTP-сервера pyftpdlib и клиента на библиотеках ftplib и aioftp. Он воспроизводит основные сценарии: создание control- и data-соединений, скачивание файлов, поддерживает активный и пассивный режимы. Всё как в жизни.
TLS-генератор (Yandex-Tank + Nginx). Используется для работы с шифрованным трафиком, который составляет до 70% всех потоков данных. Причина его добавления в пул генераторов заключается в том, что проигрывание pcap-файлов с заранее записанным TLS-соединением нас не устраивает, нужен «живой» трафик. Задачи требуют, чтобы СЗИ участвовал в установлении соединений «третьим в середине». Yandex-Tank — это надстройка над генератором полезной нагрузки (Phantom, JMeter, BFG или Pandora). Он считывает конфигурацию, запускает генератор, отслеживает состояние и логирует результаты. На наш взгляд, Phantom — самый гибкий вариант: он поддерживает все популярные криптонаборы, позволяет настраивать длину ключа RSA и ECDSA. Клиентская часть готова, а серверная представлена проверенным и широко распространённым Nginx.
Генераторы атак: APT, DDoS, Web-атак, а также генератор легитимных клиентов на базе Selenium (с OWASP Juice Shop в роли веб-приложения).
Практика как критерий истины
Сценарий: «Когда голоса не бывает много»
В качестве первого примера практического использования генератора трафика приведём режим обработки СЗИ потоков данных VoIP-телефонии. Несмотря на видимую лёгкость формулировки, за ней скрывается ряд нюансов, способных нарушить работу call-центра организации. Генератор трафика предназначен для создания сложных сценариев, которые должны ввести СЗИ в условия предельных показателей функционирования. Примеры таких показателей:
количество устанавливаемых вызовов в секунду
общее количество обслуживаемых вызовов
средний процент неудачных вызовов.
Пробуем решить задачу. В качестве предусловия имеется узел-мастер и некоторый пул серверов, которыми он может распоряжаться по своему усмотрению. Отсюда возникает вопрос: откуда узел-мастер узнает, какими ресурсами обладает генератор?
Текущее состояние проекта предусматривает автоматическую калибровку контейнера-генератора: запускается эталонное задание с закольцовыванием выхода генератора на вход (так называемая схема «петля») через программирование коммутатора. Этот процесс выполняется для конкретного набора ресурсов, выделенного контейнеру. В повседневной работе оператор не действует каждый раз по наитию — он использует уже откалиброванные контейнеры. Но когда в состав генератора включается новый сервер, калибровка обязательна.
В зависимости от потенциала сервера и поставленных задач, на нём может быть размещено от одного до... на данный момент мы дошли до трёх десятков контейнеров-работников на одном узле. Представим, что пул аппаратных ресурсов распределён между генераторами, и показатели каждого контейнера в текущем сценарии известны. Теперь у нас есть всё, чтобы устроить идеальный шторм вызовов.

Первый сценарий — «Новый год!». Имитируем пик нагрузки, когда все звонят близким. Генератор создаёт идеальный шторм вызовов.

Второй сценарий — «Болтушки» — призван оценить устойчивость работы СЗИ в условиях сохранения максимального количества одновременно удерживаемых вызовов. Любая система массового обслуживания имеет свои ограничения, но даже с их учётом некоторые особенности функционирования могут быть восприняты некорректно.
Представим: система обрабатывает предельное количество звонков, скажем, N соединений открыты и не закрываются — абоненты просто «болтают». На вход в систему поступает ещё 10 вызовов. Очевидный ответ: они должны завершиться неудачей — система ведь перегружена. Но проиграть такой сценарий и убедиться в этом на практике нужно обязательно!
А что будет, если эти 10 вызовов имеют более высокий приоритет обслуживания (QoS) или даже гарантированную полосу пропускания? Как писал самый русский поэт: «О сколько нам открытий чудных...».
Сценарий: «Быстрее, выше, сильнее»
Это сценарий спорта высоких достижений — те случаи, когда здесь и сейчас нужно проверить работоспособность решения в условиях экстремальной нагрузки и максимальной масштабируемости. Как было сказано в фильме «Москва слезам не верит»: «Трудно с тремя, а когда трёх научишься организовывать, дальше число уже не имеет значения». Так и в наших экспериментах — планку в 400 Гбит/с мы не считали слишком высокой, но получили значения, недоступные разработчикам в повседневной работе.
Предельные режимы — это индикатор разных способностей СЗИ, и воспроизведение таких условий — обязательный критерий создания качественного продукта. Например, максимальная пропускная способность с длинными UDP-пакетами (MTU 1518) давно заслужила репутацию «бесполезного» теста — но виной тому лишь то, что эту цифру часто переносят на показатели собственной сети. На самом деле это искусственный показатель, необходимый разработчикам, чтобы проверить способность архитектуры, аппаратных компонентов и вспомогательных систем справляться с большими объёмами данных, которые нужно просто перебросить.
Противоположность — сверхкороткие пакеты (64 байта). Этот тест оценивает способность СЗИ справляться с прерывистой нагрузкой: вместо обработки большого объёма за один цикл, система вынуждена выполнять множество коротких циклов. Это быстро исчерпает память, если разработчик статично выделяет 9 КБ на пакет.
Наша платформа способна генерировать такой объём трафика, при котором большинство устройств работают на пределе своих возможностей. При этом все описанные испытания объединены в единый сценарий тестирования, который автоматически подготавливает СЗИ и запускает необходимые проверки.







Потери — ещё одна важная характеристика. В канале с потерями TCP-сессия ведёт себя иначе: логика расширения скользящего окна приводит к катастрофической деградации. Поэтому сценарии с потерями также должны быть исследованы.

Сценарий: «Вкалывают роботы, а не человек»
Мы не остановились на простой генерации трафика. Чтобы автоматизировать процесс полностью, мы добавили модуль управления СЗИ и платформу автоматизации процессов Camunda.
В наших экспериментах необходимо учитывать не только трафик, но и состояние СЗИ, которое конфигурируется в соответствии с политиками организаций. Поэтому архитектура была дополнена модулем управления СЗИ. Управлять как СЗИ, так и генераторами нам помогает Camunda — современная платформа с открытым исходным кодом для оркестрации бизнес-процессов и автоматизации рабочих процессов.
С её помощью можно разрабатывать комплексные интеграционные сценарии, где происходит синхронное управление и конфигурирование всех участников эксперимента. Сценарии составляются с помощью блок-схем: каждая схема отвечает за определённое действие — запуск генератора, настройка QoS-очередей, пауза и т.д. В них реализован полный цикл автоматической настройки всего окружения. А результаты отправляются на почту в виде готовых отчётов.
Итак, мы имеем общий сценарий управления в единой хронологии, объекты управления — осталось нажать кнопку. Кнопка у нас одна: в рамках функционирования сценария оператор генератора трафика не нужен. Нажимаем «Старт» — и система отрабатывает всё автоматически, от начала до конца.
Пример: автосценарий сравнения QoS


С помощью системы автоматизации сценариев тестирования Camunda и разработанной нами платформы генерации трафика на Kubernetes был создан готовый автосценарий для сравнения работы подсистемы QoS на различных этапах обработки трафика. Тест заключается в следующем: генерируются два UDP-потока с фиксированной пропускной способностью — один с низким приоритетом, другой с высоким. На первой итерации обработка потока выполняется на коммутаторе. На второй итерации QoS обрабатывается уже на уровне макета приложения (с использованием библиотеки DPDK). В результате сравнивается, какая из реализаций эффективнее справляется с приоритезацией трафика.

Хронология выполнения действий:
11:43:00 — подача двух потоков по 1 Гбит/с с разными классами обслуживания (коммутатор SNR + макет ПО)
11:43:15 — включение эмуляции «бутылочного горлышка»
11:43:30 — включение обработки PauseFrame на коммутаторе
11:44:00 — завершение первой группы заданий
11:44:30 — начало второй итерации (программная эмуляция QoS)
11:47:30 — завершение задания, очистка среды.
Разница очевидна. Мы на одном окне (рис. 14) можем увидеть поведение различных реализаций в идентичных условиях. И что самое важное, подобные сценарии могут быть многокомпонентными и содержащими фазы произвольной длительности. А имея библиотеку уже реализованных сценариев, возможности системы ограничиваются лишь фантазией оператора.
Если ты такой умный — покажи свои деньги графики
Важно уметь отслеживать статистику в реальном времени как с генераторов, так и с самих СЗИ, а также сохранять все эти данные, для анализа в будущем. Для выполнения данной задачи мы используем комплекс из следующих компонентов:

Telegraf — здесь название говорит само за себя, этот компонент собирает данные с работающих генераторов / СЗИ и пересылает их в БД.
InfluxDB — нереляционная СУБД, специализированная под хранение данных с временными метками.
Grafana — веб-приложение, позволяющие отображать данные из InfluxDB в виде различных графиков и диаграмм.
Метрики генераторов:
общие для всех генераторов параметры — пропускная способность, количество одновременных соединений, CPS, PPS
специализированные параметры для конкретного генератора, к примеру, для FTP — это может быть количество успешных скачиваний файлов, количество попыток установления data или control соединения.
Рабочие области в Grafana организованы в дашборды, на которых размещаются панели, отображающие ту или иную метрику в установленном виде. На панелях можно отмечать ключевые этапы (начало теста, изменение конфигурации, конец теста). Важно: InfluxDB и Grafana можно разместить вне стенда, собирая данные с нескольких площадок в одном месте.
Вывод
Мы столкнулись с тем, что функционал NGFW усложняется быстрее, чем мы успеваем тестировать новые версии. Покупка дорогих коммерческих генераторов часто нерентабельна и ограничена доступностью оборудования, поэтому мы решили закрыть этот вопрос самостоятельно.
Как показала практика, наличие своей платформы для тестирования критически важно для верификации сложного сетевого оборудования. Этот инструмент стал нашим главным помощником в поиске узких мест и проверке предельных режимов работы. Мы рекомендуем коллегам из других команд взять этот подход на вооружение: адаптируйте k8s под себя и делайте собственную тестовую площадку — это эффективное вложение для обеспечения качества вашей работы.

