Журналы аудита Kubernetes — лучшие практики и конфигурация ✨.

Этот учебник был первоначально опубликован в блоге SigNoz и написан Винаяком Пандеем.

Kubernetes является фактическим лидером среди инструментов оркестровки контейнеров. С ростом популярности разработки на основе микросервисов Kubernetes стал основным инструментом для развертывания и управления крупномасштабными корпоративными приложениями. Однако, несмотря на множество функций, предлагаемых Kubernetes, это сложный инструмент для управления и эксплуатации. Эта статья будет посвящена тому, как настроить журналы аудита Kubernetes, чтобы вы могли иметь записи о событиях, происходящих в вашем кластере.

Что такое журнал аудита Kubernetes?

Если у вас есть опыт работы с Kubernetes, то вы должны знать, что все коммуникации между компонентами Kubernetes и команды, выполняемые пользователями, представляют собой вызовы REST API. Kubernetes API Server — это компонент, который обрабатывает все эти запросы. Поэтому всякий раз, когда вы выполняете команду kubectl, она, по сути, является оберткой для вызова API, сделанного к серверу API.

Журналы аудита Kubernetes записывают все эти вызовы API, сделанные к серверу API. Сюда входят вызовы API различных пользователей и вызовы, сделанные различными компонентами самой Kubernetes. Эти журналы предоставляют много информации, связанной с запросом API, например, время запроса, IP-адрес источника и пользователя, который сделал запрос, тип запроса и ответ, отправленный сервером API.

Зачем нужно настраивать журналы аудита Kubernetes?

Журналы аудита обеспечивают видимость событий, происходящих в кластере Kubernetes, и служат основой для обеспечения безопасности и соответствия нормативным требованиям. Правильно настроенные журналы аудита позволяют быстро выявить любую аномальную активность, происходящую в кластере, например, неудачные попытки входа в систему или попытки получить доступ к конфиденциальным секретам.
Аудит позволяет быстро принимать меры в отношении злонамеренных действий вместо того, чтобы действовать изолированно. Регулярный аудит данных журнала событий также помогает в укреплении кластера и устранении любых ошибок в конфигурации.

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

Журналы аудита собираются на основе настроенной политики аудита. Политика аудита определяет, какие события должны быть записаны и какие данные должны быть включены. Правила, настроенные в политике аудита, обрабатываются по порядку, и первое совпадающее правило устанавливает уровень аудита события.

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

  • RequestReceived: Этап для событий, генерируемых, как только обработчик аудита получает запрос.
  • ResponseStarted: После отправки заголовков ответа, но до отправки тела ответа.
  • ResponseComplete: Отправка тела ответа завершена.
  • Паника: события, генерируемые при возникновении паники.

Информация, захваченная для события, зависит от настроенного уровня аудита. Вы можете использовать следующие уровни аудита:

  • Нет: Не регистрировать события, соответствующие этому правилу
  • Метаданные: Регистрировать метаданные события запроса. Тело запроса/ответа не регистрируется.
  • Запрос: Регистрировать метаданные события и тело запроса.
  • RequestResponse: Регистрировать метаданные события вместе с телом запроса и ответа.

Настройка аудита Kubernetes

Настало время увидеть аудит Kubernetes в действии. В кластере с собственным хостингом аудит не включен изначально. Если вы используете управляемый кластер Kubernetes, вы можете обратиться к документации вашего поставщика, чтобы проверить, включен ли аудит по умолчанию или его нужно включить.
Кластер, используемый здесь, имеет один экземпляр control-plane и один экземпляр узла, и вы можете использовать те же шаги для кластера minikube или любого другого пустого кластера Kubernetes.

Шаг 1: Подключение к control-plane

Подключитесь к узлу control-plane и создайте каталог для размещения политики аудита, а также журналов аудита.

mkdir /etc/kubernetes/audit
Войдите в полноэкранный режим Выход из полноэкранного режима

Шаг 2: Создайте политику аудита

Создайте файл политики аудита с именем /etc/kubernetes/audit/policy.yaml со следующими данными:

apiVersion: audit.k8s.io/v1
kind: Policy
rules:

- level: None
  verbs: ["get", "watch", "list"]

- level: None
  resources:
  - group: "" # core
    resources: ["events"]

- level: None
  users:
  - "system:kube-scheduler"
  - "system:kube-proxy"
  - "system:apiserver"
  - "system:kube-controller-manager"
  - "system:serviceaccount:gatekeeper-system:gatekeeper-admin"

- level: None
  userGroups: ["system:nodes"]

- level: RequestResponse
Войти в полноэкранный режим Выйти из полноэкранного режима

Шаг 3: Добавьте необходимые записи

Добавьте следующие записи в /etc/kubernetes/manifests/kube-apiserver.yaml:

