1 - Renforcer les normes de sécurité d'un Pod

Cette page vous donne un aperçu des bonnes pratiques lorsqu'il s'agit de renforcer les Normes de Sécurité d'un Pod.

Utilsation du Contrôleur de Validation Pod Security

FEATURE STATE: Kubernetes v1.25 [stable]

Le Contrôleur de Validation Pod Security tend à remplacer PodSecurityPolicies qui est obsolète.

Configurer tous les namespaces d'une grappe

Les namespaces dépourvus de toute configuration doivent être considérés comme des lacunes importantes dans le modèle de sécurité de votre grappe. Nous recommandons de prendre le temps d'analyser les types de charges de travail qui se produisent dans chaque namespace, et en se référant aux Normes de Sécurité des Pods, de décider du niveau approprié pour chacun d'entre eux. Les namespaces non étiquetés doivent uniquement indiquer qu'ils n'ont pas encore été étudiés.

Dans le scénario où toutes les charges de travail dans tous les namespaces ont les mêmes prérequis, nous fournissons un exemple qui illustre comment les étiquettes PodSecurity peuvent être appliquées en vrac.

Adoptez le principe du moindre privilège

Dans un monde idéal, chaque pod dans chaque namespace répondrait aux exigences de la politique de restriction. Toutefois, cela n'est ni possible ni pratique, car certaines charges de travail nécessitent des privilèges élevés pour des raisons légitimes.

  • Les Namespaces autorisant les charges de travail avec des privilèges élevés devraient établir et appliquer des contrôles d'accès appropriés.
  • Pour les charges de travail s'exécutant dans ces namespaces permissifs, maintenez à jour une documentation sur leurs exigences de sécurité uniques. Si possible, envisagez comment ces exigences pourraient être encore plus strictes.

Adopter une stratégie à plusieurs modes

Le modes audit and warn des du contrôleur de validation des Normes de Sécurité de Pod facilitent la collecte d'informations importantes sur la sécurité de vos pods sans interrompre les charges de travail existantes.

C'est une bonne pratique d'activer ces modes pour tous les namespaces, en choisissant le niveau désiré et la version que vous souhaiteriez éventuellement appliquer. Les avertissements et les annotations d'audit générés dans cette phase peuvent vous guider vers cet état. Si vous vous attendez à ce que les auteurs de la charge de travail apportent des modifications pour être en cohérence avec le niveau souhaité, utilisez le mode warn. Si vous prévoyez d'utiliser les journaux d'audit pour suivre/faire avancer les changements afin qu'ils correspondent au niveau souhaité, utilisez le mode audit.

Lorsque vous avez le mode enforce choisi en tant que valeur désiré, ces autres modes peuvent tout aussi être utiles dans certains cas:

  • En choisissant le même niveau utilisé avec le mode enforce pour le mode warn, les clients recevront des avertissements lors de la création des Pods (ou des ressources qui contiennent des structures de Pod) qui n'ont pas été validés. Cela les aidera à les mettre à jour afin qu'ils soient conformes.
  • Dans les Namespaces qui utilisent le mode enforce d'une version spécifique qui n'est pas la plus récente, le fait de mettre le meme niveau que enforce pour les modes audit et warn, mais en utilisant la dernière version, permet de connaître les paramètres qui étaient autorisés par les versions précédentes, mais qui ne le sont plus selon les bonnes pratiques actuelles.

Alterntives tierces

D'autres alternatives pour renforcer les profiles de sécurité sont en cours de développement dans l'écosystem de Kubernetes:

La décision de partir sur une solution interne (ex: le contrôleur de validation PodSecurity ) plutôt qu'un outil tiers dépend complètement de votre situation. Lors de l'évaluation de toute solution, la confiance de votre chaîne d'approvisionnement est cruciale. En fin de compte, il est préférable d'opter l'une des approches susmentionnées plutôt que de ne rien faire.

2 - Certificats PKI et exigences

