Всем привет!
Некоторое время назад ksdaemon пригласил меня в гости к подкасту SD podCast. Это получилось очень интересное путешествие по дебрям нашего проекта и были открыты уголки, про которые раньше даже никто не спрашивал :) Отличная демонстарция фразы — хочешь понять (свой же продукт!) сам — объясни другим.
Так как обычно аудитория Хабра все же предпочитает текстовые новости, мы решили выложить также и план беседы, который был подготовлен заранее. Он очень незначительно отличается от того, что прозвучало в беседе, но содержит всю-всю полезную информацию, которой мы хотели поделиться.
Для тех, кто не знакомы с продуктом для начала рекомендую изучить наш сайт и GitHub проект.
Текст беседы в подкасте Software Development podCast 58.
Пара слов о себе
Меня зовут Павел Одинцов, я автор проекта FastNetMon для обнаружения DDoS атак. Сейчас живу в Лондоне и занимаюсь преимущественно вопросами связанными с проектированием и программирование систем связанных с сетями.
Стандартный вопрос — как ты попал в айти? Как давно и чем занимаешься?
Попадание в ИТ вряд ли случайно, любовь к технике унаследовал от отца, внимание к деталям и умение сконцентрироваться на конкретном вопросе – от матери.
Детство мое прошло по большей части среди кип журналов Техника – Молодежи, Радио, где довольно часто описывалось, как своими силами собрать персональный компьютер. Это в те временами, разумеется, было за рамками моих возможностей, но интерес зародился уже и тогда и с появлением доступных по цене компьютеров (это был Celeron 266 c 32Mb RAM) наконец-то появилась возможность выйти за рамки чтения журналов и попробовать все на практике!
А дальше последовали годы чтения различных книжек, журналов (в основном – Мир ПК, иногда – Хакер), сидения в IRC чатах (привет Руснет и ДалНет!) и изучения технической документации в интернете, который по тем временам у меня был лишь на даче и на скорости 33к.
Через какое-то время в моем городе, Самаре, появился доступный GPRS и Спутниковые провайдеры интернета и, пожалуй, с этого момента было положено начало моей профессиональной практике. Все началось с того, что знакомый по ICQ попросил написать простенький скрипт на Perl, который я тогда как раз учил. Заодно с этим проектом пришло понимание, что разрабатывать на Windows довольно тяжко и принято решение перейти на Linux.
Со временем, хобби превратилось в довольно уверенное знание как Perl, так и Linux и я устроился на работу в Доменный Регистратор
Пара слов о том, что это за атаки, какие подтипы бывают, как обычно происходит атака, как оно устроено и зачем нужно
Раз уже основная тема подкаста проект FastNetMon, то говорить я буду именно в его контексте. DoS/DDoS атак имеется огромное множество и мы не ставим перед собой задачу защищать пользователя от всех его типов.
В первую очередь, мы сконцентрированы на атаках volumetric, осуществляемыми по протоколам L3/L4.
Эти атаки нацелены на исчерпание емкостей каналов либо производительности оборудования с целью прерывания корректного функционирования того или иного сервиса.
Нередко, это атака на какой-либо определенный сайт, также бывают случаи, когда идет атака на инфраструктуру определенного оператора либо компании в целом – это намного опаснее.
Если говорить о текущих типах атак, то основные их типа используемые для атак на емкости канала – это NTP, SSDP, SNMP, DNS-амплификации. Суть их довольно простая, они используют промежуточный узел находящийся под управлением хакера, который в свою очередь шлет подложные запросы используя адрес жертвы вместо своего собственного на тысячи (иногда сотни тысяч) узлов интернета, которые имеют на себе сервис уязвимый к данному типу атаки. После приема этих запросов эти (часто вполне легитимные) сервисы генерируют ответ и отвечают огромным шквалом запросов на указанный узел жертвы, выводя его из строя.
В дополнение к этим атакам стоит отметить атаки, которые используют спуфинг, они часто осуществляются либо используя некорректно настроенное оборудование хостинг-провайдеров и Дата Центров либо специальные хостинги, которые предоставляют эту услугу на черном рынке. С ними бороться сложнее, они могут быть очень изощренными.
Какие есть способы борьбы с такими атаками? Возможные варианты решений
Типичный сценарий борьбы с данными атаками на исчерпание канала довольно печальный. Обычно, с ними сталкивается не сам владелец сайта,
Если в компании нет средств обеспечивающий прозрачный мониторинг трафика, то первые шаги будут сродни панике, когда все лежит и не понятно, что произошло.
Обычно, после этого следует попытка захвата шаблонов трафика с роутеров, серверов, свитчей посредством обычно tcpdump либо встроенных решений от конкретного вендора.
Почти всегда по дампу очевидно, что идет атака на определённый IP адрес в сети и зачастую можно выявить определенную закономерность (например, что атака идет UDP пакетами с 53-го порта – яркий маркер DNS амплификации).
После этого, обычно осуществляется BGP Blackhole анонс узла, на который идет атака дабы отсечь паразитный трафик на уровне вышестоящего оператора. При этом, если сеть компании достаточно велика и имеет большой запас емкости и современное оборудование поддерживающее BGP Flow Spec, то имеется возможность не блокировать узел целиком, а отсечь именно паразитный трафик и сохранить функционирование сервиса.
Одним из возможных вариантов защиты от подобных атак является использования «центров фильтрации трафика», но их использование сопряжено с рядом проблем, в частности – по-прежнему требуется кому-то принять решение, какой трафик и когда передать в центр фильтрации.
FastNetMon как раз имеет своей целью полную автоматизацию всех шагов от выявления факта атаки, определения ее типа и развертывания контрмер. Обычно, у него на это уходит не более 5-секунд без вмешательства человека вовсе. Разумеется, мы также поддерживаем вариант, когда клиент использует центры фильтрации трафика для защиты, FastNetMon может использовать для переключения трафика на центр фильтрации в случае атаки.
Как появилась идея написать?
Идея родилась во время, когда я работал в Хостинг-индустрии, потому что задачи описанные в предыдущем параграфе мне приходилось решать десятки, а может и сотни раз вручную, каждый раз определяя тип атаки и вручную отбивая эту самую атаку.
Какие были до этого реализации/альтернативы?
Будучи ведущим инженером в мои задачи входило не столько написание решения, сколько поиск решения, которое подходило бы под задачу и вписывалось в бюджет.
Перебрано было очень много решений, но основным фактором этих решений была цена – она была совершенно неподъемная и превосходила стоимость всего парка сетевого оборудования в десятки раз, что делало их внедрение совершенно неоправданным.
Как до этого решались вопросы защиты от DDoS?
Вручную, по звонку телефона дежурному администратору ночью :)
Принцип работы системы
Ключевой принцип, на котором базируется FNM – это понятие порогового значения трафика. Порог – это величина трафика исходящего либо приходящего на узел в нашей сети (в мегабитах, потоках-секунду либо пакетах-в-секунду), после которой трафик считается аномальным и представляет угрозу для работы сети. В каждом случае – это различные значения, часто – также различные значения для различных узлов в одной сети.
После достижения этого порога выполняется либо безусловная блокировка узла либо осуществляется захват всего трафика данного узла и его анализ с целью определения цели атаки и определение параметров паразитных пакетов.
Внутреннее устройство
Внутри FastNetMon представляет собой конвейер, на вход которого принимается трафик в почти любом формате.
Сейчас мы поддерживаем:
- sFlow v4
- sFlow v5
- Netflow v5
- Netflow v9
- IPFIX
- SPAN
- Mirror
- PF_RING
- Netmap
- SnabbSwitch
После этого из вендор-специфичных форматов трафик конвертируется во внутреннее универсальное представление.
После этого, на каждый узел в сети создается множество счетчиков с детализацией по протоколу (TCP, UDP, ICMP), с детализацией по флагам (например, TCP SYN) или по опциям IP (наличие фрагментации) и отдельный следящий подпроцесс фиксирует, как только скорость определенного счетчика трафика в единицу времени превысила заданный пользователем порог.
А вот после этого начинается немного магии, в которую вовлечены статистические методы, DPI, чтобы установить тип атаки и выбрать наиболее подходящие меры по противодействию.
И, наконец, осуществляется либо вызов скрипта либо генерация BGP анонса с целью заблокировать либо весь трафик целиком либо только паразитный – силами BGP Flow Spec.
Внешний API
По большей части, он отсутствует в привычном понимании API.
FastNetMon умеет экспортировать информацию в Graphite, InfluxDB, чтобы визуализировать трафик.
Для приема информации мы используем довольно четко стандартизованные протоколы, такие как sFlow, IPFIX и NetFlow и если вендор реализует их корректно – мы автоматически гарантируем поддержку со своей стороны.
Система плагинов
Она родилась сама собой, когда пришло понимание, что мир – он очень сложный и одним протоколом (в то время это был захват трафика с миррор/зеркального интерфейса) не обойтись, после этого мы стали добавлять новые протоколы – sFlow, Netflow и когда дошло до добавления четвертого мы провели серьезный рефакторинг и торжественно изолировали каждый модуль захвата трафика в отдельную библиотеку с фиксированным внешним API. Теперь любой может довольно легко разработать плагин реализующий его собственный, особенный способ съема телеметрии трафика.
Документация
Это больной вопрос, на самом деле. Почти уверен – что для многих open source проектов – тоже. Обычно, на документацию нет времени, но мы стараемся очень внимательно рассматривать все запросы на GitHub и рассылке, чтобы дать максимально подробные ответы, на которые ссылаемся в будущем. Целостной документации описывающей каждый этап в работе проекта, к сожалению, нету.
Тестирование
За годы жизни проекта мы накопили очень большое количество pcap дампов для почти сотен различных моделей устройств. Мы используем их в нашей внутренней системе тестирования при внесении изменения в парсеры.
К сожалению, эти дампы почти всегда содержат конфиденциальную информацию клиентов и раскрытие их в виде open source невозможно, мы очень внимательно относимся к хранению этой информации и доступ к ней очень тщательно контролируется.
Кроме того, для критичных и сложных по своей сути протоколов (BGP Flow Spec, например) у нас имеются unit тесты.
Адаптация для работы на разных платформах
Сейчас мы поддерживаем почти любой дистрибутив Linux, имеем официальный порт в FreeBSD, в состоянии добавления в официальную пакетную базу Debian. Какое-то время назад добавили поддержку для MacOS просто потому что захотелось поиграться на своем ноутбке :)
Мы пишем код в максимально переносимом формате используя доступные API для платформ и, например, для портирования на FreeBSD потребовалось поменять буквально 4 функции (использовались иные имена констант).
Основная проблема – очень широкий спектр поддерживаемых дистрибутивов и частое отсутствие нужной версии библиотеки в репозитории. Сейчас решается не сильно красиво – на каждой платформе зависимости собираются из исходного кода в момент установки. Нам это не нравится, но, увы, сборка бинарных проектов под почти 20 поддерживаемых дистрибутивов – задача для нас неподъемная. Мы пытались, но довольно быстро сдались — получается крайне сложная система.
На каких технологиях построена (языки, фреймворки, модули) и почему были выбраны именно они?
Основной язык проекта C++. Очень активно используем STL и Boost, где STL не предоставляет решений. У нас не сильно много внешних зависимостей именно в коде в связи со спецификой проекта и малым числом имеющихся наработок в открытом виде, только самое необходимое либо коннекторы к базам-данным.
Но мы активно используем внешние проекты – такие как ExaBGP, InfluxDB, Graphite, Grafana, GoBGP для обеспечения визуализации трафика либо взаимодействия со внешним миром.
Одним из основных критериев, почему мы выбираем тот или иной проект для интеграции – наличие API и дружественность к разработчикам.
Например, такие проекты работы с BGP как Quagga, Bird предоставляют очень скудные возможности по интеграции, поэтому несмотря на популярность они нам не подошли.
Что можешь сказать об отказоустойчивости, масштабировании и производительности системы? Благодаря чему решаются эти вопросы?
В основном вопросы высокой доступности решаются на уровне архитектуры, так как протокол BGP по своей сути является очень хорошо резервированным и с этой стороны нам не приходится прилагать никаких усилий. Обычно, FastNetMon анонсирует узлы под атакой по крайне мере на два независимых роутера имеющихся в сети.
Чтобы обеспечить отказоустойчивость FastNetMon, обычно можно просто продублировать трафик сети на второй инстанс (обычно, роутеры и свитчи поддерживают такое, кроме этого – всегда можно использоваться samplicator) и тем самым обеспечить отказоустойчивость – если один инстанс будет потерян, второй выполнит задачу и заблокирует трафик.
По поводу масштабирования по нагрузке, у нас есть подтвержденный опыт внедрения на сети с почти 1.4Tb трафика, такие цифры были достигнуты на базе NetFlow v9 коллектора и при этом оставалось еще множество возможностей для увеличения пропускной способности.
Если же этого не хватит – всегда можно разделить трафик по какому-либо признаку и установить дополнительные инстансы FastNetMon.
Почему open source?
Проект был открытым с самых первых шагов, у нас нету момента, когда сотни тысяч строк кода были загружены одним коммитом – можно проследить эволюцию с самого начала!
Но вообще вопроса при создании не стояло, была цель создать проект, которые решит проблему не только в конкретном случае конкретного провайдера, а решит ее в обобщенном виде, без ухода в детали.
Поэтому путь был один – открытый код! Иначе бы вышло узко- специализированное решение решающее одну очень-маленькую задачу в конкретной сфере.
Какие ты видишь преимущества в публикации проекта в open-source?
Безусловно – это огромный impact. Когда видишь, что твое решение используют в 103 странах включая Кубу – это воодушевляет :)
В чем отличие open-source проектов и закрытых коммерческих разработок?
Бывают «закрытые» open-source проекты и бывают очень «открытые» коммерческие проекты с закрытым кодом.
Тут важно не столько открытость кода, сколько философия проекта – чтобы она тоже была открытой, к изменениям, улучшениям.
Для многих открытый код – гарантия уверенности в завтрашнем дне, что новое руководство компании-производителя не поменяет политики лицензирования, что компания не разорится и если же поддержка не поможет – всегда можно разобраться самому либо найти специалиста, кто улучшит это.
Учитывая большое количество скандалов на тему шпионского ПО – открытый код выглядит еще более привлекательно. Всегда заверения в безопасности можно подтвердить ссылкой на код и возможностью независимой верификации.
Сообщество вокруг проекта, как проект живет и развивается. Насколько много контрибьюта со стороны? Запросы на новые фичи и баги.
Основной контрибьют в проект идет по нескольким направлениям:
- Интеграция с различными вендорами (A-10 Network, Radware,
- Mikrotik).
- Запросы нового функционала от имеющихся пользователей с
- детальными описаниям их кейсов использования – это очень важная
- информация для развития проекта
- Тестирование на всем возможном многообразии сетевых устройств
- и программного обеспечения к ним
- Интеграция в различные дистрибутивы (AltLinux, FreeBSD, Debian)
- Непосредственного контрибута в ядро проекта (непосредственно модули обнаружения атак и аналитики), к сожалению, довольно мало и основная часть разработки в этом направлении идет собственными силами.
Планы по дальнейшему развитию проекта
Основная цель – ускорить развитие проекта и привлечь больше разработчиков к разработке непосредственно ядра системы.
Сейчас атакующая сторона движется очень быстро и довольно сложно поспевать за разработкой мер противодействия новым угрозам, но мы стараемся.
Как часть реализации этого плана – несколько месяцев назад мы выпустили коммерческую версию FastNetMon Advanced, в которой реализован ряд преимуществ критичных для крупных компаний и крупных сетей класса TIER-2 и выше. В основном они касаются упрощенного развертывания, эксплуатации и более гибкого управлению в больших сетях. Основное ядро проекта при этом используется в обоих продуктах одно и тоже.
Как разработать правильную архитектуру, которая позволила бы расширять проект в дальнейшем, не меняя кардинально и не переписывая бОльшую часть кода? :)
Когда видишь много запросов нового функционала от клиентов, просто буквально чешутся руки схватиться и реализовать! На первых этапах жизни проекта – это стоит делать именно так! Когда не ясно – нужен кому- либо проект и ищется его «ниша».
Но потом – стоит время от времени останавливаться и задать себе вопрос «а как это сделать универсально?», «а кому это еще потребуется?». Часто помогает небольшая заморозка запроса на несколько недель, чтобы обдумать требуемые изменения в архитектуре и убедиться, что идея верная – и лишь после этого приступать к ее разработке.
Кроме того, стоит время от времени останавливаться и просто внимательно просматривать код той или иной подсистемы в поисках места, которое можно унифицировать или улучшить.
Также если появилось чувство, что некоторая подсистема превысила все возможные границы сложности (в нашем случае так было с BGP Flow Spec), то стоит подумать о подробнейшем покрытии ее юнит тестами, так как тщательной вычитки уже недостаточно.
Насколько важно продумывать архитектуру изначально, и как следовать ей в дальнейшем, развивая проект, но при этом не уводя его в сторону монструозности и костылезации? :)
У нас не было архитектуры изначально – лишь смутные цели, чего мы хотим добиться. На первых шагах не было ясно даже что проект будет работать и сможет справляться с нагрузкой в десятки миллионов пакетов- секунду! Это было очень много и по началу мы не могли отработать и 120 000 пакетов в секунду!
Поэтому как я уже говорил ранее, стоит время от времени останавливаться и думать о возможностях разделения системы на модули.
Насколько важна документация и тестирование
Как любят говорить многие, для опенсорс проекта лучшая документация – это код. Я в корне не согласен, так как за всю историю проекта лишь единицы внимательно разобрались в коде и ответили на своим вопросы таким образом.
Но всегда недостаток документации можно заменить отзывчивым сообществом и оперативной реакцией разработчиков. Мы можем похвастаться и тем и другим! Часто вопросы решаются задолго до того, как я добираюсь до заданного тикета – кто-то из членов сообществ решил ответить и помог решить проблему без участия разработчиков вовсе :)
По поводу тестирования – на мой взгляд, нужно соблюдать баланс. Покрывать тестами очевидные вещи – совершенно бессмысленно, это пустая трата времени, которое можно потратить с пользой. Но если сложность какой-то системы очень высокая либо высока опасность сбоя при взаимодействии с внешними системами – тесты совершенно необходимы.
Всякие социальные аспекты open-source разработки: неправильные PR, глупые вопросы и ошибки
У нас есть классный социальный аспект, что часто мы просим помощи наших пользователей, чтобы тот или иной вендор решил свои проблемы.
Модель работы многих вендоров сетевого оборудования на тему исправления багов такова, что внешняя компания не имеющая контракта/оборудования в использовании просто не имеет возможности завести баг об его исправлении.
В итоге мы получаем десятки багов «FastNetMon не работает с устройством XXX вендора YYY», сначала мы извинялись, что проблема у вендора и поделать ничего не можем.
Сейчас – мы помогаем максимально детально исследовать и изолировать проблему и после этого просим клиента от своего имени создать запрос на исправление бага – и это помогает! Очень многие идут навстречу и тем самым решают проблему очень многих пользователей того же самого вендора!
Автор: Павел Одинцов