Настройка Audit Logs

Политика аудита, хранение логов аудита.

Введение

Audit Logs фиксируют обращения к API-серверу Kubernetes и помогают определить:

  • что произошло;
  • когда произошло событие;
  • кто инициировал действие;
  • с каким ресурсом выполнялось действие;
  • где было зафиксировано событие;
  • откуда был инициирован запрос;
  • куда был направлен запрос.

События аудита формируются в kube-apiserver. Для каждого запроса на разных этапах обработки создаётся audit event, затем событие обрабатывается политикой аудита и записывается в backend. Политика аудита определяет, какие события записывать и с каким уровнем детализации, а backend отвечает за сохранение записей.

В платформе «Штурвал» для Audit Logs используется log backend: события записываются в файл на узлах control-plane, собираются модулем логирования, отправляются в VLogs и отображаются в интерфейсе платформы.

Включение audit logging увеличивает потребление памяти API-сервером, потому что для аудита по каждому запросу хранится дополнительный контекст. Объём потребления зависит от настроенной политики аудита.


Когда логи аудита доступны в интерфейсе

  • Кластер развёрнут с расширенными настройками безопасности — тогда политика аудита настраивается автоматически, в VLogs создаётся проект kube audit, логи собираются модулем сбора логов (Vector) и доступны на вкладке Логи дашборда кластера.
  • Если кластер создан без расширенных настроек безопасности, политику аудита можно настроить вручную. Для отображения логов на дашборде должен быть включён модуль сбора логов и настроен сбор Audit Logs из /var/log/kube-api-audit/audit.log.
Скриншот: Audit Logs на вкладке «Логи»

Audit Logs на вкладке «Логи»


Политика аудита

Audit Policy задаётся YAML-файлом в формате Kubernetes Audit Policy. Правила обрабатываются по порядку: первое подходящее правило определяет уровень аудита для события.

Доступны уровни аудита:

  • None — не записывать события, подходящие под правило.
  • Metadata — записывать метаданные запроса: пользователя, время, ресурс, действие и другие поля без тела запроса и ответа.
  • Request — записывать метаданные и тело запроса без тела ответа. Для нересурсных запросов этот уровень не применяется.
  • RequestResponse — записывать метаданные, тело запроса и тело ответа. Для нересурсных запросов этот уровень не применяется.

Событие может быть записано на одном из этапов обработки запроса:

  • RequestReceived — запрос получен audit handler и ещё не передан дальше по цепочке обработчиков.
  • ResponseStarted — заголовки ответа отправлены, тело ответа ещё не отправлено. Этап создаётся только для long-running-запросов, например watch.
  • ResponseComplete — тело ответа полностью отправлено.
  • Panic — при обработке запроса возникла panic.

Политика передаётся в kube-apiserver через флаг --audit-policy-file. Если флаг не указан, события аудита не записываются. В файле политики обязательно должно быть поле rules; политика без правил считается некорректной.

Для подготовки YAML можно использовать графический редактор политики аудита.

Минимальная политика для записи всех запросов на уровне Metadata:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata

Настройка политики аудита вручную

Если кластер создан без расширенных настроек безопасности, Audit Policy можно добавить вручную через конфигурацию узлов.

  1. Перейдите в раздел Администрирование → Конфигурация узлов нужного кластера.
  2. Создайте или отредактируйте объект конфигурации узлов (NCI). В селекторе узлов выберите лейбл node-role.kubernetes.io/control-plane (без значения), чтобы применить настройки к узлам control-plane.
  3. Если Audit Policy уже была добавлена через NCI, измените существующий манифест или создайте новый NCI с более высоким приоритетом.
  4. В блоке Настраиваемые разделы выберите Файлы и директорииУправлять+ и добавьте файл:
    • Путь: /etc/kubernetes/audit_policy.yaml
    • Тип: файл
    • Содержимое: YAML политики аудита.
  5. Нажмите Добавить, затем Завершить.
Скриншот: настройка NCI

Настройка NCI

После применения NCI узлы control-plane последовательно перезапускаются.

Настройка API-сервера

Отредактируйте манифест kube-apiserver на control-plane узлах: /etc/kubernetes/manifests/kube-apiserver.yaml.

Добавьте аргументы запуска:

spec:
  containers:
  - command:
    - --audit-policy-file=/etc/kubernetes/audit_policy.yaml
    - --audit-log-path=/var/log/kube-api-audit/audit.log
    - --audit-log-maxage=30
    - --audit-log-maxbackup=10
    - --audit-log-maxsize=100
    - --audit-log-mode=batch

Смонтируйте файл политики и директорию логов:

    volumeMounts:
    - mountPath: /etc/kubernetes/audit_policy.yaml
      name: audit-policy
    - mountPath: /var/log/kube-api-audit/
      name: audit-log
      readOnly: false

