Как настроить альтернативные решения по управлению политиками безопасности?

Для корректной работы DKP необходимы расширенные привилегии на запуск и работу полезной нагрузки системных компонентов. Если вместо модуля admission-policy-engine используется альтернативное решение по управлению политиками безопасности (например, Kyverno), необходима настройка исключений для следующих пространств имен:

  • kube-system;
  • все пространства имен с префиксом d8-* (например, d8-system).

Как расширить политики Pod Security Standards?

Pod Security Standards реагируют на label security.deckhouse.io/pod-policy: restricted или security.deckhouse.io/pod-policy: baseline.

Чтобы расширить политику Pod Security Standards, добавив к существующим проверкам политики свои собственные, необходимо:

  • создать шаблон проверки (ресурс ConstraintTemplate);
  • привязать его к политике restricted или baseline.

Пример шаблона для проверки адреса репозитория образа контейнера:

1apiVersion: templates.gatekeeper.sh/v1
2kind: ConstraintTemplate
3metadata:
4  name: k8sallowedrepos
5spec:
6  crd:
7    spec:
8      names:
9        kind: K8sAllowedRepos
10      validation:
11        openAPIV3Schema:
12          type: object
13          properties:
14            repos:
15              type: array
16              items:
17                type: string
18  targets:
19    - target: admission.k8s.gatekeeper.sh
20      rego: |
21        package d8.pod_security_standards.extended
22        violation[{"msg": msg}] {
23          container := input.review.object.spec.containers[_]
24          satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
25          not any(satisfied)
26          msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
27        }
28        violation[{"msg": msg}] {
29          container := input.review.object.spec.initContainers[_]
30          satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)]
31          not any(satisfied)
32          msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos])
33        }

Пример привязки проверки к политике restricted:

1apiVersion: constraints.gatekeeper.sh/v1beta1
2kind: K8sAllowedRepos
3metadata:
4  name: prod-repo
5spec:
6  match:
7    kinds:
8      - apiGroups: [""]
9        kinds: ["Pod"]
10    namespaceSelector:
11      matchLabels:
12        security.deckhouse.io/pod-policy: restricted
13  parameters:
14    repos:
15      - "mycompany.registry.com"

Пример демонстрирует настройку проверки адреса репозитория в поле image у всех подов, создающихся в пространстве имен, имеющих label security.deckhouse.io/pod-policy: restricted. Если адрес в поле image создаваемого пода начинается не с mycompany.registry.com, под создан не будет.

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

Больше примеров описания проверок для расширения политики можно найти в библиотеке Gatekeeper.

Как включить одну или несколько политик Pod Security Standards, не отключая весь набор?

Чтобы применить только нужные политики безопасности, не отключая весь предустановленный набор:

  1. Добавьте в нужное пространство имён метку: security.deckhouse.io/pod-policy: privileged, чтобы отключить встроенный набор политик.
  2. Создайте ресурс SecurityPolicy, соответствующий уровню baseline или restricted. В секции policies укажите только необходимые вам настройки.
  3. Добавьте в пространство имён дополнительную метку, которая будет соответствовать селектору namespaceSelector в SecurityPolicy. В примерах ниже это security-policy.deckhouse.io/baseline-enabled: "true" либо security-policy.deckhouse.io/restricted-enabled: "true"

SecurityPolicy, соответствующая baseline:

