Содержание статьи
- Основные понятия и схема работы
- Шпаргалка по хукам
- Селекторы
- Установка и настройка
- Основные локации Tetragon
- Особенности для контейнеров
- Просмотр событий в реальном времени
- Политики трассировки
- Блокировка в политике
- Написание исключений
- Сетевая политика трассировки
- Файловая политика трассировки
- Кулстори на хостинге
- Выводы
Tetragon основан на eBPF — это технология, встроенная в ядро Linux, которая позволяет безопасно и эффективно запускать мини‑программы прямо в ядре. Благодаря этому eBPF-инструменты, как правило, быстрее и потребляют меньше ресурсов, чем классические решения вроде закостенелого auditd.
Тот, кто хотя бы раз настраивал auditd для SOC, наверняка сталкивался с самыми разными, в том числе безумными, конфигурациями — например, очень популярный конфиг от Neo23x0 насчитывает более 800 строк. Попытки преодолеть ограничения и адаптироваться под конкретный дистрибутив и архитектуру — та еще морока.
info
Сразу оговоримся, что Falco и иные инструменты и подходы мы не рассматриваем, — это тема отдельной статьи.
Tetragon универсален и работает на множестве платформ, написан на Go, а еще «из коробки» приспособлен к работе с контейнерами. Но информации по нему (а особенно тому, как использовать его эффективно) крайне мало.
Давай вместе разбираться, как можно играться с Tetragon. Бонусом в конце статьи — реальная история о том, почему Tetragon местами лютый вин.
Основные понятия и схема работы
Начать придется с теории, но мы обойдемся без душных деталей. Итак, внутри у Tetragon технология eBPF. Изначально она была разработана для Linux, но, кстати, и в Microsoft сейчас тоже пилят свою реализацию.
Ядро Linux — это программный слой между приложениями и оборудованием, на котором они работают. Приложения живут в непривилегированном слое, называемом пользовательским пространством, оно не может получить доступ к оборудованию напрямую. Вместо этого приложение делает запросы, используя интерфейс системных вызовов, так называемые syscall, чтобы попросить ядро действовать от его имени.
Этот доступ к оборудованию может включать чтение и запись в файлы, отправку и получение сетевого трафика или даже просто доступ к памяти. Ядро также отвечает за координацию параллельных процессов, позволяя многим приложениям работать одновременно.

eBPF, или Extended Berkeley Packet Filter, — фреймворк, позволяющий пользователям загружать и запускать программы в ядре операционной системы.
А еще BPF — это виртуальная машина внутри Linux, которая выполняет код BPF в режиме ядра. После загрузки программа eBPF прикрепляется к целевой функции ядра, чтобы наш код запускался всякий раз, когда происходит ее вызов. Считай, что это некая прослойка‑надзиратель.
Так как это все работает на привилегированном уровне, нужна серьезная безопасность. Поэтому механизм eBPF включает верификатор, который гарантирует, что программа eBPF загружается только в том случае, если ее запуск безопасен. Детали можно посмотреть в документации.
Есть готовые библиотеки для написания своей утилиты с применением eBPF, но лишь на небольшом числе языков. Среди них — C, Go, Rust и Python. Выбор языка усложняется еще и тем, что не для всех языков есть либы, реализующие поддержку libbpf (популярный вариант для обеспечения переносимости программ eBPF между разными версиями ядра). Но мы с тобой не кодеры и будем использовать готовое решение, разработчики которого уже обо всем позаботились.

Давай разберем основные функциональные компоненты системы.
Политики трассировки (tracing policy) — это для нас основной инструмент работы. Они позволяют настраивать как реакции для мониторинга (логирования), так и активные действия (блокирование доступа, убийство процесса и прочее) на основе заданных критериев. Политики задаются в файлах YAML и складируются в каталог /
. В качестве критериев могут выступать названия сисколов, вызовы функций ядра, значения вызываемых аргументов. Можно добавлять кастомный текст, который добавится в алерт.
Чтобы составить собственную политику аудита, надо разбираться в принципах работы ядра Linux. Ключевые сущности, на которые можно навесить генерацию событий (или выполнение иных действий), следующие:
- LSM (Linux Security Modules) BPF, они же хуки безопасности SELinux/AppArmor. Для их использования необходимо выполнение ряда условий — модули должны быть загружены, включены и прочее. Названия функций можно взять из исходников Linux. Из преимуществ — возможность рассчитывать хеши для файлов и обогащать ими генерируемые события. Обычно в компаниях, где используются политики безопасности, с харденингом и так все неплохо, поэтому движемся дальше.
-
Kprobes (Kernel probes), или зонды ядра. По сути, дают возможность создания брейк‑пойнта перед вызовом инструкции ядра с выполнением произвольного кода. Например, можно заменить аргументы — кстати, не только входные. Но kprobes могут меняться между версиями ядра операционки, что сделает наши политики нестабильными. Чтобы вывести список доступных kprobes, выполни в терминале
cat /
. В политиках Tetragon для системных вызовов (syscall) рекомендуется использовать обобщенное название вызова, например вместо значенийproc/ kallsyms do_sys_open
,__x64_sys_open
или__ia32_sys_open
в политике можно указывать простоsys_open
. Tetragon умный, сам разберется и адаптируется под архитектуру, на которой работает. - Uprobes. В целом аналогичны kprobes, только применяются к программам в пространстве пользователя. Здесь работу с uprobes мы рассматривать не будем, поскольку хуки ядра и так дают нам достаточно возможностей для тонкой настройки политик.
- Tracepoints. Точки трассировки статически прописаны в ядре. Именно они считаются наиболее удачным вариантом для отслеживания и прикрепления своего кода для отладки. Основное преимущество перед зондами — стабильность между релизами.
Чтобы узнать доступные трейспойнты в своей системе, выполни такую команду:
cat /sys/kernel/debug/tracing/available_events
Вывод будет в формате «категория:имя»; последнее — как раз то, за что может уцепиться eBPF.
В некоторых системах ряд точек недоступен, проверить их список можно так:
cat /sys/kernel/debug/krpobes/blacklist
Из минусов трейспойнтов — они есть далеко не для всех функций ядра, и, если нужного нет, придется смотреть в сторону kprobes.
К чему в итоге лучше хукаться и как посмотреть все позиции данного меню? При выборе между названием syscall, функции ядра, kprobe и tracepoint предпочтительнее ориентироваться на трейспойнты, поскольку они имеют более стабильный интерфейс, чем элементы ядра. Функции ядра могут периодически меняться, что в долгосрочной перспективе может привести к проблемам. Если совсем лень разбираться, можно просто грепать в выводе утилиты bpftrace: bpftrace
— она покажет просто всё, за что можно зацепиться.
Мы в статье будем использовать микс на основе отдельных сисколов и функций ядра. Это обеспечит плавный переход от auditd (который сравнительно известен) к применению eBPF на основе kprobes и tracepoints.
Шпаргалка по хукам
Чтобы упростить себе и коллегам жизнь, мы составили таблицу по самым популярным или интересным активностям, которые обычно хотят видеть безопасники. В таблице мы свели имена отдельных сисколов, как их привыкли записывать в правилах auditd. Рядом указываем названия функций ядра, сопоставляемых с данными сисколов, — это уже можно пытаться использовать в eBPF-решениях, в том числе в Tetragon.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее