mtls-configuration

Par wshobson · agents

Configurez le TLS mutuel (mTLS) pour une communication service à service sans confiance implicite (zero-trust). À utiliser lors de la mise en œuvre d'un réseau zero-trust, de la gestion de certificats ou de la sécurisation des communications entre services internes.

npx skills add https://github.com/wshobson/agents --skill mtls-configuration

Configuration mTLS

Guide complet pour implémenter TLS mutuel pour la communication de maillage de services sans confiance.

Quand utiliser cette compétence

  • Implémenter une mise en réseau sans confiance
  • Sécuriser la communication de service à service
  • Rotation et gestion des certificats
  • Déboguer les problèmes de poignée de main TLS
  • Exigences de conformité (PCI-DSS, HIPAA)
  • Communication sécurisée multi-cluster

Concepts fondamentaux

1. Flux mTLS

┌─────────┐                              ┌─────────┐
│ Service │                              │ Service │
│    A    │                              │    B    │
└────┬────┘                              └────┬────┘
     │                                        │
┌────┴────┐      Poignée de main TLS    ┌────┴────┐
│  Proxy  │◄───────────────────────────►│  Proxy  │
│(Sidecar)│  1. ClientHello             │(Sidecar)│
│         │  2. ServerHello + Cert      │         │
│         │  3. Client Cert             │         │
│         │  4. Vérifier les deux Certs │         │
│         │  5. Canal chiffré           │         │
└─────────┘                              └─────────┘

2. Hiérarchie des certificats

Root CA (Auto-signé, longue durée)
    │
    ├── Intermediate CA (Niveau cluster)
    │       │
    │       ├── Workload Cert (Service A)
    │       └── Workload Cert (Service B)
    │
    └── Intermediate CA (Multi-cluster)
            │
            └── Certificats cross-cluster

Templates

Template 1 : Istio mTLS (Mode strict)

# Activer mTLS strict sur tout le maillage
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
---
# Remplacement au niveau de l'espace de noms (permissif pour migration)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: legacy-namespace
spec:
  mtls:
    mode: PERMISSIVE
---
# Politique spécifique à la charge de travail
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: payment-service
  namespace: production
spec:
  selector:
    matchLabels:
      app: payment-service
  mtls:
    mode: STRICT
  portLevelMtls:
    8080:
      mode: STRICT
    9090:
      mode: DISABLE # Port des métriques, pas de mTLS

Template 2 : Istio Destination Rule pour mTLS

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: default
  namespace: istio-system
spec:
  host: "*.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
# TLS vers un service externe
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: external-api
spec:
  host: api.external.com
  trafficPolicy:
    tls:
      mode: SIMPLE
      caCertificates: /etc/certs/external-ca.pem
---
# TLS mutuel vers un service externe
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: partner-api
spec:
  host: api.partner.com
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/certs/client.pem
      privateKey: /etc/certs/client-key.pem
      caCertificates: /etc/certs/partner-ca.pem

Template 3 : Cert-Manager avec Istio

# Installer l'émetteur cert-manager pour Istio
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: istio-ca
spec:
  ca:
    secretName: istio-ca-secret
---
# Créer le secret CA Istio
apiVersion: v1
kind: Secret
metadata:
  name: istio-ca-secret
  namespace: cert-manager
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-ca-cert>
  tls.key: <base64-encoded-ca-key>
---
# Certificat pour la charge de travail
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: my-service-cert
  namespace: my-namespace
spec:
  secretName: my-service-tls
  duration: 24h
  renewBefore: 8h
  issuerRef:
    name: istio-ca
    kind: ClusterIssuer
  commonName: my-service.my-namespace.svc.cluster.local
  dnsNames:
    - my-service
    - my-service.my-namespace
    - my-service.my-namespace.svc
    - my-service.my-namespace.svc.cluster.local
  usages:
    - server auth
    - client auth

Template 4 : Intégration SPIFFE/SPIRE

