cert-manager tratta l’emissione e il rinnovo dei certificati TLS come risorse Kubernetes dichiarative: un controller riconcilia lo stato osservato con quello desiderato, esattamente come avviene per qualunque altro oggetto del cluster. Lo sviluppa Jetstack, è scritto in Go e distribuito con licenza Apache 2.0; prende il posto di kube-lego, lo strumento per Let’s Encrypt che gli stessi autori hanno iniziato a deprecare.

Contesto

Su un cluster con molti host pubblicati via Ingress, gestire i certificati a mano è un lavoro ripetitivo che ritorna a ogni scadenza: si genera la CSR (Certificate Signing Request), si completa la validazione presso la CA, si salvano chiave e catena in un Secret, e si rifà tutto prima che il certificato scada. Con Let’s Encrypt la durata è di 90 giorni, quindi il rinnovo ricapita ogni pochi mesi su ciascun nome. La prima generazione di automazioni — kube-lego — leggeva l’annotazione kubernetes.io/tls-acme: "true" sugli Ingress e otteneva certificati ACME, ma inchiodava tutta la logica a un solo emittente, dentro un flusso difficile da estendere.

Il passo successivo è descrivere il certificato come risorsa di prima classe e affidare a un controller il compito di portarlo allo stato richiesto. È lo stesso modello che Kubernetes applica già a Deployment e Service, esteso al materiale crittografico.

Architettura

cert-manager aggiunge alcune Custom Resource Definition nel gruppo certmanager.k8s.io, versione v1alpha1. Le due risorse principali sono:

  • Issuer (a livello di namespace) e ClusterIssuer (a livello di cluster) — descrivono un’autorità emittente: un account ACME (Let’s Encrypt o un altro server compatibile), una CA interna costruita da una coppia chiave/certificato in un Secret, oppure un emittente self-signed per i test.
  • Certificate — dichiara il certificato che si vuole: i nomi DNS (Subject Alternative Name), il Secret di destinazione dove finiscono chiave e catena, l’emittente di riferimento e la finestra di rinnovo anticipato.

Il controller tiene d’occhio queste risorse e agisce di conseguenza: genera la chiave privata e la CSR, porta avanti la validazione presso l’emittente, scrive l’esito nel Secret indicato e pianifica il rinnovo con anticipo sulla scadenza. Un ClusterIssuer per Let’s Encrypt si configura così:

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v01.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    http01: {}

Accanto al controller principale c’è un componente a sé, l’ingress-shim, che tiene in vita il vecchio flusso ad annotazioni: intercetta gli Ingress annotati e crea per ciascuno la risorsa Certificate corrispondente, così chi arriva da kube-lego non deve riscrivere subito i propri manifest.

Il flusso ACME e il punto critico

Per gli emittenti ACME il controller deve dimostrare alla CA di controllare il dominio prima di ottenere il certificato. Il protocollo Automatic Certificate Management Environment prevede più tipi di sfida, e la scelta tra questi è il punto in cui l’automazione mette le mani sulla rete e sul DNS: va decisa con cura.

  • HTTP-01 — la CA chiede un token su http://<dominio>/.well-known/acme-challenge/<token>. cert-manager pubblica per un attimo quel percorso attraverso l’Ingress. Funziona solo se il nome è raggiungibile dall’esterno sulla porta 80 e non copre i certificati wildcard.
  • DNS-01 — la prova è un record TXT su _acme-challenge.<dominio>, creato tramite le API del provider DNS e rimosso alla fine. Non richiede che il servizio sia esposto e abilita i wildcard, ma in cambio cert-manager riceve credenziali con permessi di scrittura sulla zona DNS.

Una terza sfida storica, TLS-SNI-01, è ormai da considerare fuori uso: il 9 gennaio 2018 Let’s Encrypt l’ha sospesa dopo una segnalazione secondo cui, su certe configurazioni di hosting condiviso, poteva servire a ottenere certificati su sottodomini che il richiedente non controllava. Ricorda un fatto strutturale: per la CA, chi sa rispondere alla sfida è il legittimo titolare del nome. La validazione di dominio attesta il controllo dell’endpoint, non l’identità di chi sta dietro.

ACME v2 e wildcard: lo stato a febbraio 2018

Il protocollo ACME è in transizione. Il 5 gennaio 2018 Let’s Encrypt ha pubblicato l’endpoint di staging per ACME v2, su https://acme-staging-v02.api.letsencrypt.org/directory, e ha indicato il 27 febbraio come data prevista per l’endpoint di produzione. ACME v2 non è retrocompatibile con v1 ed è la versione che porterà l’emissione dei certificati wildcard, ammessi solo con la sfida DNS-01.

Per ora, quindi, l’emissione in produzione passa ancora da ACME v1 (acme-v01.api.letsencrypt.org), i wildcard via Let’s Encrypt non ci sono ancora in produzione, e il supporto pieno a v2 in cert-manager dipende dalla versione installata, da verificare caso per caso. Chi ha in mente i wildcard su Kubernetes fa bene a predisporre subito un emittente DNS-01 con un provider supportato, così da essere pronto quando la produzione v2 sarà attiva.

Implicazioni operative

Portare i certificati dentro l’API del cluster sposta i rischi e i controlli. Le chiavi private finiscono nei Secret, che di default sono codificati in base64 ma non cifrati a riposo in etcd: abilitare la cifratura a riposo e una policy RBAC (Role-Based Access Control) restrittiva sull’accesso ai Secret entra nella superficie da proteggere. Per gli emittenti DNS-01 anche le credenziali del provider DNS vivono nel cluster, e vanno trattate come segreti ad alto privilegio: chi le ha in mano può emettere certificati per l’intera zona.

Un unico emittente ACME tende inoltre ad accentrare le richieste: Let’s Encrypt applica limiti di frequenza per dominio registrato, e un controller mal configurato che riprova in loop può bruciare la quota e bloccare le emissioni legittime. L’endpoint di staging serve proprio a evitarlo mentre si mette a punto la configurazione.

Limiti

cert-manager è ancora agli inizi: le CRD sono in v1alpha1, quindi la forma delle risorse può cambiare tra una versione e l’altra senza retrocompatibilità, e la migrazione dei manifest va messa in conto. Il controller automatizza l’emissione, ma non toglie il bisogno di monitorare: vanno comunque seguiti gli eventi sulle risorse Certificate e la scadenza effettiva dei certificati nei Secret, perché un rinnovo fallito non fa rumore finché il certificato non scade. E la validazione di dominio resta validazione di dominio: dove servono garanzie sull’identità dell’organizzazione, le opzioni da valutare restano una CA interna via Vault o un emittente enterprise, non l’automazione ACME.


Immagine di copertina: Icona/logo del protocollo ACME (Automatic Certificate Management Environment) — logo di IETF ACME Working Group, pubblico dominio — https://commons.wikimedia.org/wiki/File:ACME%E2%80%93protocol-icon.svg