Guide de Sécurisation d'un Cluster Kubernetes

Principes Fondamentaux de la Sécurité

La sécurisation d'un cluster Kubernetes repose sur une approche multicouche. Chaque couche doit être configurée pour minimiser les risques, du réseau jusqu'aux conteneurs.

Couche Mesure de Protection Solution
Cluster Contrôle d'accès (RBAC) Principe du moindre privilège
Réseau Politiques réseau Modèle zéro confiance
Conteneur Analyse d'images Détection de vulnérabilités
Runtime Normes de sécurité Pod Restreindre les conteneurs privilégiés
Données Gestion des secrets Intégration avec HashiCorp Vault

Configuration Pratique

Gestion des Droits avec RBAC

Un exemple de configuration RBAC pour limiter l'accès en lecture aux pods dans un namespace spécifique :

<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">rbac.authorization.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Role</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">production</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-viewer</span>
<span class="hljs-attr">rules:</span>
- <span class="hljs-attr">apiGroups:</span> [<span class="hljs-string">""</span>]
  <span class="hljs-attr">resources:</span> [<span class="hljs-string">"pods"</span>]
  <span class="hljs-attr">verbs:</span> [<span class="hljs-string">"get"</span>, <span class="hljs-string">"watch"</span>, <span class="hljs-string">"list"</span>]
---
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">rbac.authorization.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">RoleBinding</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">grant-pod-view</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">production</span>
<span class="hljs-attr">subjects:</span>
- <span class="hljs-attr">kind:</span> <span class="hljs-string">User</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">dev-user</span>
  <span class="hljs-attr">apiGroup:</span> <span class="hljs-string">rbac.authorization.k8s.io</span>
<span class="hljs-attr">roleRef:</span>
  <span class="hljs-attr">kind:</span> <span class="hljs-string">Role</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-viewer</span>
  <span class="hljs-attr">apiGroup:</span> <span class="hljs-string">rbac.authorization.k8s.io</span>

Politiques Réseau

Pour implémenter une isolation réseau stricte, on combine une politique de refus total avec une règle d'autorisation spécifique :

<span class="hljs-comment"># Politique par défaut : tout bloquer</span>
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
<span class="hljs-comment"># Autoriser le trafic entrant uniquement depuis les pods frontend</span>
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: <span class="hljs-number">8080</span>

Normes de Sécurité des Pods

Une PodSecurityPolicy (PSP) restreint les capacités des contenerus. Voici un exemple restreignant l'élévation de privilèges :

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: strict-policy
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: <span class="hljs-string">'runtime/default'</span>
    apparmor.security.beta.kubernetes.io/allowedProfileNames: <span class="hljs-string">'runtime/default'</span>
spec:
  privileged: <span class="hljs-literal">false</span>
  allowPrivilegeEscalation: <span class="hljs-literal">false</span>
  requiredDropCapabilities:
    - <span class="hljs-keyword">ALL</span>
  runAsUser:
    rule: <span class="hljs-string">'MustRunAsNonRoot'</span>
  seLinux:
    rule: <span class="hljs-string">'RunAsAny'</span>
  fsGroup:
    rule: <span class="hljs-string">'MustRunAs'</span>
    ranges:
    - min: <span class="hljs-number">1</span>
      max: <span class="hljs-number">65535</span>
  volumes:
  - <span class="hljs-string">'configMap'</span>
  - <span class="hljs-string">'emptyDir'</span>
  - <span class="hljs-string">'projected'</span>
  - <span class="hljs-string">'secret'</span>
  - <span class="hljs-string">'downwardAPI'</span>

Sécurité des Images

L'analyse des images est cruciale. Nous utilisons Trivy dans un pipeline GitLab CI pour détecter les vulnérabilités critiques :

<span class="hljs-comment"># Installation de Trivy</span>
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.49.1

<span class="hljs-comment"># Analyse rapide</span>
trivy image nginx:alpine

<span class="hljs-comment"># Configuration CI</span>
cat > .gitlab-ci.yml << <span class="hljs-string">'EOF'</span>
<span class="hljs-string">image_scan:</span>
<span class="hljs-string">  stage: test</span>
<span class="hljs-string">  script:</span>
<span class="hljs-string">    - trivy image --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA</span>
<span class="hljs-string">  allow_failure: true</span>
<span class="hljs-string">EOF</span>

Gestion des Secrets avec Vault

L'intégration avec Vault permet de centraliser et de rafraîchir automatiquement les secrets :

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: app-credentials
  namespace: production
spec:
  type: kv-v2
  mount: kv
  path: apps/production
  refreshAfter: 30m
  destination:
    name: app-secrets
    create: true
  rolloutRestartTargets:
  - kind: Deployment
    name: backend-service

Surveillance et Détection des Menaces

Journal d'Audit

Configuration de l'audit pour capturer chaque requête sur des ressources sensibles :

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  resources:
  - group: <span class="hljs-string">""</span>
    resources: [<span class="hljs-string">"secrets"</span>, <span class="hljs-string">"configmaps"</span>]
- level: Metadata
  resources:
  - group: <span class="hljs-string">""</span>
    resources: [<span class="hljs-string">"pods"</span>, <span class="hljs-string">"services"</span>]

Détection Réseau avec Falco

Falco surveille les appels système et génère des alertes en cas d'activité suspecte :

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco-agent
  namespace: security
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      containers:
      - name: falco
        image: falcosecurity/falco:latest
        securityContext:
          privileged: true
        volumeMounts:
        - name: config
          mountPath: /etc/falco
      volumes:
      - name: config
        configMap:
          name: falco-rules

Liste de Contrôle

  1. Cluster : Activer RBAC, configurer les politiques réseau, appliquer la norme Pod Security, activer la journalisation d'audit.
  2. Conteneurs : Utiliser des images minimales, analyser les vulnérabilités, restreindre les privilèges (pas de privileged: true), définir des limites de ressources.
  3. Réseau : Appliquer des NetworkPolicies, configurer un Ingress Controller, activer TLS pour tout le trafic externe, limiter les accès sortants.
  4. Données : Stocker les secrets dans Kubernetes Secrets ou un gestionnaire externe, intégrer Vault, chiffrer les volumes persistants.

Problèmes Courants et Solutions

  • Conteneurs privilégiés : Éviter privileged: true. Utiliser securityContext pour limiter les capacités.
  • Images vulnérables : Mettre en place une analyse systématique (Trivy, Clair) et n'utiliser que des images officeilles ou vérifiées.
  • Exposition réseau : Appliquer des politiques réseau restrictives par défaut (deny all) et n'autoriser que le trafic nécesssaire.
  • Fuites de secrets : Ne jamais coder en dur. Utiliser Secrets, Vault ou des solutions équivalentes.

La sécurisation d'un cluster Kubernetes est un processus continu. En suivant ces pratiques, vous réduirez considérablement la surface d'attaque.

Étiquettes: kubernetes RBAC NetworkPolicy PodSecurityPolicy trivy

Publié le 16 juin à 18h32