Kubernetes requiert les certificats gérés par PKI (Public Key Infrastructure ou ICP pour Infrastructure à Clé Publique) pour l'authentification via TLS. Si vous installez Kubernetes à l'aide de kubeadm, les certificats dont votre grappe exige sont automatiquement générés. Vous pouvez également générer vos propres certificats -- par exemple, mieux sécuriser vos clés privées en ne les stockant pas tous sur la machine hébergeant le serveur API.

Cette page liste les certificats requis par votre grappe.

Comment les certificats au sein de votre grappe sont utilisés ?

Kubernetes requiert une PKI pour les opérations suivantes:

Certificats Serveur

  • Certificat Serveur pour le serveur API.
  • Certificate Serveur pour le serveur etcd
  • Certificats Serveur pour chaque kubelet (chaque noeud exécute un kubelet)
  • Certificat Serveur optionnel pour le front-proxy

Certificats Client

  • Les certificats Client pour chaque kubelet, utilisés pour s'authentifier auprès du serveur API en tant que client de l'API de Kubernetes
  • Certificat Client pour chaque serveur API, utilisé pour s'authentifier en tant que client auprès de etcd
  • Certificat Client pour le gestionnaire de contrôleurs afin de sécuriser la communication avec le serveur API
  • Certificat Client pour le planificateur afin de sécuriser la communication avec le serveur API
  • Certificat Client, un pour chaque noeud, pour kube-proxy pour s'authentifier auprès du serveur API
  • Certificats Client optionnels pour les administrateurs de la grappe afin de s'authentifier auprès du serveur API
  • Certificat Client optionnel pour le front-proxy

Certificats client et serveur pour Kubelet

Pour établir une connexion sécurisée et s'authentifier lui-même auprès de kubelet, le serveur API a besoin d'une paire certificat client/clé privée.

Dans ce scénario, il existe deux approches pour l'utilisation du certificat:

  • Certificat et clé privée partagés: kube-apiserver peut utiliser le même certificat et la même clé privée que ceux qu'il utilise pour permettre l'authentification de ses clients. C'est-à-dire, les fichiers existant, dont apiserver.crt et apiserver.key, peuvent être utilisés pour communiquer avec les serveurs kubelet.

  • Certficat et clé privée distincts: D'un autre côté, kube-apiserver peut utiliser un autre certificat et une autre clé privée afin de s'authentifier auprès des serveurs kubelet. Dans ce cas précis, un nouveau certificat nommé kubelet-client.crt et la clé privée lui correspondant, kubelet-client.key devront alors être créés.

etcd implemente également le Mutual TLS (mTLS) pour authentifier ses clients et les peer.

Où sont stockés les certificats ?

Si vous installez Kubernetes à l'aide de kubeadm, la plupart des certificats se trouvent dans /etc/kubernetes/pki. Tous les chemins des fichiers dans cette documentation sont relatifs à ce dossier, sauf ceux des certificats du compte utilisateur dont la base est plutôt /etc/kubernetes, et que cette dernière soit l'emplacement par défaut utilisé par kubeadm pour stocker ces certificats.

Configurer manuellement les certificats

Si vous ne souhaitez pas utiliser kubeadm pour générer les certificats requis, vous pouvez les créer manuellement. Voir Certificats pour plus de détails sur la création de votre propre certificat racine et les certificats issus de ce dernier. Voir Gestion des certificats avec kubeadm pour en savoir plus sur la gestion des certificats.

Certificat racine principal

Vous pouvez créer un certificat racine principal, controllé par un administrateur. Ce certificat racine principal permet ensuite de créer de multiples certificats racine intermédiaires, et déléguer toute création supplémentaire à Kubernetes lui-même.

Certificats racines requis:

Chemin CN par défaut Description
ca.crt,key kubernetes-ca Certificat racine et sa clé privée par défaut de Kubernetes
etcd/ca.crt,key etcd-ca Pour tout ce qui est lié à etcd
front-proxy-ca.crt,key kubernetes-front-proxy-ca Pour le front-end proxy

