Skip to content
Back to blog

Durcissement de la Sécurité Kubernetes : Les Contrôles qui Comptent en Production

La configuration par défaut de Kubernetes est conçue pour faciliter le démarrage, pas pour la sécurité en production. Après avoir audité une douzaine de clusters dans les secteurs finance, télécoms et SaaS, les mêmes lacunes apparaissent dans presque tous. Cet article couvre les contrôles avec le meilleur ratio impact/effort, ceux que vous pouvez implémenter cette semaine.

Le Modèle de Menace

Avant de durcir quoi que ce soit, soyez clair sur ce que vous défendez :

  1. Charge de travail compromise - un conteneur est pénétré via une vulnérabilité dans l’application ou ses dépendances. Peut-il atteindre l’API Server ? Peut-il se déplacer latéralement vers d’autres pods ?
  2. Threat interne - un développeur ou un pipeline CI obtient plus d’accès que nécessaire. Peut-il lire les secrets des autres namespaces ?
  3. Image malveillante - une image compromise est déployée dans votre cluster. S’exécute-t-elle avec des privilèges root ? Peut-elle modifier les binaires du système hôte ?

Chaque contrôle ci-dessous adresse au moins un de ces scénarios.

Contrôle 1 : RBAC - Moindre Privilège Réel

L’erreur la plus fréquente que j’observe : accorder ClusterAdmin à des comptes de service parce que c’est “plus simple”. Ce n’est pas plus simple. C’est une bombe à retardement.

Ce que j’ai trouvé dans un audit récent :

Terminal window
kubectl get clusterrolebindings -o json | \
jq '.items[] | select(.roleRef.name == "cluster-admin") | .subjects[]'

Résultat : 14 comptes de service avec des droits cluster-admin dans un cluster de 200 nœuds. Dont l’opérateur de monitoring et le runner CI.

La règle : créez des rôles avec uniquement les verbes et ressources nécessaires.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deploy-only
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]

Contrôle 2 : Network Policies - Segmentation par Défaut

Par défaut, chaque pod peut communiquer avec chaque autre pod dans le cluster. C’est catastrophique pour la sécurité.

Commencez par une politique de refus global, puis autorisez explicitement :

# Default deny all ingress and egress in a namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress

Puis autorisez uniquement ce qui est nécessaire :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080

Contrôle 3 : Pod Security Standards

Depuis Kubernetes 1.25, les Pod Security Standards remplacent les PodSecurityPolicies dépréciées. Configurez-les au niveau namespace :

apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted

Le profil restricted interdit :

  • Les conteneurs s’exécutant en root
  • L’escalade de privilèges
  • Les capacités Linux dangereuses
  • Le montage des chemins sensibles de l’hôte

Pour les applications legacy qui nécessitent root, utilisez le profil baseline et documentez explicitement pourquoi.

Contrôle 4 : Secrets Management - Sortir d’etcd

Les secrets Kubernetes sont encodés en base64, pas chiffrés. N’importe qui ayant accès à etcd peut les lire. N’importe qui pouvant exec dans un pod peut lire les secrets montés.

L’approche que nous recommandons :

  1. Chiffrement au repos d’etcd (configurer EncryptionConfiguration)
  2. Intégration avec un gestionnaire de secrets externe (HashiCorp Vault ou AWS Secrets Manager)
  3. Rotation automatique via l’opérateur External Secrets
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: db-credentials
data:
- secretKey: password
remoteRef:
key: production/db
property: password

Contrôle 5 : Audit Logging et Détection

Sans logs d’audit, vous volez à l’aveugle. Activez l’audit au niveau API Server et cherchez ces patterns :

audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: Metadata
resources:
- group: ""
resources: ["pods", "services"]

Signaux d’alerte à surveiller :

  • exec dans des pods en production hors heures de bureau
  • Création de nouveaux ClusterRoleBindings
  • Accès aux secrets depuis des IPs inhabituelles
  • Téléchargements d’images depuis des registries non approuvés

Bilan

Implémenter ces cinq contrôles réduit drastiquement votre surface d’attaque. La priorité recommandée :

  1. RBAC audit et nettoyage (impact immédiat, effort faible)
  2. Network Policies sur les namespaces critiques (impact élevé, effort moyen)
  3. Pod Security Standards en mode warn d’abord (transition douce)
  4. Audit logging (visibilité immédiate)
  5. External Secrets (effort plus élevé, valeur à long terme)

La sécurité Kubernetes n’est pas un projet ponctuel. C’est un processus continu d’audit, de remédiation et d’amélioration. Commencez par ce qui fait le plus mal, mesurez, itérez.


Share LinkedIn X

Related posts