- --audit-policy-file=/etc/kubernetes/audit/policy.yaml
- --audit-log-path=/etc/kubernetes/audit/audit.log
- --audit-log-maxsize=500
- --audit-log-maxbackup=3
Войти в полноэкранный режим Выйти из полноэкранного режима

Прокрутите вниз и добавьте том в разделе volumes:

- hostPath:                              
    path: /etc/kubernetes/audit          
    type: DirectoryOrCreate               
  name: audit
Войдите в полноэкранный режим Выйти из полноэкранного режима

Теперь смонтируйте этот том, добавив следующие данные в разделе volumeMounts:

- mountPath: /etc/kubernetes/audit      
  name: audit
Войти в полноэкранный режим Выйти из полноэкранного режима

Это все, что вам нужно сделать, чтобы настроить ведение журнала аудита. Поскольку вы изменили манифест kube-apiserver, ваш kube-apiserver pod будет создан заново. Как только pod будет запущен, выполните следующую команду для создания учетной записи службы.

kubectl create sa test
Вход в полноэкранный режим Выйдите из полноэкранного режима

Этот запрос API будет записан в файл журнала аудита (/etc/kubernetes/audit/audit.log), и вы увидите несколько подобных записей:

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "RequestResponse",
    "auditID": "a6029022-4ff0-4c54-97ed-4099d0ca1923",
    "stage": "RequestReceived",
    "requestURI": "/api/v1/namespaces/default/serviceaccounts?fieldManager=kubectl-create",
    "verb": "create",
    "user": {
        "username": "kubernetes-admin",
        "groups": ["system:masters", "system:authenticated"]
    },
    "sourceIPs": ["172.31.22.88"],
    "userAgent": "kubectl/v1.23.6 (linux/amd64) kubernetes/ad33385",
    "objectRef": {
        "resource": "serviceaccounts",
        "namespace": "default",
        "apiVersion": "v1"
    },
    "requestReceivedTimestamp": "2022-07-31T08:36:48.679291Z",
    "stageTimestamp": "2022-07-31T08:36:48.679291Z"
}
Вход в полноэкранный режим Выход из полноэкранного режима

и

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "RequestResponse",
    "auditID": "a6029022-4ff0-4c54-97ed-4099d0ca1923",
    "stage": "ResponseComplete",
    "requestURI": "/api/v1/namespaces/default/serviceaccounts?fieldManager=kubectl-create",
    "verb": "create",
    "user": {
        "username": "kubernetes-admin",
        "groups": ["system:masters", "system:authenticated"]
    },
    "sourceIPs": ["172.31.22.88"],
    "userAgent": "kubectl/v1.23.6 (linux/amd64) kubernetes/ad33385",
    "objectRef": {
        "resource": "serviceaccounts",
        "namespace": "default",
        "name": "test",
        "apiVersion": "v1"
    },
    "responseStatus": {
        "metadata": {},
        "code": 201
    },
    "requestObject": {
        "kind": "ServiceAccount",
        "apiVersion": "v1",
        "metadata": {
            "name": "test",
            "creationTimestamp": null
        }
    },
    "responseObject": {
        "kind": "ServiceAccount",
        "apiVersion": "v1",
        "metadata": {
            "name": "test",
            "namespace": "default",
            "uid": "d6ea858a-206d-4b4a-aca0-499e22f00729",
            "resourceVersion": "1676",
            "creationTimestamp": "2022-07-31T08:36:48Z"
        }
    },
    "requestReceivedTimestamp": "2022-07-31T08:36:48.679291Z",
    "stageTimestamp": "2022-07-31T08:36:48.684377Z",
    "annotations": {
        "authorization.k8s.io/decision": "allow",
        "authorization.k8s.io/reason": ""
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Если проверить auditID, то он одинаков для обоих событий (a6029022-4ff0-4c54-97ed-4099d0ca1923), поскольку обе записи относятся к одному событию. Первая запись относится к этапу RequestReceived, а вторая — к этапу ResponseComplete. Имея эти данные, вы можете легко выяснить, что это был за запрос и кто его выполнил, посмотрев на поля sourceIPs, username, requestURI, responseStatus и responseObject.

В политике аудита, если вы измените уровень аудита с RequestResponse на MetaData, вы не увидите поля requestObject и responseObject, а если уровень аудита установлен на Request, то поле requestObject будет присутствовать, но поле responseObject не будет регистрироваться.

Возвращаясь к нашим данным о событиях, HTTP Status 201 в поле responseStatus означает, что в результате HTTP POST запроса один или несколько новых ресурсов были успешно созданы на сервере, который в данном случае является учетной записью службы. Если пользователь, не имеющий доступа к созданию учетной записи службы, попытается создать учетную запись службы, вы увидите в журнале аудита запись, подобную этой:

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "RequestResponse",
    "auditID": "605e41ff-394a-4b8d-bd32-86ffa984d55a",
    "stage": "RequestReceived",
    "requestURI": "/api/v1/namespaces/default/serviceaccounts?fieldManager=kubectl-create",
    "verb": "create",
    "user": {
        "username": "myuser",
        "groups": ["Dev", "system:authenticated"]
    },
    "sourceIPs": ["172.31.22.88"],
    "userAgent": "kubectl/v1.23.6 (linux/amd64) kubernetes/ad33385",
    "objectRef": {
        "resource": "serviceaccounts",
        "namespace": "default",
        "apiVersion": "v1"
    },
    "requestReceivedTimestamp": "2022-07-31T09:00:44.262246Z",
    "stageTimestamp": "2022-07-31T09:00:44.262246Z"
}
Вход в полноэкранный режим Выход из полноэкранного режима