Добавьте hostPath для политики и логов:

  volumes:
  - hostPath:
      path: /etc/kubernetes/audit_policy.yaml
      type: File
    name: audit-policy
  - hostPath:
      path: /var/log/kube-api-audit/
      type: DirectoryOrCreate
    name: audit-log

Логи аудита пишутся в /var/log/kube-api-audit/audit.log. Если используются сервисы логирования «Штурвала», Vector собирает события из этого файла и перенаправляет их в экземпляр VLogs - VLSingle в неймспейс кластера управления.


Примеры рекомендуемых политик

Ниже приведены примеры политик для кластера управления и клиентских кластеров. Они отличаются от автоматически монтируемых отсутствием исключений лога действий системных сервисаккаунтов. Например, чтобы исключить действия системных ServiceAccounts в кластере управления в блоке “rules” первым добавьте правило с уровнем логирования None:


  - level: None
    users: ["system:serviceaccounts:monitoring",
            "system:serviceaccounts:shturval-backend",
            "system:serviceaccounts:ingress",
            "system:nodes",
            "system:serviceaccounts:trivy-system",
            "system:serviceaccounts:cert-manager",
            "system:serviceaccounts:metallb-system",
            "system:serviceaccounts:kyverno",
            "system:serviceaccounts:shturval-operator-system",
            "system:serviceaccounts:kube-system",
            "system:serviceaccount:shturval-cert-expiration:shturval-cert-expiration",
            "system:serviceaccount:shturval-services-system:default",
            "system:serviceaccount:kube-system:cilium-operator",
            "system:serviceaccount:kube-vip:shturval-vip-provider",
            "system:serviceaccount:kube-vip:shturval-vip",
            "system:kube-controller-manager",
            "system:kube-scheduler",
            "system:serviceaccount:kyverno:shturval-policy-manager",
            "system:serviceaccount:kyverno:shturval-policy-manager-cleanup-controller",
            "system:serviceaccount:shturval-node-config-system:default",
            "system:serviceaccount:cert-manager:shturval-cert-manager-webhook",
            "system:serviceaccount:cert-manager:shturval-cert-manager",
            "system:serviceaccount:monitoring:shturval-metrics-kube-state-metrics",
            "system:serviceaccount:kube-system:cilium",
            "system:serviceaccount:trivy-system:shturval-scanner",
            "system:apiserver",
            "system:serviceaccount:logging:fluent-operator",
            "system:serviceaccount:kube-system:generic-garbage-collector",
            "system:serviceaccount:kube-system:job-controller",
            "system:serviceaccount:monitoring:shturval-metrics-operator",
            "system:serviceaccount:kube-system:persistent-volume-binder",
            "system:serviceaccount:kube-system:job-controller",
            "system:serviceaccount:shturval-services-system:default",
            "system:serviceaccount:trivy-system:shturval-scanner",
            "system:serviceaccount:rawfile-provisioner:shturval-local-csi-driver",
            "system:serviceaccount:ingress:shturval-ingress-controller",
            "system:serviceaccount:velero:shturval-backup-server",
            "system:serviceaccount:cert-manager:shturval-cert-manager-cainjector"]
    verbs: ["watch", "list", "create", "update", "get", "delete", "patch"]

Политика для кластера управления

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
  - "ResponseStarted"
omitManagedFields: true
rules:
  - level: Metadata
    verbs: ["delete"]
    resources:
      - group: "controlplane.cluster.x-k8s.io"
        resources: ["kubeadmcontrolplanes", "kubeadmcontrolplanetemplates"]
  - level: Request
    verbs: ["create", "update", "patch"]
    resources:
      - group: "controlplane.cluster.x-k8s.io"
        resources: ["kubeadmcontrolplanes", "kubeadmcontrolplanetemplates"]
  - level: Metadata
    verbs: ["delete"]
    resources:
      - group: "infrastructure.cluster.x-k8s.io"
        resources: ["basisclusters",
                    "basismachines",
                    "basismachinetemplates",
                    "basisproviders",
                    "ovirtclusters",
                    "ovirtmachines",
                    "ovirtmachinetemplates",
                    "ovirtproviders",
                    "vsphereclusteridentities",
                    "vsphereclusters",
                    "vsphereclustertemplates",
                    "vspheremachines",
                    "vspheremachinetemplates"]
      - group: "ops.shturval.tech"
        resources: ["shturvalserviceconfigs"]
      - group: "node.shturval.tech"
        resources: ["nodeconfigitems", "nodeconfigs"]
  - level: Request
    verbs: ["create", "update", "patch"]
    resources:
      - group: "infrastructure.cluster.x-k8s.io"
        resources: ["basisclusters",
                    "basismachines",
                    "basismachinetemplates",
                    "basisproviders",
                    "ovirtclusters",
                    "ovirtmachines",
                    "ovirtmachinetemplates",
                    "ovirtproviders",
                    "vsphereclusteridentities",
                    "vsphereclusters",
                    "vsphereclustertemplates",
                    "vspheremachines",
                    "vspheremachinetemplates"]
      - group: "cluster.x-k8s.io"
        resources: ["clusterclasses",
                    "clusters",
                    "machinedeployments",
                    "machinehealthchecks",
                    "machinepools",
                    "machines",
                    "machinesets"]
  - level: Request
    verbs: ["create", "delete", "update", "patch"]
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "clusterroles"]
  - level: Request
    verbs: ["create", "delete"]
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterrolebindings", "rolebindings"]
  - level: Request
    verbs: ["create", "delete", "update", "patch"]
    resources:
      - group: "permissions.shturval.tech"
        resources: ["*"]
  - level: Metadata
    verbs: ["create", "delete", "update", "patch", "get"]
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]

