За последние пару десяток лет IT-индустрия сделала огромный прорыв в своем развитии – появилось очень много новых технологий, сервисов, языков программирования и т.д. Но самое важное – количество пользователей IT-технологий выросло до гигантских масштабов. Особенно заметно это стало на объемах трафика – такие крупные сервисы как Google, Facebook, Twitter обрабатывают петабайты трафика. При этом всем известно о том, какие они имеют датацентры. Однако я не собираюсь сейчас говорить об облачных технологиях и NoSQL-решениях. Я бы хотел посмотреть на всю эту ситуацию немножко с другой стороны, а именно с точки зрения безопасности.
Представим, что у вас есть датацентр, в который заведен толстенный провод с трафиком. Как вы думаете, насколько безопасен трафик, который к вам идет? Я бы не был слишком наивным и сказал бы – ни на сколько. В интернете чересчур много статей про то, как делать вирусы, сетевых червей, DoS, DDoS, количество скрипт-киддисов сейчас просто зашкаливает, а возможность найма профессиональных взломщиков никого не удивляет.
В этот момент вы начинаете думать о том, как себя обезопасить от всего этого ужаса, и бравые ребята из какого-нибудь IT-консалтинга вам говорят: поставьте систему обнаружения вторжений, межсетевой экран, IPS и антивирусы везде и всюду. На резонный вопрос «А сколько нам этих штук надо?», вам называют цифры 10/20/100/500 в зависимости от толщины вашего провода с трафиком.
И вот тут-то возникает вопрос, о котором бы я и хотел поговорить: как распараллелить обработку трафика в целях его защиты? Вопрос этот очень важный по нескольким причинам:
1. Безопасность является составной частью фундамента, на котором должна базироваться ваша система/сервис/что-угодно.
2. Механизмы безопасности являются очень ресурсоемкими (вспоминаем Касперского на домашнем компьютере).
3. Механизмы безопасности практически никак не ускорить с помощью таких вещей как кеширование, предсказание выполнения и т.п.
С одной стороны для того, чтобы сделать нашу жизнь лучше, мы можем придумывать новые способы повышения производительности самих средств защиты. С другой стороны мы можем немного покреативить и оставить средства защиты как есть, а вместо их улучшения придумать способ организации распределенной обработки трафика средствами защиты.
В этот момент особо нетерпеливые люди начинают предлагать поставить нечто вроде F5 Big-IP, который будет распределять трафик на сервера с Checkpoint Security Gateway, а мы будем радоваться жизни. В принципе неплохое решение, но оно перестает работать, когда:
• вы хотите легко и непринужденно переконфигурировать настройки средств защиты (изменить правила межсетевого экрана, добавить IP-адреса в VPN и пр.);
• вы хотите незаметно добавить еще один экземпляр средства защиты;
• у вас падает один или, что еще хуже, сразу несколько экземпляров средств защиты.
Плюс к этому вы еще ограничены существующими вариантами средств защиты, потому что если вы захотите написать свое, то вы … ну … просто запаритесь.
Но не надо бояться, мы вам поможем! У нас в компании стоит классная штука под названием Crossbeam. И не просто стоит, а еще и активно нами эксплуатируется под разработку и портирование своих средств защиты. Расскажу вкратце, что же это такое.
Crossbeam – это платформа, заточенная под сквозную обработку трафика средствами защиты. Она предоставляет:
• мощную аппаратную конфигурацию;
• механизмы по распределению и балансировке трафика;
• средства для разработки своих собственных приложений.
Платформа состоит из следующих компонентов:
1. Аппаратное обеспечение
1) Шасси
2) Блоки питания и вентиляции
3) Модули:
i. Сетевые (NPM – network processing module)
ii. Приложений (APM – application processing module)
iii. Управления (CPM – control processing module)
2. Программное обеспечение
1) Операционная системы XOS
2) Виртуальные процессоры приложений – VAP (Virtual Application Processor)
3) Приложения
Процесс обработки трафика можно представить следующим образом:
Входящий трафик прилетает в порт сетевого модуля (NPM), который осуществляет его распределение по модулям приложений (APM). Вкратце это делается так:
1. NPM разбирает заголовок IP-пакета.
2. из заголовка извлекаются следующие данные:
a. IP-адрес источника
b. IP-адрес назначения
c. TCP-порт источника
d. TCP-порт назначения
и формируются в кортеж. Все пакеты, у которых такие кортежи одинаковые называются потоком трафика.
3. по полученному кортежу выполняется поиск в т.н. таблице активных сетевых потоков (AFT – active flow table). Результат поиска – это номер APM, предназначенный для обработки трафика.
4. если поиск был успешен, то пакет отправляется на соответствующий APM.
5. если поиск не был успешен, то NPM обращается к CPM, который хранит конфигурацию всей платформы, за тем, чтобы он добавил новую запись в AFT.
Такой алгоритм позволяет решить озвученный вначале вопрос: как распараллелить обработку трафика в целях его защиты. При этом, заметьте, такой метод распределения трафика достаточно избирателен для того, чтобы балансировать нагрузку, но в то же время он не допускает раздербанивания сессий пользователя по нескольким вычислительным узлам.
К тому же средства платформы позволяют нам:
• легко и непринужденно переконфигурировать настройки средства защиты, т.к. это делается один раз в одном месте и применяется для всех экземпляров;
• в случае падения одного или нескольких экземпляров средств защиты автоматически перераспределять нагрузку на другие экземпляры средств защиты (APM).
В общем, очень интересная железка с хорошим функционалом.
Когда она к нам попала, то мы решили, что негоже такой штуке простаивать впустую и разработали специально под неё криптографический шлюз. В нашем понимании это такая программа, которая ставится перед нашим датацентром и:
• производит расшифрование пакетов для трафика, идущего в датацентр, тем самым разгружая сервера от ресурсоемких вычислений
• производит зашифрование пакетов для трафика, идущего из датацентра, тем самым обеспечивая безопасную передачу информации до клиентов
Для ясности приведу схему
Этот шлюз делает следующее:
• распределяет входящие пакеты трафика по APM;
• зашифровывает содержимое каждого пакета по алгоритму ГОСТ 28147-89;
• отправляет пакет туда, куда он шел;
• для пакетов, идущих в обратную сторону, производит то же самое, только рашифровывая содержимое.
При этом для каждого клиента (по сути, для каждого IP-адреса) должен быть свой собственный ключ.
Разработку мы начинали на обычном CentOS, потому что то, что крутится на APM – это ни что иное как урезанный и патченный RHEL. Написав и отладив наш криптошлюз под CentOS мы начали перенос на Crossbeam. Имея в распоряжении SDK, документацию и связь с разработчиками самого Crossbeam мы затратили на это где-то с полгода. Суть переноса заключается в том, чтобы написать к приложению интерфейс общения с платформой и учесть возможности по перераспределению трафика.
Первая проблема, с которой мы столкнулись – это отладка. На APM нет gdb, следовательно как отлаживать мы сначала и не знали. Но крепко подумав и внимательно посмотрев на APMы мы увидел COM-порт. Дальше решение пришло довольно быстро – удаленная отладка через COM-порт. Выставили параметры ядра для Linux-образа APM, включили в proc отладку через kdb – заработало. Кстати, про отладку можно почитать у наших коллег (http://habrahabr.ru/company/neobit/blog/141067)
Вторая проблема была в равномерном распределении нагрузки по процессорным ядрам. Изначально криптошлюз представлял собой модуль ядра, который ставил хук в подсистеме netfilter. Когда мы начали посылать трафик, то увидели, что из 16 доступных на APM ядер одно загружено на 99%, а остальные простаивают. При этом потери пакетов были просто нещадные. Связано это было вот с чем. Вызов обработчика netfilter-хуков в ядре Linux выполняется через программные прерывания сетевого интерфейса. Можете посмотреть в /proc/interrupts, чтобы посмотреть так ли это для вашей системы.
Существует 2 варианта решения данной проблемы:
1. Настройка параметра ядра SMP_AFFINITY.
2. Пересборка ядра Linux с параметром CONFIG_HOTPLUG_CPU (начиная с версии ядра 2.6.24.3).
В первом случае в файл /proc/irq/<номер прерывания>/smp_affinity производится запись битовой маски, в которой единицы соответствуют ядрам, участвующим в обработке данного прерывания. Однако в большинстве случаев данное решение позволяет только перераспределить нагрузку с одного ядра на другое. Т.е. при записи в smp_affinity маски 4 (000100) обработка прерываний производится на третьем ядре. Однако при записи маски 7 (000111) обработка прерываний производится только на первом ядре. Таким образом, данное решение применимо лишь для весьма ограниченного набора аппаратного обеспечения. Второй вариант является более универсальным, однако не всегда применим – многие производители сильно модифицируют ядро Linux для своего аппаратного обеспечения, не предоставляя исходные тексты для возможности пересборки. И Crossbeam в их числе. Пришлось применять немного тайных знаний от разработчиков Crossbeam– написали заточенный под Crossbeam драйвер, который выполнял первоначальную обработку трафика еще до того, как пакет попадал в ядро Linux.
В итоге нам удалось достичь производительности, которая нас самих очень сильно удивила – потоковое шифрование по ГОСТ 28147-89 на скорости 0.95 Гбит/с. На одном APM. А достигается это за счет нескольких вещей: во-первых, распараллеливанием обработки сетевого трафика, во-вторых, распределением нагрузки по ядрам, и в-третьих – за счет мощной аппаратной платформы.
Если вспомнить про возможности распараллеливания трафика, то можно сказать, что скорость шифрования растет практически линейно с прибавлением APM. То есть, если запускать приложение на нашей максимальной конфигурации в 3 APM, то можно шифровать со скоростью почти 3 Гбит/с. Если вы богаты, то можете купить самую крутую модель и делать до 10 Гбит/с. Неплохо, да?
Кстати, эти цифры получены экспериментальным путем, а не теоретическим, как это делают большинство производителей. Мы собрали стенд, который генерировал нагрузку в 5 Гбит/с. В качестве HTTP-сервера, для которого мы расшифровывали пакеты, взяли nginx, покрутили его настройки, настройки сетевого стека Linux, и заставили nginx отдавать HTML-статику со скоростью 5 Гбит/с.
Подводя итоги, хотелось бы сделать следующие выводы. Распараллеливание обработки трафика – очень эффективный подход к преодолению узких мест, однако применять этот подход для средств защиты начали совсем недавно, а для алгоритма ГОСТ мы стали одними из первых. Наша идея заключалась в распараллеливании потоков трафика совместно с шифрованием сетевых соединений в отдельных потоках и распределении вычислений по большому числу ядер на нескольких независимых вычислительных модулях. Естественно, сам процесс отделения функций безопасности от логики работы прикладной системы был нетривиален, но наши усилия полностью оправдались, о чем свидетельствуют полученные цифры.
Автор: NWOcs