1apiVersion: deckhouse.io/v1alpha1
2kind: SecurityPolicy
3metadata:
4  name: baseline
5spec:
6  enforcementAction: Deny
7  policies:
8    allowHostIPC: false
9    allowHostNetwork: false
10    allowHostPID: false
11    allowPrivilegeEscalation: true
12    allowPrivileged: false
13    allowedAppArmor:
14      - runtime/default
15      - localhost/*
16    allowedCapabilities:
17      - AUDIT_WRITE
18      - CHOWN
19      - DAC_OVERRIDE
20      - FOWNER
21      - FSETID
22      - KILL
23      - MKNOD
24      - NET_BIND_SERVICE
25      - SETFCAP
26      - SETGID
27      - SETPCAP
28      - SETUID
29      - SYS_CHROOT
30    allowedHostPaths: []
31    allowedHostPorts:
32      - max: 0
33        min: 0
34    allowedProcMount: Default
35    allowedUnsafeSysctls:
36      - kernel.shm_rmid_forced
37      - net.ipv4.ip_local_port_range
38      - net.ipv4.ip_unprivileged_port_start
39      - net.ipv4.tcp_syncookies
40      - net.ipv4.ping_group_range
41      - net.ipv4.ip_local_reserved_ports
42      - net.ipv4.tcp_keepalive_time
43      - net.ipv4.tcp_fin_timeout
44      - net.ipv4.tcp_keepalive_intvl
45      - net.ipv4.tcp_keepalive_probes
46    seLinux:
47      - type: ""
48      - type: container_t
49      - type: container_init_t
50      - type: container_kvm_t
51      - type: container_engine_t
52    seccompProfiles:
53      allowedProfiles:
54        - RuntimeDefault
55        - Localhost
56        - undefined
57        - ''
58      allowedLocalhostFiles:
59        - '*'
60  match:
61    namespaceSelector:
62      labelSelector:
63        matchLabels:
64          security-policy.deckhouse.io/baseline-enabled: "true"

SecurityPolicy, соответствующая restricted:

1apiVersion: deckhouse.io/v1alpha1
2kind: SecurityPolicy
3metadata:
4  name: restricted
5spec:
6  enforcementAction: Deny
7  policies:
8    allowHostIPC: false
9    allowHostNetwork: false
10    allowHostPID: false
11    allowPrivilegeEscalation: false
12    allowPrivileged: false
13    allowedAppArmor:
14      - runtime/default
15      - localhost/*
16    allowedCapabilities:
17      - NET_BIND_SERVICE
18    allowedHostPaths: []
19    allowedHostPorts:
20      - max: 0
21        min: 0
22    allowedProcMount: Default
23    allowedUnsafeSysctls:
24      - kernel.shm_rmid_forced
25      - net.ipv4.ip_local_port_range
26      - net.ipv4.ip_unprivileged_port_start
27      - net.ipv4.tcp_syncookies
28      - net.ipv4.ping_group_range
29      - net.ipv4.ip_local_reserved_ports
30      - net.ipv4.tcp_keepalive_time
31      - net.ipv4.tcp_fin_timeout
32      - net.ipv4.tcp_keepalive_intvl
33      - net.ipv4.tcp_keepalive_probes
34    allowedVolumes:
35      - configMap
36      - csi
37      - downwardAPI
38      - emptyDir
39      - ephemeral
40      - persistentVolumeClaim
41      - projected
42      - secret
43    requiredDropCapabilities:
44      - ALL
45    runAsUser:
46      rule: MustRunAsNonRoot
47    seLinux:
48      - type: ""
49      - type: container_t
50      - type: container_init_t
51      - type: container_kvm_t
52      - type: container_engine_t
53    seccompProfiles:
54      allowedProfiles:
55        - RuntimeDefault
56        - Localhost
57      allowedLocalhostFiles:
58        - '*'
59  match:
60    namespaceSelector:
61      labelSelector:
62        matchLabels:
63          security-policy.deckhouse.io/restricted-enabled: "true"

Что, если несколько политик (операционных или безопасности) применяются на один объект?

В этом случае необходимо, чтобы конфигурация объекта соответствовала всем политикам, которые на него распространяются.

Например, рассмотрим две следующие политики безопасности:

1apiVersion: deckhouse.io/v1alpha1
2kind: SecurityPolicy
3metadata:
4  name: foo
5spec:
6  enforcementAction: Deny
7  match:
8    namespaceSelector:
9      labelSelector:
10        matchLabels:
11          name: test
12  policies:
13    readOnlyRootFilesystem: true
14    requiredDropCapabilities:
15    - MKNOD
16---
17apiVersion: deckhouse.io/v1alpha1
18kind: SecurityPolicy
19metadata:
20  name: bar
21spec:
22  enforcementAction: Deny
23  match:
24    namespaceSelector:
25      labelSelector:
26        matchLabels:
27          name: test
28  policies:
29    requiredDropCapabilities:
30    - NET_BIND_SERVICE

Тогда для выполнения требований приведенных политик безопасности в спецификации контейнера нужно указать:

1    securityContext:
2      capabilities:
3        drop:
4          - MKNOD
5          - NET_BIND_SERVICE
6      readOnlyRootFilesystem: true

Проверка подписи образов

Доступно в следующих редакциях: SE+, EE, CSE Lite (1.67), CSE Pro (1.67).

В модуле реализована функция проверки подписи образов контейнеров, подписанных с помощью инструмента Cosign. Проверка подписи образов контейнеров позволяет убедиться в их целостности (что образ не был изменен после его создания) и подлинности (что образ был создан доверенным источником). Включить проверку подписи образов контейнеров в кластере можно с помощью параметра policies.verifyImageSignatures ресурса SecurityPolicy.

Как подписать образ…

Шаги для подписания образа:

  • Сгенерируйте ключи: cosign generate-key-pair
  • Подпишите образ: cosign sign --key <key> <image>

Подробнее о работе с Cosign можно узнать в документации.

Пример SecurityPolicy для настройки проверки подписи образов контейнеров:

1apiVersion: deckhouse.io/v1alpha1
2kind: SecurityPolicy
3metadata:
4  name: verify-image-signatures
5spec:
6  match:
7    namespaceSelector:
8      labelSelector:
9        matchLabels:
10          kubernetes.io/metadata.name: default
11  policies:
12    verifyImageSignatures:
13      - reference: docker.io/myrepo/*
14        publicKeys:
15        - |-
16          -----BEGIN PUBLIC KEY-----
17          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
18          5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
19          -----END PUBLIC KEY-----
20      - reference: company.registry.com/*
21        dockerCfg: zxc==
22        publicKeys:
23        - |-
24          -----BEGIN PUBLIC KEY-----
25          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
26          5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
27          -----END PUBLIC KEY-----

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

Пример вывода ошибки при создании пода с образом контейнера, не прошедшим проверку подписи:

1[verify-image-signatures] Image signature verification failed: nginx:1.17.2