Политика для клиентского кластера

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
  - "ResponseStarted"
omitManagedFields: true
rules:
  - level: Metadata
    verbs: ["delete"]
    resources:
      - group: ""
        resources: ["deployments", "statefulsets", "daemonsets", "pods/log", "pods"]
  - level: RequestResponse
    verbs: ["create", "update", "patch"]
    resources:
      - group: ""
        resources: ["deployments", "statefulsets", "pods"]
  - level: Request
    resources:
      - group: ""
        resources: ["pods/exec"]
    verbs: ["create", "delete", "update", "patch", "get"]
  - level: Request
    verbs: ["create", "delete", "update", "patch"]
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "clusterroles"]
  - level: Request
    verbs: ["create", "delete"]
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterrolebindings", "rolebindings"]
  - level: Request
    verbs: ["create", "delete", "update", "patch"]
    resources:
      - group: "permissions.shturval.tech"
        resources: ["*"]
  - level: Metadata
    verbs: ["delete"]
    resources:
      - group: "cilium.io"
        resources: ["ciliumnetworkpolicies"]
      - group: "ops.shturval.tech"
        resources: ["shturvalserviceconfigs"]
      - group: "node.shturval.tech"
        resources: ["nodeconfigitems", "nodeconfigs"]
  - level: Request
    verbs: ["create", "update", "patch"]
    resources:
      - group: "cilium.io"
        resources: ["ciliumnetworkpolicies"]
  - level: Metadata
    verbs: ["create", "delete", "update", "patch"]
    resources:
      - group: "velero.io"
        resources: ["backups", "restores"]
  - level: Metadata
    verbs: ["create", "delete", "update", "patch", "get"]
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]

Параметры log backend

Log backend записывает события аудита в файл в формате JSON Lines. Для настройки используются флаги kube-apiserver:

  • --audit-log-path — путь к файлу логов. Если флаг не указан, log backend отключён. Значение - означает вывод в стандартный поток.
  • --audit-log-maxage — максимальное число дней хранения старых файлов audit log.
  • --audit-log-maxbackup — максимальное число файлов audit log, которые сохраняются при ротации.
  • --audit-log-maxsize — максимальный размер файла audit log в мегабайтах до ротации.
  • --audit-log-mode — режим обработки событий: batch, blocking или blocking-strict.

В режиме blocking API-сервер ожидает обработки каждого события аудита перед ответом. В режиме batch события буферизуются и обрабатываются пакетами. В режиме blocking-strict ошибка аудита на этапе RequestReceived приводит к ошибке всего запроса к kube-apiserver.

По умолчанию batching и throttling включены для webhook backend и отключены для log backend. При использовании batch-режима параметры нужно подбирать с учётом нагрузки на API-сервер и скорости записи backend.

Для контроля состояния подсистемы аудита используются метрики kube-apiserver:

  • apiserver_audit_event_total — общее число экспортированных событий аудита.
  • apiserver_audit_error_total — общее число событий, отброшенных из-за ошибки экспорта.

Log backend и webhook backend поддерживают ограничение размера записываемых событий. По умолчанию truncate отключён; для log backend его включает флаг audit-log-truncate-enabled, а максимальный размер batch и события задаётся флагами audit-log-truncate-max-batch-size и audit-log-truncate-max-event-size.


Формат событий

События аудита имеют структуру Kubernetes API из группы audit.k8s.io. Для patch-запросов тело запроса записывается как JSON-массив операций patch, а не как полный объект Kubernetes:

[
  {
    "op": "replace",
    "path": "/spec/parallelism",
    "value": 0
  },
  {
    "op": "remove",
    "path": "/spec/template/spec/containers/0/terminationMessagePolicy"
  }
]

Где смотреть логи

  • Дашборд кластера → вкладка «Логи» — при расширенных настройках безопасности и работающем сборе логов в VLogs. Для Audit Logs используется проект kube audit.
  • VLogs — при использовании сервисов логирования «Штурвала» события перенаправляются в экземпляр VLogs - VLSingleв неймспейс кластера управления.
  • Экспорт в SIEM — см. Экспорт логов в SIEM.

См. также: