Выберите продукт

Kubernetes Audit Policy: настройка audit log API, webhook backend и ретеншн без лишнего шума

Разбираем Kubernetes audit log на практике: как собрать audit policy под задачи безопасности, включить аудит флагами kube-apiserver, выбрать файл или webhook backend, снизить шум omitStages и продумать retention для incident response.
Kubernetes Audit Policy: настройка audit log API, webhook backend и ретеншн без лишнего шума

Зачем Kubernetes audit log нужен в реальной эксплуатации

Kubernetes audit log — это журнал действий на уровне Kubernetes API: кто и что делал через kube-apiserver, с какими объектами, откуда пришёл запрос и чем он закончился. В отличие от логов приложений и компонентов кластера, аудит фокусируется на действиях (API-запросах) и часто становится единственным источником правды при разборе инцидентов: утечка токенов, неожиданные изменения RBAC, создание привилегированных Pod, подмена образов, отключение admission-контуров.

Ключевая идея: аудит включается и настраивается политикой (audit policy), а не «как получится». Если включить всё подряд в максимальной детализации, вы утонете в объёмах, задержках и стоимости хранения. Если включить слишком мало — расследование будет слепым.

Ниже — практический подход: какие события действительно нужны, как выбрать уровень логирования, как включить аудит через флаги apiserver, как отправлять события в webhook backend и как продумать ретеншн.

Как устроен аудит в kube-apiserver: события, уровни и стадии

Аудит в Kubernetes генерируется на kube-apiserver и описывается объектом audit event. Вы управляете тем, какие события писать и сколько данных включать, через audit policy.

Уровни (level): Metadata / Request / RequestResponse

  • Metadata — минимум: метаданные запроса (кто, что, к чему, результат). Это базовый уровень для большинства ресурсов.

  • Request — добавляется тело запроса. Полезно, когда важно видеть, что именно пытались изменить (например, patch RBAC или PodSpec).

  • RequestResponse — добавляется и запрос, и ответ. Самый шумный и рискованный по данным уровень (может утянуть лишнее), но иногда незаменим для расследования сложных кейсов.

Практическое правило: RequestResponse применяйте точечно — для узкого списка ресурсов и только там, где вы уверены, что не «засветите» чувствительные данные и не взорвёте объём.

Стадии (stages) и omitStages

Запрос к API проходит несколько стадий. Наиболее полезны:

  • RequestReceived — запрос пришёл, но ещё не авторизован и не выполнен.

  • ResponseStarted — актуально для watch/streaming.

  • ResponseComplete — запрос обработан полностью (обычно это то, что нужно для расследований).

  • Panic — если apiserver паниковал (редко, но важно).

Чтобы убрать «дубликаты», часто используют omitStages. Самый частый выбор — исключить RequestReceived и оставить ResponseComplete (и иногда Panic). Так вы сохраняете итог запроса, не раздувая лог на каждый вызов двумя-тремя событиями.

Если ваша цель — incident response и расследование «кто изменил объект», то почти всегда достаточно событий стадии ResponseComplete: они содержат пользователя, ресурс, вердикт авторизации и код ответа.

Схема стадий аудита kube-apiserver и уровней логирования

Включение аудита: флаги apiserver и обязательные файлы

Дальше зависит от того, как у вас развёрнут control plane: kubeadm, managed Kubernetes или «самосбор». Но принципы одинаковые: вы задаёте audit policy и настраиваете backend(ы), куда kube-apiserver будет писать события.

Минимальный набор флагов для файлового бэкенда

Для записи в файл обычно нужны:

  • --audit-policy-file — путь к YAML с audit policy.

  • --audit-log-path — куда писать audit log (если пусто — файл не пишется).

  • --audit-log-maxage, --audit-log-maxbackup, --audit-log-maxsize — базовая ротация на стороне apiserver.

  • --audit-log-format — обычно json.

Пример (значения подберите под свои диски и требования):

--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-format=json
--audit-log-maxage=7
--audit-log-maxbackup=10
--audit-log-maxsize=100

Локальный файл на control-plane — полезная страховка, но не финальная цель. Для поиска, корреляции и долгого хранения аудит почти всегда нужно централизовать.

Webhook backend: отправка аудита во внешнюю систему

Webhook backend отправляет audit events на удалённый приёмник (лог-агрегатор, SIEM, собственный сервис). В kube-apiserver включается флагом --audit-webhook-config-file. Конфиг по формату похож на kubeconfig: кластер, CA, адрес и учётные данные.

Webhook — это сеть и потенциальные проблемы доставки. Заранее продумайте:

  • буферизацию или очередь на стороне приёмника;

  • SLO на доступность endpoint’а;

  • поведение при деградации: что происходит, если приёмник недоступен (задержки, дропы, backpressure).

