ACME implementieren

Vorwort

Das Automatic Certificate Management Environment (ACME) ist ein standardisiertes Internetprotokoll. Daher können beliebige ACME-Clients verwendet werden und wir können hier nur ein paar Beispiele zur Implementierung zeigen.
Der Client muss "External Account Binding" (EAB) unterstützen.
Eine ACME-Challenge, wie beispielsweise bei "Let‘s Encrypt", findet dadurch nicht statt. Somit können auch interne Server via ACME Zertifikate beziehen.


Benötigte Daten

Im wesentlichen werden drei Parameter benötigt, um ein Zertifikat via ACME abrufen zu können:

Ihre ACME Server-URL
Ihre Account-ID bzw. Key-ID
Ihren HMAC Key

Ihre ACME Server-URL, Key-ID und der HMAC Key sind in der ACME-Accountverwaltung hinterlegt.
Behandeln Sie diese Daten vertraulich und melden Sie Kompromittierungen sofort.


Beispiele zur Implementierung

  • Einzelner Server via Certbot

    Installieren Sie zunächst Certbot auf Ihrem Server. Je nach verwendeter Software und Betriebssystem stehen verschiedene Anleitungen unter https://certbot.eff.org/instructions zur Verfügung.

    Verwenden Sie einen Apache oder Nginx Webserver unter RHEL, so kann Certbot wie folgt installiert werden:

    Stellen Sie sicher, dass Ihr System auf dem aktuellen Stand ist:

    # dnf update -y

    Installieren Sie das Epel repository:
    Unter RHEL 8:
    # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y

    Unter RHEL 9:
    # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -y

    Zusätzlich wird unter RHEL 9 der CodeReady Builder benötigt:
    # subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms

    Certbot mit Apache- oder Nginx-Plugin installieren:

    Für Apache:
    # dnf install certbot python3-certbot-apache

    Für Nginx:
    # dnf install certbot python3-certbot-nginx

    Nach der Installation kann die Version geprüft werden:

    # certbot --version


    Beispiele zur Verwendung:

    Nach der Installation von Certbot kann folgender Befehl verwendet werden, um ein neues Zertifikat zu beantragen und automatisch in die SSL-Konfiguration einzubinden (für Nginx das "--apache" durch "--nginx" ersetzen):

    # certbot --apache --agree-tos --rsa-key-size 4096 --email <eigene Mailadresse> --server <ACME Server-URL> --eab-kid <Key ID> --eab-hmac-key <HMAC Key>

    Certbot listet dabei alle konfigurierten VirtualHosts auf und fragt, für welche Domain das Zertifikat erneuert werden soll.

    Möchten Sie das neue Zertifikat lieber manuell in Ihre Konfiguration einbinden, so erweitern Sie das Kommando bitte um "certonly" (für Nginx das "--apache" durch "--nginx" ersetzen):

    # certbot certonly --apache --agree-tos --rsa-key-size 4096 --email <eigene Mailadresse> --server <ACME Server-URL> --eab-kid <Key ID> --eab-hmac-key <HMAC Key>

    Natürlich können Sie auch den Domainnamen mit der Erweiterung "--domain" direkt mit angeben:

    # certbot certonly --apache --agree-tos --rsa-key-size 4096 --email <eigene Mailadresse> --server <ACME Server-URL> --eab-kid <Key ID> --eab-hmac-key <HMAC Key> --domain <FQDN des Zertifikats>

    Das Zertifikat, die Chain und der private Schlüssel werden im Ordner
    /etc/letsencrypt/live/domainname/ gespeichert.

    Automatische Erneuerung

    Certbot sollte nun auch automatisch einen Systemd-Timer (certbot-renew.timer) angelegt haben.
    Prüfen Sie, ob der Timer angelegt wurde und aktiv ist:

    # systemctl list-timers --all

    Zertifikate werden damit automatisch erneuert, wenn sie weniger als 30 Tage gültig sind.
    30 Tage ist der Defaultwert. Dieser kann in der jeweiligen Konfigurationsdatei angepasst werden:

    # vi /etc/letsencrypt/renewal/domainname.conf

    Ersetzen Sie hier "# renew_before_expiry = 30 days" beispielsweise durch "renew_before_expiry = 14 days", um das Zertifikat erst 14 Tage vor Ablauf zu erneuern.


    Kubernetes-Cluster via Cert-Manager

    Cert-Manager ist eine Möglichkeit ACME in Kubernetes zu verwenden. Cert-Manager kümmert sich dabei vollständig um den Lebenszyklus des Zertifikats und erneuert dieses automatisch.

    Installation:

    Dokumentation: https://cert-manager.io/docs/installation/

    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml

    Issuer anlegen

    Als erstes muss der ACME-Account als Issuer angelegt werden und der HMAC key als Kubernetes Secret. Issuer und Secret sind in einem Namespace gültig.

    Secret:
    kubectl create secret generic harica-hmac --from-literal secret=<HMAC Key> -n default

    Issuer:
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: harica-issuer # The name of an Issuer
      namespace: default
    spec:
      acme:
        email: myemail@fernuni-hagen.de # A valid email address
        # for certificate expiry alerts
        server: <Server URL> # The ACME server URL
        externalAccountBinding:
          keyID: <Key ID>
          keySecretRef:
            name: harica-hmac # The name of the Kubernetes Secret
            # created with your HMAC
            key: secret
        privateKeySecretRef:
          name: harica-issuer-account-key # The private key created by Cert-Manager
        solvers:
        - http01:
            ingress:
              class: nginx


    Zertifikat erstellen

    Im Zertifikat wird auf den Issuer referenziert:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: example.fernuni-hagen.de
      namespace: default
    spec:
      secretName: study-candidate-swagger-tls
      issuerRef:
        name: harica-issuer
        kind: Issuer
      dnsNames:
        - example.fernuni-hagen.de


    Der private und public key werden als Secret zu Verfügung gestellt, welches in die Pods gemountet werden kann.

    ClusterIssuer verwenden

    Um einen Issuer Cluster-weit zu verwenden muss das Secret für den HMAC Key in den Namespace cert-manager deployed werden und vom Typ ClusterIssuer, statt Issuer angelegt werden.
    Beim Zertifikat muss spec.issuerRef.kind: ClusterIssuer gesetzt werden.


  • Automatisierte Zertifikatserneuerung im IIS via simple-acme

    Laden Sie zunächst simple-acme herunter und entpacken Sie das Tool auf dem gewünschten Windows Server (Download)

    Editieren Sie die "settings_default.json" von simple-acme.
    Damit wird der Zeitraum der Zertifikatserneuerung an die Zertifikatslaufzeit von Harica angepasst.
    Mit nachfolgender Konfiguration wird das Zertifikat 14 Tage vor Ablauf erneuert.
    Zudem können Sie sich via E-Mail benachrichtigen lassen, wenn das Zertifikat erneuert wurde.


    ...

    "ScheduledTask": {
        "RenewalDays": null,
        "RenewalDaysRange": 0,
        "RenewalMinimumValidDays": 14,
        "RenewalDisableServerSchedule": false,
        "RandomDelay": "01:00:00",
        "StartBoundary": "04:00:00",
        "ExecutionTimeLimit": "02:00:00"
      },
      "Notification": {
        "ComputerName": null,
        "Email": {
          "SmtpServer": "mailhost.fernuni-hagen.de",
          "SmtpPort": 25,
          "SmtpUser": null,
          "SmtpPassword": null,
          "SmtpSecure": false,
          "SmtpSecureMode": 1,
          "SenderName": "Absendername",
          "SenderAddress": "mailadresse@fernuni-hagen.de",
          "ReceiverAddresses": ["vorname.nachname@fernuni-hagen.de"],
          "NotifyOnSuccess": true
        },
        "Script": {
          "Path": null,
          "Parameters": null,
          "NotifyOnSuccess": false
        }
      },

    ...



    Öffnen Sie eine PowerShell oder die Eingabeaufforderung als Administrator.

    Passen Sie den folgenden Befehl an Ihre Konfiguration und Ihren ACME-Account an und führen Sie ihn danach aus.
    Beachten Sie die Erläuterungen zu den Variablen, die durch Ihre Parameter ersetzt werden müssen.
    Wichtig: Der Hostname muss unter Bindings im IIS gesetzt sein.

    _PATH_\wacs.exe --source iis --host "_FQDN des Zertifikats_" --certificatestore WebHosting --baseuri "_ACME-SERVER-URL_" --emailaddress "_MAIL_ADRESSE_" --eab-key-identifier "_KEY ID/ACCOUNT ID_" --eab-key "_HMAC KEY_" --accepttos --siteid "_ID_DER_WEBSEITE_" --sslport "_WENN_EIN_ANDERER_ALS_443_VERWENDET_WIRD_"

    Erläuterungen zu den Variablen:

    _PATH_
    Der Pfad zu Ihrer wacs.exe Datei

    _FQDN des Zertifikats_
    Meistens der Name des Servers oder der Webseite

    _ACME-SERVER-URL_
    Diese finden Sie in Ihrer ACME-Accountverwaltung

    _MAIL_ADRESSE_
    Ihre persönliche E-Mail-Adresse

    _KEY ID/ACCOUNT ID_
    Diese finden Sie in Ihrer ACME-Accountverwaltung

    _HMAC KEY_
    Diesen finden Sie in Ihrer ACME-Accountverwaltung

    _ID_DER_WEBSEITE_
    Wenn das Zertifikat nicht für ALLE Webseiten auf dem Server gelten soll, sondern nur für eine Bestimmte (Im IIS unter erweiterten Einstellungen der Site zu finden)

    _WENN_EIN_ANDERER_ALS_443_VERWENDET_WIRD_
    Standardmäßig erfolgt die Bindung auf Port 443. Wenn die Bindung auf einen anderen Port stattfinden soll, muss dieser hier angegeben werden.
    Wenn 443 verwendet wird, entfernen Sie den Parameter "--sslport" bitte komplett aus dem Befehl.

    Abschließende Prüfung

    Überprüfen Sie, ob das neue Zertifikat erfolgreich im IIS hinterlegt wurde. Falls ein neues Binding angelegt wurde, kann das alte Binding entsprechend entfernt werden.
    Prüfen Sie dann, ob ein neuer Task zur automatischen Erneuerung des Zertifikats angelegt wurde.

    Damit ist die Einrichtung abgeschlossen.

    Verwendung ohne IIS

    Soll das Zertifikat nicht im IIS eingebunden werden, so kann "--source" auf "manual" gesetzt werden:

    _PATH_\wacs.exe --source manual --host "_FQDN des Zertifikats_" --baseuri "_ACME-SERVER-URL_" --emailaddress "_MAIL_ADRESSE_" --eab-key-identifier "_KEY ID/ACCOUNT ID_" --eab-key "_HMAC KEY_" --accepttos




Weitere Use-Cases

Für weitere Use-Cases können die Dokumentationen von Harica, Cert-Manager und simple-acme verwendet werden:

Harica
Cert-Manager
simple-acme



Sonstiges

Ansible Collection für ACME