Skip to content

5.7 Безопасность в K8s

Безопасность k8s осуществляется на следующих основных этапах: - Безопасность docker image - Admission controllers * это специальные плагины k8s, которые перехватывают запросы к серверу API Kubernetes до сохранения объекта, производя проверку подлинности и авторизации запроса - Безопасность хоста (node) - Безопасность в рантайме (pod security admisson) - Network security - Application security

Безопасность docker

Базовые правила по обеспечения безопасности docker:

  • Регулярно устанавливайте обновления
  • Ограничивайте доступ к сокету docker и не оставляйте его без защиты
  • Создавайте и используйте непривилегированного пользователя для работы контейнера
  • Не запускайте контейнер с повышенными привилегиями
  • Используйте профильные инструменты для проверки docker образов на предмет уязвимостей
  • Ограничивайте возможности контейнера и его ресурсы
  • Предотвращайте повыщение привилегий внутри контейнера
  • Отключайте межконтейнерное взаимодействие
  • Используйте модули безопасности Linux
  • Используйте readonly ФС и docker volumes

Дополнительные правила по обеспечения безопасности docker:

  • Используйте легковесные образы ОС
  • Подписывайте и проверяйте docker-образы для митигации атак MITM
  • Используйте доверенные хранилища артефактов
  • Применяйте механизм многоэтапной сборки (multistaging)
  • Не допускайте утечки сенсетивной информации в Dockerfile
  • Используйте фиксированные теги версий образов
  • Используйте инструкцию COPY вместо ADD
  • Используйте линтеры при работе с Dockerfile
  • Используйте полноценный DevSecOps-конвейер

Базовые принципы безопасности хоста

  • Регулярно устанавливайте обновления (ОС, библиотеки, зависимости)
  • Используйте инфраструктурные сканеры (nessus, openvas greenbone, xspider)
  • По возможности, не используйте public-ip (используйте внутренние сети или VPN)

Sysdig Falco — opensource-инструмент для обнаружения аномалий и мониторинга активности в системе.

Network security

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

  • трафик в кластере по умолчанию разрещен и никак не контролируется (если не используется, к примеру, service mesh)
  • адреса подов часто меняется
  • трафик не щифруется (если не используется дополнительных средств, service mesh в том числе)

Для удобства создания манифестов длā желаемых Network Policy можно использовать инструмент cilium editor (cni cilium) - https://editor.cilium.io/

Service mesh

В обеспечении безопасности сетей в кластере вам также может помочь сервисная сетка (service mesh)

Сервисная сетка – это набор инструментов, позволяющих осуществлять мониторинг трафика между микросервисами, включая схему взаимодействия и коды HTTP-статусов между ними.

Преимущества сервисной сетки (service mesh) на базе инструмента Istio:

  • Istio – вмешательство в сетевое взаимодействие
  • Отказоустойчивость: ретрай запроса при сбое (благодаря коду ответа)
  • Канареечные выкаты: регулирует процент сетевого трафика на новой версии сервиса
  • Управление трафиком (таймауты, ретраи, балансировка)
  • Наблюдаемость: журналы, метрики, трассировки
  • Безопасность: аутентификация и авторизация, работа с токенами, контроль трафика

App security

Для обеспечения безопасности развернутых в вашем кластере k8s приложений воспользуйтесь следующими рекомендациями:

  • Используйте k8s secrets (или HashiCorp Vault в качестве альтернативы)
  • Применяйте практики devsecops (SAST, SCA, DAST, IAST, RASP)
  • Используйте сервисную сетку (service mesh) для контроля за интеграционными потоками приложений, расширенными возможностями деплоя и обновления)
  • Проводите аудит кластера с помощью профильнýх инструментов проверки: kube-hunter, kube-audit, chaos-monkey и проч.

Авторизация в Kubernetes system-admin

Из kube/conf берем поле client-certificate-data и декодируем, получаем сертификат в формате pem

echo "client-certificate-data" | base64 -d > cert.pem
Далее расшифровываем сам сертификат
openssl x509 -in cert.pem -text -noout
В сертификате определен Subject, Public-Key, Signature
1
2
3
4
5
6
---
Certificate:
    Data:
        Subject: O = system:masters, CN = system:admin
        Public-Key
        Signature Value
Найдем все права этого пользователя или группы
kubectl get rolebinding,clusterrolebinding --all-namespaces -o yaml | grep system:masters -B 20

---
- apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRoleBinding
  metadata:
    annotations:
      rbac.authorization.kubernetes.io/autoupdate: "true"
    creationTimestamp: "2024-01-16T09:35:53Z"
    labels:
      kubernetes.io/bootstrapping: rbac-defaults
    name: cluster-admin
    resourceVersion: "139"
    uid: 652339e7-38c8-4009-8ddf-adc61b7154c4
  roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: cluster-admin
  subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: Group
    name: system:masters
И теперь можно посмотреть саму роль
kubectl get clusterrole/cluster-admin -o yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2024-01-16T09:35:53Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "77"
  uid: 7a87ee32-c6bf-409b-bca6-5abe5c833c30
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

kubectl auth can-i list pods --as jean

Создание и аутентификация пользователей с помощью клиентских сертификатов X.509

1
2
3
4
openssl genrsa -out pavel.key 2048
openssl req -new -key pavel.key \\n-out pavel.csr \\n-subj "/CN=pavel"
cat pavel.csr | base64
nvim csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: pavel
spec:
  request: LS0tLS1CRULS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
1
2
3
4
5
6
7
8
kubectl apply -f csr.yaml
kubectl get csr
kubectl certificate approve pavel
kubectl get csr pavel -o jsonpath='{.status.certificate}'| base64 -d > pavel.crt
kubectl config --kubeconfig pavel-kubeconfig set-credentials pavel --client-key=pavel.key --client-certificate=pavel.crt --embed-certs=true
kubectl config --kubeconfig pavel-kubeconfig set-context pavel --user=pavel
kubectl config --kubeconfig pavel-kubeconfig get-contexts
kubectl get pods
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 namespace: default
 name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: pod-reader-binding
 namespace: default
subjects:
- kind: User
  name: pavel
  apiGroup: rbac.authorization.k8s.io
roleRef:
 kind: Role
 name: pod-reader
 apiGroup: rbac.authorization.k8s.io
1
2
3
4
kubectl apply -f prr.yaml
kubectl get pods
export KUBECONFIG=~/Documents/pavel-kubeconfig
kubectl get pods