Всем привет. Меня зовут Добрый Кот Telegram.
От коллектива FR-Solutions и при поддержке @irbgeo Telegram : Хочу поделиться с вами своим опытом на тему сертификатов в кубе.
* Будет серия статей, в которых постараюсь описать свой опыт перехода от самоподписанных сертификатов к централизованному обслуживанию сертификатов через vault.
** В этой статье будет затронута тема базовой организации сертификатов.
Думаю, многие из вас уже не раз разворачивали k8s кластера. Вы пользовались разными инструментами (kubespray, kubeadm, hardway, или просто брали менедж куб от облачного провайдера). Все эти решения реализуют за вас ряд сценариев, которые когда-то кто-то делал руками, но ему это надоело, и он сделал автоматизацию. Одна из таких автоматизаций - выписывание сертификатов кластера k8s.
Кто из вас вспомнит:
Из скольки сертификатов состоит куб?
Cколько Certificate Authority в кластере и для чего их несколько?
У кого какой common name, какие organization, usages, alternative names у каждого сертификата?
Какие сертификаты используются сразу в нескольких компонентах кластера?
Кто из вас с первой попытки соберет пазл с сертификатами?
Попробуете пройти путь джедая?)
Итак. Начну сразу с картинки.
Немного поясню, что там нарисовано:
блоки синего цвета - базовые сертификаты k8s;
блоки зеленого цвета - сертификаты расширения API;
блоки фиолетового цвета - сертификаты для etcd и интеграции с ним;
блок красного цвета это rsa ключ для выпуска JWT токенов;
линии связи указывают, кто использует сертификаты и ключи;
блоки посередине, куда ведут стрелки от блоков с сертификатами – компоненты k8s.
В базовой комплектации должны получить 13 сертификатов 3 СА и один RSA ключ.
Несколько интересных наблюдений:
Все компоненты используют публичные ключи от CA, за исключением kube-controller-manager.
kube-controller-manager использует root-ca-key для выпуска сертификатов.
Сертификат etcd-health-check-client не используется компонентами k8s (используется для подключения к etcd через etcdctl)*.
Теперь давайте заглянем внутрь сертификатов:
Компонент | key | name | CN | Organization | Usages | CA |
etcd | --trusted-ca-file | etcd-ca | (any) | (any) | CA | etcd-ca |
--cert-file | etcd-server | (any) | (any) | DigitalSignature,KeyEncipherment,ServerAuth | etcd-ca | |
-key-file | etcd-server-key | - | - | - | - | |
--peer-trusted-ca-file | etcd-peer | (any) | (any) | DigitalSignature,KeyEncipherment,ServerAuth,ClientAuth | etcd-ca | |
--peer-key-file | etcd-peer-key | - | - | - | - | |
etcdctl | --cert | etcd-health-check-client | (any) | DigitalSignature,KeyEncipherment,ClientAuth | etcd-ca | |
--key | etcd-health-check-client-key | - | - | - | - | |
kube-apiserver | --client-ca-file | root-ca | system:kube-apiserver-etcd-client, system:etcd-healthcheck-client | (any) | CA | root-ca |
--tls-cert-file | kube-apiserver-server | localhost kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster kubernetes.default.svc.cluster.local ${api-fqdn} | (any) | DigitalSignature,KeyEncipherment,ServerAuth | root-ca | |
--tls-private-key-file | kube-apiserver-server-key | - | - | - | ||
--etcd-cafile | etcd-ca | (any) | (any) | CA | etcd-ca | |
--etcd-certfile | kube-apiserver-etcd-client | (any) | (any) | DigitalSignature,KeyEncipherment,ClientAuth | etcd-ca | |
--etcd-keyfile | kube-apiserver-etcd-client-key | - | - | - | - | |
--kubelet-client-certificate | kube-apiserver-kubelet-client | (any) | system:masters | DigitalSignature,KeyEncipherment,ClientAuth | root-ca | |
--kubelet-client-key | kube-apiserver-kubelet-client-key | - | - | - | - | |
--proxy-client-cert-file | front-proxy-client | (any) | (any) | DigitalSignature,KeyEncipherment,ClientAuth | front-proxy-ca | |
--requestheader-client-ca-file | front-proxy-ca | (any) | (any) | CA | fron-proxy-ca | |
--service-account-key-file | SA*-pub | - | - | - | - | |
--service-account-signing-key-file | SA*-key | - | - | - | - | |
kube-controller-manager | --root-ca-file | root-ca | (any) | (any) | CA | root-ca |
--client-ca-file | root-ca | (any) | (any) | CA | root-ca | |
--requestheader-client-ca-file | frot-proxy-ca | (any) | (any) | CA | frot-proxy-ca | |
--tls-cert-file | kube-controller-manager-server | localhost kube-controller-manager.default kube-controller-manager.default.svc kube-controller-manager.default.svc.cluster kube-controller-manager.default.svc.cluster.local | (any) | DigitalSignature,KeyEncipherment,ServerAuth | root-ca | |
--tls-private-key-file | kube-controller-manager-server-key | - | - | - | - | |
--cluster-signing-cert-file | root-ca | (any) | (any) | CA | root-ca | |
--cluster-signing-key-file | root-ca-key | - | - | - | - | |
--service-account-private-key-file | SA*-key | - | - | - | - | |
kubeconfig | kube-controller-manager-client | system:kube-controller-manager | (any) | DigitalSignature,KeyEncipherment,ClientAuth | root-ca | |
kube-scheduler | --client-ca-file | root-ca | (any) | (any) | CA | root-ca |
--requestheader-client-ca-file | fron-proxy-ca | (any) | (any) | CA | fron-proxy-ca | |
--tls-cert-file | kube-scheduler-server | localhost kube-scheduler.default kube-scheduler.default.svc kube-scheduler.default.svc.cluster kube-scheduler.default.svc.cluster.local | (any) | DigitalSignature,KeyEncipherment,ServerAuth | root-ca | |
| kube-scheduler-server-key | |||||
kubeconfig | kube-scheduler-client | system:kube-scheduler | (any) | DigitalSignature,KeyEncipherment,ClientAuth | root-ca | |
kubelet | kubeconfig | kubelet-client | system:node:{hostname} | system:nodes | DigitalSignature,KeyEncipherment,ClientAuth | root-ca |
kubelet-server | localhost system:node:* |
CN | Organization | Cluster Role | type |
system:kube-scheduler | system:volume-scheduler | User | |
system:kube-scheduler | system:kube-scheduler | User | |
system:kube-controller-manager | system:kube-controller-manager | User | |
system:nodes | system:node | Group | |
system:masters | cluster-admin | Group |
(any) - можно указывать любое значение кроме system:* , если не хотите случайно дать лишние права в k8s
Итого:
Визуально мы видим какие сертификаты +- безопасны, а какие нет.
Видим излишние привилегии у kube-controller-manager и что он может создавать сертификаты любого типа прямо из k8s-api.
Имеем риск кражи приватных ключей с мастеров.
Требуется дополнительные ограничения в ролевых политиках, чтобы пользователю нельзя было подписывать сертификат базовыми сущностями certificate и csr approve.
Имеем сложный процесс обновления сертификатов, и еще сложнее, если надо обновлять сертификат CA.
P.S. Все выше написанное – ИМХО и может отличаться от вашего мнения. По неточностям в статье буду рад услышать комментарии и разумную критику. Всем пис.
Подписывайтесь, ставьте лайк если понравилась статья и подключайтесь к нам в телеграмм для обсуждения.
полезное чтиво:
https://kubernetes.io/docs/setup/best-practices/certificates/
https://etcd.io/docs/v3.2/op-guide/security/
https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/
https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/
https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/