и

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "RequestResponse",
    "auditID": "605e41ff-394a-4b8d-bd32-86ffa984d55a",
    "stage": "ResponseComplete",
    "requestURI": "/api/v1/namespaces/default/serviceaccounts?fieldManager=kubectl-create",
    "verb": "create",
    "user": {
        "username": "myuser",
        "groups": ["Dev", "system:authenticated"]
    },
    "sourceIPs": ["172.31.22.88"],
    "userAgent": "kubectl/v1.23.6 (linux/amd64) kubernetes/ad33385",
    "objectRef": {
        "resource": "serviceaccounts",
        "namespace": "default",
        "apiVersion": "v1"
    },
    "responseStatus": {
        "metadata": {},
        "status": "Failure",
        "reason": "Forbidden",
        "code": 403
    },
    "responseObject": {
        "kind": "Status",
        "apiVersion": "v1",
        "metadata": {},
        "status": "Failure",
        "message": "serviceaccounts is forbidden: User "myuser" cannot create resource "serviceaccounts" in API group "" in the namespace "default"",
        "reason": "Forbidden",
        "details": {
            "kind": "serviceaccounts"
        },
        "code": 403
    },
    "requestReceivedTimestamp": "2022-07-31T09:00:44.262246Z",
    "stageTimestamp": "2022-07-31T09:00:44.274511Z",
    "annotations": {
        "authorization.k8s.io/decision": "forbid",
        "authorization.k8s.io/reason": ""
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Это событие сообщает вам, что пользователь myuser попытался создать учетную запись службы, но запрос был отклонен из-за недостаточного разрешения.

Поскольку эти записи имеют формат JSON, вы можете использовать инструмент jq для поиска записей журнала с помощью таких команд, как:

tail -f  /etc/kubernetes/audit/audit.log   | jq '.| select(.responseStatus.code | contains(403) )'
tail -f  /etc/kubernetes/audit/audit.log   | jq '.| select(.user.username | contains("myuser") )'
Войти в полноэкранный режим Выйти из полноэкранного режима

Лучшие практики для аудита Kubernetes

В производственной среде необходимо учитывать некоторые лучшие практики для аудита Kubernetes. К ним относятся:

  • Создание комплексной политики аудита, основанной на ваших требованиях к ведению журналов.
  • Используйте бэкенды webhook для отправки данных аудита на удаленные конечные точки вместо хранения журналов на диске
  • контролировать доступ к данным аудита, чтобы их нельзя было подделать.
  • Настроить оповещения и визуализацию на основе журналов аудита, чтобы вы получали информацию о важных событиях, таких как удаление секретов и т.д.

Заключительные мысли

Аудит — очень важная часть безопасности кластера Kubernetes, которая дает вам видимость событий, происходящих в вашем кластере, и помогает запустить правильно настроенный и безопасный кластер. В этой статье вы узнали о том, что такое аудит Kubernetes, почему он важен и как его настроить.

Безопасность — это бесконечный процесс, и всегда есть возможности для дальнейшей оптимизации и улучшения. Информация, представленная в этой статье, отправляет вас в путь к обеспечению безопасности вашего кластера Kubernetes, чтобы вы могли изучить его дальше.

Если вы хотите быть в курсе проблем в вашем кластере Kubernetes, вам необходимо следить за ним. SigNoz, APM с открытым исходным кодом, может отслеживать метрики, трассировки и журналы вашего кластера Kubernetes. Он создан для поддержки OpenTelemetry natively, стандарта с открытым исходным кодом для инструментария облачных приложений.

Вы можете ознакомиться с репозиторием SigNoz на GitHub здесь:

Читайте следующий блог, чтобы узнать, как мониторить кластер Kubernetes с помощью SigNoz:

Мониторинг Kubernetes с помощью инструментов с открытым исходным кодом

Оцените статью
devanswers.ru
Добавить комментарий