Типовой набор флагов:

--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-webhook-config-file=/etc/kubernetes/audit-webhook.yaml
--audit-webhook-mode=batch

Режим batch обычно снижает накладные расходы, но требует, чтобы приёмник корректно обрабатывал пачки и переживал пики.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Практичный audit policy: пишем важное и не пишем лишнее

Audit policy — это набор правил (rules), которые матчатся сверху вниз. Первое совпадение определяет действие: логировать на нужном уровне или не логировать вовсе.

Ниже — шаблон, от которого удобно отталкиваться. Он показывает ключевые техники: omitStages, точечный RequestResponse, исключение шумных эндпоинтов и акцент на критичные изменения.

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: None
    nonResourceURLs:
      - "/healthz*"
      - "/readyz*"
      - "/livez*"
      - "/metrics"

  - level: Metadata
    resources:
      - group: ""
        resources: ["pods", "services", "configmaps", "namespaces", "serviceaccounts"]
      - group: "apps"
        resources: ["deployments", "daemonsets", "statefulsets", "replicasets"]

  - level: Request
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
      - group: "admissionregistration.k8s.io"
        resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"]

  - level: RequestResponse
    verbs: ["create", "update", "patch", "delete", "deletecollection"]
    resources:
      - group: ""
        resources: ["secrets"]

  - level: Metadata

Что здесь важно и что нужно адаптировать

  • Сначала выкидываем неинформативное: /healthz, /readyz, /livez, /metrics. Эти вызовы частые и обычно не помогают расследованиям.

  • База — Metadata на массовые ресурсы. Это даёт «кто/что/где/когда/результат» без лишнего объёма.

  • Повышаем детализацию для контуров контроля: RBAC и admission webhooks. Любые изменения тут часто означают попытку закрепиться или расширить привилегии.

  • Secrets — отдельная история. RequestResponse на secrets почти всегда спорен: вы можете занести чувствительные данные в audit log и затем долго жить с риском утечки уже из системы логирования. Нередко разумнее оставить Metadata (фиксировать факт доступа/изменения), а содержимое защищать другими механизмами. Если всё же включаете RequestResponse, обеспечьте строгий доступ к логам, шифрование и понятный ретеншн.

  • Последнее правило — «ловим остальное» на Metadata, чтобы не потерять неизвестное поведение.

Если вам нужно глубже закрыть тему «кто входил на ноды и что делал», полезно дополнить аудит Kubernetes логированием SSH и системных событий. См. заметку про алерты на SSH-входы через PAM и journald.

Где хранить audit log и как продумать retention

Retention — это не только «сколько дней держать». Это компромисс между требованиями безопасности и комплаенса, стоимостью хранения и удобством расследований.

Ротация на apiserver vs централизованное хранение

Флаги --audit-log-maxage, --audit-log-maxbackup, --audit-log-maxsize помогают не забить диск на control-plane, но не решают задачу долгого хранения и поиска. Как минимум, аудит стоит вывозить в централизованную систему: через webhook backend или агент, который читает файл и отправляет дальше.

Типовой подход:

  • локально: 1–7 дней для «быстрых разборов» и на случай проблем с доставкой;

  • централизованно: 30–180+ дней в зависимости от требований;

  • «холодный» архив: если нужно хранить год и больше, делайте отдельный контур с редким доступом.

Контроль объёма: что чаще всего раздувает лог

  • watch-запросы (особенно от контроллеров и операторов);

  • RequestResponse на широких ресурсах;

  • частые запросы системных компонентов к apiserver;

  • дубли из-за стадий, если не настроен omitStages.

Если видите взрыв объёма — первым делом проверьте omitStages и правила с высоким level на массовых ресурсах.

Поток audit log из webhook backend в централизованное хранилище

Incident response: какие вопросы audit log должен закрывать

При инциденте вы почти всегда пытаетесь ответить на несколько конкретных вопросов. Хорошая audit policy должна помогать отвечать на них быстро и с достаточной точностью.

Чек-лист вопросов к audit log

  1. Кто выполнил действие: пользователь, группы, serviceAccount, impersonation.

  2. Откуда: source IP, user-agent, иногда — цепочка прокси (если вы её прокидываете).

  3. Что именно сделали: verb, resource, namespace/name.

  4. Результат: код ответа, отказ authn/authz, ошибки admission.

  5. Когда и как часто: временная шкала, повторяющиеся попытки.