Avant les certificats racines précedent, il est aussi nécessaire d'avoir un couple de clés publiaue/privé pour la gestion du service account, sa.key and sa.pub. L'exemple ci-dessous illustre les fichiers vus dans le tableau précédent:

/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
/etc/kubernetes/pki/etcd/ca.crt
/etc/kubernetes/pki/etcd/ca.key
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-ca.key

Tous les certificats

Si vous ne souhaitez pas stocker les clés privées de vos certificats racine au sein de votre grappe, vous pouvez génrer tous les certificqts en dehors de cette dernière.

Certificats requis:

CN par défaut CN du certificat racine O (dans Subject) Key usage SAN
kube-etcd etcd-ca server, client <nom d'hôte>, <IP de l'hôte>, localhost, 127.0.0.1
kube-etcd-peer etcd-ca server, client <nom d'hôte>, <IP de l'hôte>, localhost, 127.0.0.1
kube-etcd-healthcheck-client etcd-ca client
kube-apiserver-etcd-client etcd-ca client
kube-apiserver kubernetes-ca server <nom d'hôte>, <IP de l'hôte>, <advertise_IP>1
kube-apiserver-kubelet-client kubernetes-ca system:masters client
front-proxy-client kubernetes-front-proxy-ca client

kind correspond à une ou plusieurs valeurs de key usqge de x509 (dont key usage est une extension du standard x509), qui est documenté ici .spec.usages pour le type CertificateSigningRequest:

kind Key usage
server digital signature, key encipherment, server auth
client digital signature, key encipherment, client auth

Les emplacements des Certificats

