Проблемы анализа гигабитного трафика на обычном оборудовании
К вопросу об ограничениях стандартной архитектуры аппаратуры и системного программного обеспечения с точки зрения задачи обработки сетевого трафика на гигабитных скоростях в режиме реального времени.
Многие помнят времена, когда пропускная способность интернет-канала средней компании составляла единицы килобайт в секунду. С точки зрения обеспечения информационной безопасности это было замечательно - при желании можно было буквально глазами наблюдать внешнюю активность: сколько открыто активных соединений, от кого, и как давно. А при совсем большом желании можно было поглядеть на трафик заинтересовавшей сессии с помощью tcpdump.
Но ещё раньше два умника - Мур и Гилдер - отметили два тренда в области компьютерного железа, вроде бы независимых: первый показал, что производительность вычислителей, доступных за одну и ту же сумму, удваивается каждый год; второй заметил, что за то же время развитие технологий передачи данных увеличивают суммарную пропускную способность сетей в три раза. И вовсе не за счёт того, что в мире строят так много сетей ежегодно.
Для безопасника это означает довольно печальный факт: рано или поздно наступит момент, когда никакой современный вычислитель не сможет обработать самый быстрый канал передачи данных при его 100%-й загрузке. Вопрос только в том, насколько далеко мы сейчас от этого момента. Может быть, он уже пройден?
Рассмотрим типичный для начала 2009 года сетевой канал Ethernet с пропускной способностью 1 Гбит/с. Размер самого маленького кадра, который можно по нему передать, составляет 64 байта. Битовые потоки никто вроде бы не анализирует, поэтому будем мерять всё в кадрах, пакетах и соединениях. Так вот, наибольшее число кадров за секунду через канал пролезет как раз при минимальном размере кадра, и в этом случае их будет 1 488 095 штук. То есть, если мы хотим успевать обрабатывать гигабитный трафик в режиме реального времени, то на обработку единичного пакета у нас есть в худшем случае не более 672 наносекунд. Это довольно-таки мало. Скажем, для процессора с тактовой частотой 2ГГц это примерно 1338 тактов на всё, включая служебные операции процессора, выполнение кода ядра ОС и собственно анализ кадра в соответствующем приложении.
На типовых процессорах (Intel Xeon или AMD Opteron) одни только накладные расходы на системный вызов составляют от 170 до 540 наносекунд, в зависимости от типа операционной системы, и это без учёта собственно полезных действий, выполняемых операционной системой во время системного вызова. А последовательность мьютексовых операций lock/unlock может стоить ещё около 350 наносекунд. Реально выполнение одного системного вызова приложением на том же AMD Opteron 2ГГц потребует не менее 1000 наносекунд, включая неустранимые затраты на ввод-вывод (кэширование из памяти на процессоре).
Отсюда следует как минимум один важный вывод: если анализирующее трафик приложение выполняет хотя бы один системный вызов на каждый пакет, оно никогда не сможет даже просто получить все пакеты с канала, не говоря уже о том, чтобы проанализировать и выполнить какие-то осмысленные действия. Популярная библиотека захвата пакетов libpcap, например, делает по-умолчанию не меньше 2-х системных вызова на пакет - read() для копирования его в свой буфер и ioctl() для получения времени прихода пакета.


subject ;-)
кроме того, попытаться ускорить обработку данных можно с помощью custom hardware, например на FPGA, что часто позволяет добиться очень хороших результатов, несмотря на то, что это достаточно медленные элементы (http://ce.et.tudelft.nl/[…]/1370_564_RegExp_JVLSI_preprint.pdf).
Но для начала потребуется классификация задач, которые мы собираемся решать, и разложить их на конкретные операции