Сценарии, под которые стоит «заточить» политику

  • Неожиданное расширение прав: изменения clusterrolebindings, привязка cluster-admin, создание ролей с чрезмерными правами.

  • Изменения admission-контуров: подмена или удаление validating/mutating webhook конфигураций.

  • Изменение критичных workload: patch Deployment/DaemonSet с добавлением привилегий, hostPath, hostNetwork, токенов.

  • Работа с secrets: массовые чтения, изменения, попытки доступа из неожиданных serviceAccount.

Для incident response важно не «логировать всё», а гарантировать, что изменения контуров контроля (RBAC, admission, authn/authz) пишутся стабильно и доступны достаточно долго.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Тонкие места безопасности: доступ к логам, приватность и «утечки через аудит»

Audit log сам по себе становится чувствительным активом. В нём есть структура кластера, имена namespace, serviceAccount, а при высоких уровнях — фрагменты payload. Поэтому:

  • ограничьте доступ к audit log на уровне ОС и системы логирования (минимум прав, отдельные роли);

  • шифруйте хранение и транспорт, особенно при webhook backend (и проверьте доверие к CA/сертификатам приёмника);

  • не включайте RequestResponse «широко», особенно на ресурсах, где потенциально есть секреты или персональные данные;

  • согласуйте ретеншн с внутренними требованиями и режимом доступа к логам.

Если вы публикуете API наружу (например, через прокси или балансировщик), не забудьте про базовую гигиену TLS на внешнем контуре и внутри лог-пайплайна: корректная валидация, актуальные цепочки, контроль истечения. При необходимости можно оформить и централизованно управлять сертификатами через SSL-сертификаты.

Проверка, что политика работает: быстрый sanity-check

После включения аудита важно убедиться, что события реально приходят и соответствуют ожиданиям по детализации и шуму.

Минимальная проверка через kubectl

Сделайте несколько безопасных действий (создать namespace, применить ConfigMap, посмотреть список Pod) и проверьте, что в логе появляются события нужного уровня.

Если аудит пишется в файл на control-plane, для первичной проверки достаточно найти события по полям "verb", "objectRef" и пользователю:

sudo grep '"verb":"create"' /var/log/kubernetes/audit.log | head -n 20
sudo grep '"objectRef"' /var/log/kubernetes/audit.log | head -n 20

Симптомы проблем

  • Лог пустой: не подключен backend (нет --audit-log-path и/или --audit-webhook-config-file), неверный путь к policy, нет прав на запись.

  • Слишком много событий: нет omitStages, логируются nonResourceURLs и health-check’и, высокий level на массовых ресурсах.

  • Не хватает данных для расследования: слишком агрессивные исключения, нет повышенного уровня для RBAC/admission/критичных изменений.

Итог: базовая стратегия audit policy для продакшена

  • Начинайте с Metadata почти везде и фиксируйте итоговую стадию ResponseComplete.

  • Используйте omitStages, чтобы убрать дубли и снизить шум.

  • Повышайте уровень до Request (и точечно до RequestResponse) для RBAC, admission и других контуров контроля.

  • Относитесь к audit log как к чувствительному активу: доступ, шифрование, ретеншн, аудит доступа к логам.

  • Не полагайтесь только на локальные файлы: централизуйте хранение и обеспечьте поиск.

При таком подходе audit policy становится не формальностью, а рабочим инструментом эксплуатации: и для расследований, и для постоянного контроля изменений в кластере.

Поделиться статьей

Вам будет интересно

Rsync over SSH: ускоряем передачу и держим нагрузку под контролем (cipher, compression, bwlimit, IO) OpenAI Статья написана AI (GPT 5)

Rsync over SSH: ускоряем передачу и держим нагрузку под контролем (cipher, compression, bwlimit, IO)

Разберём, как разогнать rsync over SSH и не «положить» прод: как выбрать быстрый cipher (chacha20-poly1305 или aes128-gcm), когда ...
Reverse DNS (PTR): как работает rDNS, зачем нужен и как настроить без боли OpenAI Статья написана AI (GPT 5)

Reverse DNS (PTR): как работает rDNS, зачем нужен и как настроить без боли

Reverse DNS (PTR, rDNS) — запись, которая сопоставляет IP-адрес с hostname. Разберём, где живёт PTR, как проверить через dig -x, з ...
Postfix: deferred и bounce из‑за DNS и TLS — разбор очереди и быстрый план ремонта OpenAI Статья написана AI (GPT 5)

Postfix: deferred и bounce из‑за DNS и TLS — разбор очереди и быстрый план ремонта

Если письма в Postfix зависают со status=deferred или уходят в bounce, чаще всего причина в DNS (резолвинг, MX/A/AAAA, rDNS PTR, H ...