Falco — проект CNCF для обнаружения аномалий в работающей системе. Он не сканирует образы, а перехватывает системные вызовы ядра и проверяет их по набору правил. В контейнерах это особенно полезно: образ может быть чистым, но внутри пода внезапно запускается оболочка или читается /etc/shadow. Ниже — установка в Kubernetes, разбор правил, исключения для ложных срабатываний и диагностика типовых сбоев.

Как Falco получает события

Источников событий три. Драйвер ядра, он же kmod, требует заголовков установленного ядра. eBPF-проба работает через bpf() и не собирает модуль, но привязана к версии ядра. Третий вариант, modern_ebpf, использует CO-RE и BTF и переносится между ядрами без пересборки. В Kubernetes выбирают именно его: ядра 5.8 и новее поддерживаются, а обновление узла не ломает загрузку.

Falco работает в режиме обнаружения: он фиксирует событие, но не блокирует процесс. Блокировка — задача admission-контроллеров, seccomp и AppArmor, и это стоит проговорить со службой безопасности заранее. Зато обнаружение не вмешивается в работу приложения и не может уронить прод.

Установка в Kubernetes

Официальный Helm-чарт создаёт DaemonSet, сервисный аккаунт, RBAC и falcoctl для обновления правил. Минимальные значения: modern_ebpf, tty=true и tolerations, чтобы поды попали на системные узлы.

В managed-кластерах с запретом привилегированных подов драйвер не загрузится. Там нужны плагины: они читают журнал аудита Kubernetes и не требуют доступа к ядру.

helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm upgrade --install falco falcosecurity/falco \
  --namespace falco --create-namespace \
  --set driver.kind=modern_ebpf --set tty=true
kubectl -n falco get pods -o wide

Проверка движка и правил

Убедитесь, что поды в Running, а в логах нет ошибок загрузки драйвера. Команда falco —list=syscall печатает доступные события и поля; пустой вывод означает, что драйвер не инициализировался.

Затем проверьте правила: falco -L выводит активные правила с приоритетами. Если список короче ожидаемого, часть файлов не прочиталась или перекрыта более поздним определением.

kubectl -n falco logs ds/falco --tail=80
kubectl -n falco exec ds/falco -- falco --version
kubectl -n falco exec ds/falco -- falco --list=syscall | head
kubectl -n falco exec ds/falco -- falco -L | wc -l

Анатомия правила

Правило — YAML-объект с условием на языке фильтров Sysdig. Условие собирается из макросов и списков: макрос заменяет фрагмент выражения, список — перечисление значений. Так не приходится дублировать длинные наборы путей и имён процессов.

Поля делятся на группы: evt.* описывает событие, proc.* — процесс, fd.* — дескриптор, container.* и k8s.* — окружение. Условие вычисляется для каждого события, поэтому тяжёлые проверки выносят в начало цепочки.

- rule: Оболочка в контейнере с терминалом
  desc: Интерактивный shell внутри пода
  condition: >
    spawned_process and container and shell_procs
    and proc.tty != 0
  output: >
    shell=%proc.name pod=%k8s.pod.name ns=%k8s.ns.name
    image=%container.image.repository cmd=%proc.cmdline
  priority: WARNING
  tags: [container, shell, mitre_execution]

В output подставляются поля в формате %field. Чем их больше, тем полезнее событие, но тем тяжелее логи. Приоритеты идут от EMERGENCY до DEBUG; на практике рабочий диапазон начинается с WARNING.

Продолжение того же правила с исключением выглядит так:

  exceptions:
    - name: debug_pods
      fields: [k8s.ns.name, k8s.pod.name]
      comps: [=, =]
      values:
        - [debug, troubleshooting]

Свои правила и обновление

Файлы пользователя кладут в /etc/falco/rules.d/, чарт монтирует каталог из ConfigMap. Файлы читаются по алфавиту, поэтому числовой префикс задаёт порядок. После правки под перезапускают: не все сборки умеют перечитывать правила на лету.

Наборы правил удобнее ставить через falcoctl: он тянет OCI-артефакт falco-rules, проверяет подпись и раскладывает файлы.

falcoctl artifact install falco-rules
falcoctl artifact info falco-rules
kubectl -n falco create configmap falco-local \
  --from-file=custom_rules.yaml
kubectl -n falco rollout restart ds/falco

Ложные срабатывания

Шум — главная причина, по которой Falco отключают через месяц. Сначала соберите статистику: какие правила срабатывают чаще всего и в каких пространствах имён. Потом добавьте исключения: они не выключают правило, а вырезают известные комбинации полей.

Для правки чужого правила используйте override с append: так вы не копируете условие целиком и не теряете обновления из upstream.

- rule: Terminal shell in container
  override:
    exceptions: append
  exceptions:
    - name: ci_runners
      fields: [k8s.ns.name]
      comps: [=]
      values:
        - [ci]

Куда отправлять события

По умолчанию события идут в stdout в читаемом виде. В кластере это неудобно: лог пода быстро уходит в ротацию. Включите JSON и отправьте события через falcosidekick — он умеет Slack, Elasticsearch, Loki, Kafka и webhook.

Если внешние сервисы запрещены, пишите в файл на узле или в syslog. gRPC-порт наружу не открывайте: встроенной аутентификации у него нет.

helm upgrade --install falco falcosecurity/falco \
  --set falcosidekick.enabled=true \
  --set falcosidekick.config.loki.hostport=http://loki:3100 \
  --set falcosidekick.config.slack.webhookurl=... \
  --set falcosidekick.webui.enabled=false

Диагностика

Типовые сбои: CrashLoopBackOff из-за отсутствия BTF, пустой поток событий из-за фильтра по пространству имён, задержки из-за переполнения кольцевого буфера. Для метрик включите webserver на порту 8765.

  • проверьте версию ядра и наличие /sys/kernel/btf/vmlinux;
  • сравните число событий до и после фильтра namespace;
  • посмотрите, не растёт ли счётчик потерь;
  • убедитесь, что правила не перекрыты более поздним файлом.
POD=$(kubectl -n falco get pod -l app.kubernetes.io/name=falco -o jsonpath='{.items[0].metadata.name}')
kubectl -n falco port-forward pod/$POD 8765:8765
curl -s localhost:8765/metrics | grep -iE 'event|drop'
kubectl -n falco logs ds/falco | grep -iE 'btf|driver'

Чек-лист внедрения

  • драйвер проверен на всех типах узлов;
  • настроен JSON и внешний приёмник;
  • правила версионируются в git;
  • есть исключения для CI и отладки;
  • настроены алерты на потери событий;
  • раз в квартал пересматривается шум.

Итог

Falco закрывает разрыв между сканированием образов и реальным поведением контейнера. Он не заменяет seccomp и сетевые политики, но даёт раннее предупреждение там, где статические проверки бессильны.

Начните с одного пространства имён и соберите статистику за неделю. Такой порядок снижает риск, что через месяц систему отключат из-за шума. Правила стоит пересматривать вместе с изменениями в приложении.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте