Přeskočit obsah

Automatizace certifikátů pomocí ACME

Automatická správa certifikátů s cert-manager a Kubernetes

Verze dokumentu: 1.0.0
Poslední aktualizace: 2026-03-14


Přehled

MazeVault implementuje ACME server (RFC 8555), který umožňuje Kubernetes clusterům automaticky žádat, vydávat a obnovovat TLS certifikáty prostřednictvím cert-manager. To eliminuje manuální správu certifikátů a propojuje vaši stávající PKI — včetně Microsoft ADCS — s cloud-native infrastrukturou.

sequenceDiagram
    participant CM as ⚙️ cert-manager
    participant MV as 🏦 MazeVault ACME Server
    participant CA as 📜 Backend CA (ADCS/Interní)

    rect rgb(235, 245, 251)
    Note over CM,MV: 🔑 Registrace účtu
    CM->>MV: POST /new-account (EAB)
    MV-->>CM: Účet zaregistrován
    end

    rect rgb(255, 248, 225)
    Note over CM,CA: 📝 Objednávka certifikátu
    CM->>MV: POST /new-order
    MV-->>CM: Objednávka + Autorizace
    CM->>MV: POST /finalize (CSR)
    MV->>CA: Podepsat CSR
    CA-->>MV: Podepsaný certifikát
    end

    rect rgb(232, 245, 233)
    Note over CM,MV: ✅ Doručení certifikátu
    MV-->>CM: Certifikát připraven
    CM->>MV: GET /cert/:id
    MV-->>CM: PEM řetězec certifikátu
    end

Klíčové výhody

Funkce Popis
Automatická obnova cert-manager automaticky obnovuje certifikáty před vypršením platnosti
Most k ADCS Vydávání certifikátů z Microsoft ADCS přes standardní ACME protokol
Směrování šablon Mapování ACME profilů nebo domén na konkrétní šablony certifikátů
Zabezpečení EAB External Account Binding zajišťuje, že se mohou registrovat pouze autorizované clustery
Automatické schválení Interní domény (.local, .internal, .lan, .corp) jsou schváleny okamžitě
Auditní stopa Všechny ACME operace jsou zaznamenány v auditním systému MazeVault

Předpoklady

  • MazeVault v1.0.17+ s aktivním ACME serverem
  • Kubernetes cluster s cert-manager v1.12+
  • Alespoň jeden nakonfigurovaný CA Account v MazeVault (ADCS, interní CA nebo externí)
  • Nakonfigurovaná šablona certifikátu pro váš případ použití

Krok 1: Vygenerování EAB přihlašovacích údajů

Přihlašovací údaje External Account Binding (EAB) spojují ACME klienta s vaší organizací v MazeVault. Každá sada přihlašovacích údajů může být použita pouze jednou.

Přes webové rozhraní

  1. Přejděte na Nastavení organizace → Certifikační autority
  2. Přejděte k sekci Přístup ACME
  3. Klikněte na Vygenerovat EAB přihlašovací údaje
  4. Vyplňte:
  5. Označení clusteru — Popisný název (např. prod-aks-westeurope)
  6. Výchozí ID projektu — Projekt, kam se certifikáty uloží (volitelné)
  7. Výchozí ID šablony — Šablona certifikátu k použití (volitelné)
  8. Klikněte na Vygenerovat
  9. Zkopírujte a bezpečně uložte EAB Key ID a HMAC klíč — HMAC klíč se zobrazí pouze jednou

Přes API

curl -X POST https://vault.example.com/api/v1/organizations/{org_id}/acme-credentials \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "proj_abc123",
    "default_template_id": "tmpl_def456",
    "cluster_label": "prod-aks-westeurope"
  }'

Odpověď:

{
  "id": "cred_xyz789",
  "eab_key_id": "***REMOVED***",
  "eab_hmac_key": "***REMOVED***",
  "cluster_label": "prod-aks-westeurope",
  "created_at": "2026-03-14T10:00:00Z"
}

Okamžitě uložte přihlašovací údaje

Hodnota eab_hmac_key je vrácena pouze jednou při vytvoření. Později ji nelze získat. Uložte ji na bezpečné místo (např. Azure Key Vault, HashiCorp Vault).


Krok 2: Vytvoření EAB Secret v Kubernetes

Uložte HMAC klíč jako Kubernetes Secret pro cert-manager:

apiVersion: v1
kind: Secret
metadata:
  name: mazevault-eab-secret
  namespace: cert-manager
type: Opaque
stringData:
  secret: "***REMOVED***"  # Váš EAB HMAC klíč
kubectl apply -f mazevault-eab-secret.yaml

Alternativa: Vytvoření přes CLI

kubectl create secret generic mazevault-eab-secret \
  --namespace cert-manager \
  --from-literal=secret="VÁŠ_EAB_HMAC_KLÍČ"

Krok 3: Konfigurace ClusterIssuer

Vytvořte ClusterIssuer (pro celý cluster) nebo Issuer (omezený na namespace):

ClusterIssuer (doporučeno)

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: mazevault-issuer
spec:
  acme:
    # URL ACME adresáře MazeVault
    server: https://vault.example.com/api/acme/directory

    # External Account Binding
    externalAccountBinding:
      keyID: "***REMOVED***"          # Vaše EAB Key ID
      keySecretRef:
        name: mazevault-eab-secret
        key: secret
      keyAlgorithm: HS256

    # Privátní klíč pro ACME účet (automaticky generován cert-managerem)
    privateKeySecretRef:
      name: mazevault-acme-account-key

    # Řešení výzvy pro domény bez automatického schválení
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx
kubectl apply -f mazevault-clusterissuer.yaml

Issuer omezený na namespace

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: mazevault-issuer
  namespace: my-app
spec:
  acme:
    server: https://vault.example.com/api/acme/directory
    externalAccountBinding:
      keyID: "***REMOVED***"
      keySecretRef:
        name: mazevault-eab-secret
        key: secret
      keyAlgorithm: HS256
    privateKeySecretRef:
      name: mazevault-acme-account-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx

Ověření stavu Issueru

kubectl get clusterissuer mazevault-issuer -o wide

Očekávaný výstup:

NAME               READY   STATUS                                                 AGE
mazevault-issuer   True    The ACME account was registered with the ACME server   30s

Krok 4: Žádost o certifikáty

Možnost A: Certificate resource

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: api-tls
  namespace: my-app
spec:
  secretName: api-tls-secret
  duration: 8760h       # 1 rok
  renewBefore: 720h     # Obnovit 30 dní před vypršením
  issuerRef:
    name: mazevault-issuer
    kind: ClusterIssuer
  commonName: api.example.com
  dnsNames:
    - api.example.com
    - api-internal.example.com

Možnost B: Ingress anotace (Auto-TLS)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  namespace: my-app
  annotations:
    cert-manager.io/cluster-issuer: mazevault-issuer
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.example.com
      secretName: api-tls-secret
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

Možnost C: ACME profily (cert-manager v1.18+)

ACME profily umožňují cert-manageru vybrat konkrétní šablonu certifikátu podle názvu:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: web-tls
  namespace: my-app
spec:
  secretName: web-tls-secret
  issuerRef:
    name: mazevault-issuer
    kind: ClusterIssuer
  commonName: web.example.com
  dnsNames:
    - web.example.com
  # Profil mapuje na šablonu certifikátu v MazeVault s odpovídajícím ACMEProfileName
  profileName: web-server

Konfigurace profilů

Pro použití ACME profilů nastavte pole ACME Profile Name na vaší šabloně certifikátu v MazeVault. Název profilu v Certificate resource musí přesně odpovídat.


Krok 5: Ověření vydání certifikátu

# Kontrola stavu Certificate
kubectl get certificate -n my-app
NAME      READY   SECRET           AGE
api-tls   True    api-tls-secret   2m
# Inspekce vydaného certifikátu
kubectl describe certificate api-tls -n my-app

# Zobrazení skutečného TLS certifikátu
kubectl get secret api-tls-secret -n my-app -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text

Automatické schválení domén

Pro interní domény MazeVault přeskočí HTTP-01 výzvu a schválí certifikáty okamžitě:

Přípona domény Příklad Výzva nutná
.local app.mycompany.local Ne (automaticky schváleno)
.internal api.cluster.internal Ne (automaticky schváleno)
.lan server.office.lan Ne (automaticky schváleno)
.corp vault.mycompany.corp Ne (automaticky schváleno)
Všechny ostatní api.example.com Ano (HTTP-01)

Interní domény jsou nejrychlejší

Pro Kubernetes služby, které používají interní DNS jména, jsou certifikáty vydány okamžitě bez validace výzvy. To je ideální pro service mesh, interní API a TLS mezi mikroslužbami.


Směrování šablon

MazeVault směruje ACME žádosti o certifikáty na správný CA backend pomocí těchto pravidel (v pořadí priority):

  1. ACME profil — Pokud žádost obsahuje profileName, použije se šablona s odpovídajícím ACMEProfileName
  2. Pravidla domén — Pokud jsou na EAB přihlašovacích údajích nakonfigurována pravidla domén, první odpovídající pravidlo určí šablonu
  3. Výchozí šablona — Záložní použití výchozí šablony nastavené na EAB přihlašovacích údajích nebo ACME účtu
graph TD
    A["📨 ACME objednávka"] --> B{"Profil<br/>specifikován?"}
    B -->|Ano| C["✅ Použít odpovídající šablonu"]
    B -->|Ne| D{"Pravidla domén<br/>odpovídají?"}
    D -->|Ano| E["✅ Použít šablonu pravidla"]
    D -->|Ne| F{"Výchozí šablona<br/>nastavena?"}
    F -->|Ano| G["✅ Použít výchozí šablonu"]
    F -->|Ne| H["❌ Chyba: Žádná šablona"]

    classDef start fill:#EBF5FB,stroke:#2196F3,stroke-width:2px,color:#1565C0
    classDef decision fill:#FFF8E1,stroke:#FF9800,stroke-width:2px,color:#E65100
    classDef success fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#2E7D32
    classDef error fill:#FFEBEE,stroke:#F44336,stroke-width:2px,color:#C62828

    class A start
    class B,D,F decision
    class C,E,G success
    class H error

Správa EAB přihlašovacích údajů

Výpis přihlašovacích údajů

Přejděte na Nastavení organizace → Certifikační autority → Přístup ACME pro zobrazení všech EAB přihlašovacích údajů s jejich stavem:

Stav Význam
Dostupný Dosud nepoužitý, připravený k registraci
Použitý Již spotřebovaný ACME klientem
Odvolaný Deaktivovaný administrátorem

Odvolání přihlašovacích údajů

Pro zabránění registraci ACME klienta (nebo vyřazení clusteru):

  1. Přejděte do sekce Přístup ACME
  2. Najděte přihlašovací údaje v tabulce
  3. Klikněte na tlačítko Odvolat

Stávající účty nejsou ovlivněny

Odvolání EAB přihlašovacích údajů neovlivní účty, které se s nimi již zaregistrovaly. Pro deaktivaci stávajícího účtu použijte tok deaktivace ACME účtu.


Reference ACME endpointů

Endpoint Metoda Popis
/api/acme/directory GET ACME adresář (discovery)
/api/acme/new-nonce HEAD, POST Získat replay-protection nonce
/api/acme/new-account POST Registrace nového účtu (vyžaduje EAB)
/api/acme/new-order POST Vytvoření objednávky certifikátu
/api/acme/order/:id POST Získat stav objednávky
/api/acme/authz/:id POST Získat detail autorizace
/api/acme/challenge/:id POST Spustit validaci výzvy
/api/acme/finalize/:id POST Odeslat CSR k podpisu
/api/acme/cert/:id POST Stáhnout vydaný certifikát

Řešení problémů

ClusterIssuer ukazuje READY stav False

kubectl describe clusterissuer mazevault-issuer

Běžné příčiny:

Chyba Řešení
401 externalAccountRequired EAB přihlašovací údaje chybí nebo jsou nesprávné
403 unauthorized: EAB credential already used Vygenerujte nové EAB přihlašovací údaje — každé mohou být použity pouze jednou
403 unauthorized: EAB credential revoked Přihlašovací údaje byly odvolány, vygenerujte nové
Connection refused Ověřte, že URL MazeVault je dosažitelná z clusteru
TLS error Ujistěte se, že cluster důvěřuje TLS certifikátu MazeVault

Certifikát zůstává ve stavu Pending

kubectl describe certificate api-tls -n my-app
kubectl describe certificaterequest -n my-app
kubectl describe order -n my-app
kubectl describe challenge -n my-app

Běžné příčiny:

Problém Řešení
Výzva selhala Ujistěte se, že Ingress controller může obsluhovat /.well-known/acme-challenge/
Šablona nenalezena Nakonfigurujte výchozí šablonu na EAB přihlašovacích údajích nebo použijte ACME profily
Objednávka vypršela Objednávky vyprší po 24 hodinách; zkontrolujte zaseknuté výzvy

Užitečné příkazy

# Zobrazit logy cert-manageru
kubectl logs -n cert-manager deploy/cert-manager -f

# Kontrola registrace ACME účtu
kubectl get secret mazevault-acme-account-key -n cert-manager -o yaml

# Vynutit obnovu certifikátu
kubectl delete secret api-tls-secret -n my-app
# cert-manager automaticky znovu vydá certifikát

Kompletní příklad: End-to-End nastavení

Zde je kompletní funkční příklad, který zajistí TLS certifikát pro webovou aplikaci:

---
# 1. EAB Secret
apiVersion: v1
kind: Secret
metadata:
  name: mazevault-eab-secret
  namespace: cert-manager
type: Opaque
stringData:
  secret: "VÁŠ_EAB_HMAC_KLÍČ"

---
# 2. ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: mazevault-issuer
spec:
  acme:
    server: https://vault.example.com/api/acme/directory
    externalAccountBinding:
      keyID: "VAŠE_EAB_KEY_ID"
      keySecretRef:
        name: mazevault-eab-secret
        key: secret
      keyAlgorithm: HS256
    privateKeySecretRef:
      name: mazevault-acme-account-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx

---
# 3. Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: myapp-tls
  namespace: default
spec:
  secretName: myapp-tls-secret
  duration: 8760h
  renewBefore: 720h
  issuerRef:
    name: mazevault-issuer
    kind: ClusterIssuer
  commonName: myapp.example.com
  dnsNames:
    - myapp.example.com
    - www.myapp.example.com

---
# 4. Ingress používající certifikát
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  namespace: default
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - myapp.example.com
        - www.myapp.example.com
      secretName: myapp-tls-secret
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 80

Související dokumentace