# Configuration du serveur SPIRE
apiVersion: v1
kind: ConfigMap
metadata:
  name: spire-server
  namespace: spire
data:
  server.conf: |
    server {
      bind_address = "0.0.0.0"
      bind_port = "8081"
      trust_domain = "example.org"
      data_dir = "/run/spire/data"
      log_level = "INFO"
      ca_ttl = "168h"
      default_x509_svid_ttl = "1h"
    }

    plugins {
      DataStore "sql" {
        plugin_data {
          database_type = "sqlite3"
          connection_string = "/run/spire/data/datastore.sqlite3"
        }
      }

      NodeAttestor "k8s_psat" {
        plugin_data {
          clusters = {
            "demo-cluster" = {
              service_account_allow_list = ["spire:spire-agent"]
            }
          }
        }
      }

      KeyManager "memory" {
        plugin_data {}
      }

      UpstreamAuthority "disk" {
        plugin_data {
          key_file_path = "/run/spire/secrets/bootstrap.key"
          cert_file_path = "/run/spire/secrets/bootstrap.crt"
        }
      }
    }
---
# DaemonSet de l'agent SPIRE (abrégé)
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: spire-agent
  namespace: spire
spec:
  selector:
    matchLabels:
      app: spire-agent
  template:
    spec:
      containers:
        - name: spire-agent
          image: ghcr.io/spiffe/spire-agent:1.8.0
          volumeMounts:
            - name: spire-agent-socket
              mountPath: /run/spire/sockets
      volumes:
        - name: spire-agent-socket
          hostPath:
            path: /run/spire/sockets
            type: DirectoryOrCreate

Template 5 : Linkerd mTLS (Automatique)

# Linkerd active mTLS automatiquement
# Vérifier avec :
# linkerd viz edges deployment -n my-namespace

# Pour les services externes sans mTLS
apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
  name: external-api
  namespace: my-namespace
spec:
  podSelector:
    matchLabels:
      app: my-app
  port: external-api
  proxyProtocol: HTTP/1 # ou TLS pour passthrough
---
# Ignorer TLS pour un port spécifique
apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations:
    config.linkerd.io/skip-outbound-ports: "3306" # MySQL

Rotation des certificats

# Istio - Vérifier l'expiration du certificat
istioctl proxy-config secret deploy/my-app -o json | \
  jq '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | \
  tr -d '"' | base64 -d | openssl x509 -text -noout

# Forcer la rotation du certificat
kubectl rollout restart deployment/my-app

# Vérifier l'identité Linkerd
linkerd identity -n my-namespace

Déboguer les problèmes mTLS

# Istio - Vérifier si mTLS est activé
istioctl authn tls-check my-service.my-namespace.svc.cluster.local

# Vérifier l'authentification par pairs
kubectl get peerauthentication --all-namespaces

# Vérifier les règles de destination
kubectl get destinationrule --all-namespaces

# Déboguer la poignée de main TLS
istioctl proxy-config log deploy/my-app --level debug
kubectl logs deploy/my-app -c istio-proxy | grep -i tls

# Linkerd - Vérifier l'état de mTLS
linkerd viz edges deployment -n my-namespace
linkerd viz tap deploy/my-app --to deploy/my-backend

Bonnes pratiques

À faire

  • Commencer avec PERMISSIVE - Migrer progressivement vers STRICT
  • Surveiller l'expiration des certificats - Configurer des alertes
  • Utiliser des certificats à courte durée de vie - 24 h ou moins pour les charges de travail
  • Renouveler le CA périodiquement - Planifier la rotation du CA
  • Enregistrer les erreurs TLS - Pour le débogage et l'audit

À éviter

  • Ne pas désactiver mTLS - Pour des raisons de commodité en production
  • Ne pas ignorer l'expiration des certificats - Automatiser la rotation
  • Ne pas utiliser de certificats auto-signés - Utiliser une hiérarchie CA appropriée
  • Ne pas ignorer la vérification - Vérifier la chaîne complète

Skills similaires