Les certificats devraient être placés dans un emplacement recommandé (tel qu'utilisé par kubeadm). Les chemins doivent être spécifiés en utilisant l'argument donné, quel que soit l'emplacement.

| CN par défaut | Chemin recommandé de la clé privée | Chemin recommandé pour le certificat | Commande | Argument pour la clé privée | Argument pour le certificat | |-------------------------------| | ------------------- | ------- | ----------- | ------------ | | etcd-ca | etcd/ca.key | etcd/ca.crt | kube-apiserver | | --etcd-cafile | | kube-apiserver-etcd-client | apiserver-etcd-client.key | apiserver-etcd-client.crt | kube-apiserver | --etcd-keyfile | --etcd-certfile | | kubernetes-ca | ca.key | ca.crt | kube-apiserver | | --client-ca-file | | kubernetes-ca | ca.key | ca.crt | kube-controller-manager | --cluster-signing-key-file | --client-ca-file,--root-ca-file,--cluster-signing-cert-file | | kube-apiserver | apiserver.key | apiserver.crt| kube-apiserver | --tls-private-key-file | --tls-cert-file | | kube-apiserver-kubelet-client | apiserver-kubelet-client.key | apiserver-kubelet-client.crt | kube-apiserver | --kubelet-client-key | --kubelet-client-certificate | | front-proxy-ca | front-proxy-ca.key | front-proxy-ca.crt | kube-apiserver | | --requestheader-client-ca-file | | front-proxy-ca | front-proxy-ca.key | front-proxy-ca.crt | kube-controller-manager | | --requestheader-client-ca-file | | front-proxy-client | front-proxy-client.key | front-proxy-client.crt | kube-apiserver | --proxy-client-key-file | --proxy-client-cert-file | | etcd-ca | etcd/ca.key | etcd/ca.crt | etcd | | --trusted-ca-file,--peer-trusted-ca-file | | kube-etcd | etcd/server.key | etcd/server.crt | etcd | --key-file | --cert-file | | kube-etcd-peer | etcd/peer.key | etcd/peer.crt | etcd | --peer-key-file | --peer-cert-file | | etcd-ca | | etcd/ca.crt | etcdctl | | --cacert | | kube-etcd-healthcheck-client | etcd/healthcheck-client.key | etcd/healthcheck-client.crt | etcdctl | --key | --cert |

Les mêmes recommandations s'appliquent pour la paire de clés du service account:

Chemin de la clé privée Chemin de la clé publique Commande Argument
sa.key kube-controller-manager --service-account-private-key-file
sa.pub kube-apiserver --service-account-key-file

L'example suivant illustrate les chemins des fichiers du précédent tableau dont vous devez mettre en place si vous générez vous-même tous vos clés privées et vos certificats:

/etc/kubernetes/pki/etcd/ca.key
/etc/kubernetes/pki/etcd/ca.crt
/etc/kubernetes/pki/apiserver-etcd-client.key
/etc/kubernetes/pki/apiserver-etcd-client.crt
/etc/kubernetes/pki/ca.key
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/apiserver.key
/etc/kubernetes/pki/apiserver.crt
/etc/kubernetes/pki/apiserver-kubelet-client.key
/etc/kubernetes/pki/apiserver-kubelet-client.crt
/etc/kubernetes/pki/front-proxy-ca.key
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-client.key
/etc/kubernetes/pki/front-proxy-client.crt
/etc/kubernetes/pki/etcd/server.key
/etc/kubernetes/pki/etcd/server.crt
/etc/kubernetes/pki/etcd/peer.key
/etc/kubernetes/pki/etcd/peer.crt
/etc/kubernetes/pki/etcd/healthcheck-client.key
/etc/kubernetes/pki/etcd/healthcheck-client.crt
/etc/kubernetes/pki/sa.key
/etc/kubernetes/pki/sa.pub

Configurer les certificats pour les comptes utilisateur

Vous devez manuellement configurer ces comptes administrateurs et les comptes de services:

Fichier Identifiant CN par défaut O (dans Subject)
admin.conf default-admin kubernetes-admin <admin-group>
super-admin.conf default-super-admin kubernetes-super-admin system:masters
kubelet.conf default-auth system:node:<nom du noeud> (voir la remarque) system:nodes
controller-manager.conf default-controller-manager system:kube-controller-manager
scheduler.conf default-scheduler system:kube-scheduler
  1. Pour chaque configuration, générez une paire certificat/clé privée x509 avec le Common Name (CN) et le Organization (O) fournis.

  2. Exécutez kubectl comme suit pour chaque configuration:

    KUBECONFIG=<filename> kubectl config set-cluster default-cluster --server=https://<host ip>:6443 --certificate-authority <path-to-kubernetes-ca> --embed-certs
    KUBECONFIG=<filename> kubectl config set-credentials <credential-name> --client-key <path-to-key>.pem --client-certificate <path-to-cert>.pem --embed-certs
    KUBECONFIG=<filename> kubectl config set-context default-system --cluster default-cluster --user <credential-name>
    KUBECONFIG=<filename> kubectl config use-context default-system
    

Ces fichiers sont utilisés comme suit:

Nom de fichier Commande Commentaire
admin.conf kubectl Configure l'administrateur du cluster
super-admin.conf kubectl Configure le super administrateur du cluster
kubelet.conf kubelet Un seul requis pour chaque noeud du cluster.
controller-manager.conf kube-controller-manager Doit être ajouté au fichier manifeste manifests/kube-controller-manager.yaml
scheduler.conf kube-scheduler Doit être ajouté au fichier manifeste manifests/kube-scheduler.yaml

Les fichiers suivant illustrent les chemins absolues des fichiers listés dans le tableau précédent:

/etc/kubernetes/admin.conf
/etc/kubernetes/super-admin.conf
/etc/kubernetes/kubelet.conf
/etc/kubernetes/controller-manager.conf
/etc/kubernetes/scheduler.conf

  1. tout autre IP ou nom DNS sur lequel joindre votre grappe (comme ceux utilisés par kubeadm, l'adresse IP et/ou le nom DNS du répartisseur de charge, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster, kubernetes.default.svc.cluster.local↩︎