Durch die immer komplexeren Infrastrukturen fallen abgelaufene Zertifikate gerne erst später auf – führt ein abgelaufenes Zertifikat einer Webseite noch zu einem klar dargestellten Fehler, so ist das Fehlerbild bei einem Mircoservice der im Hintergrund seinen Dienst verrichtet schon nicht mehr so offensichtlich. Dann kommen Admins und Manager in Erklärungsnot. Das muss aber nicht sein, denn auch für die interne CA können Sie Zertifikate ganz einfach automatisiert anfordern, verlängern und betreiben. Genau so wie mit Let’s Encrypt. Hier ein kurzes How-to, wie Sie das mit dem acme2certifier erreichen .
Das Projekt acme2certifer ist ein in python geschriebener ACME protocol proxy. Darüber können unzählige PKIs eingebunden werden und damit in die Lage versetzt werden, Zertifikate automatisiert zu erstellen. Sie können den acme2certifer mittels docker-compose installieren, eine OpenSSL CA konfigurieren und Ihre interne CA so im Handumdrehen ACME-fähig machen.
Die Github-Seite des Projekts erreichen Sie hier: https://github.com/grindsa/acme2certifier
Dort finden Sie auch Anleitungen zur Installation und zur Konfiguration aller PKIs („CA Handlers“ genannt):
* DigiCert® CertCentral
* Entrust ECS Enterprise
* EJBCA
* Generic ACME Handler (LetsEncrypt, BuyPass.com, ZeroSSL)
* Generic CMPv2 Handler
* Generic EST Handler
* Insta ActiveCMS
* Microsoft Certificate Enrollment Web Services
* Microsoft Windows Client Certificate Enrollment Protocol (MS-WCCE)
* NetGuard Certificate Lifecycle Manager
* NetGuard Certificate Manager/Insta Certifier
* OpenSSL
* OpenXPKI
* XCA
* acme2dfn (ACME proxy for German research network's PKI)
Bevor wir beginnen müssen wir allerdings noch auf einen wichtigen Aspekt hinweisen. Laut Projekt ist die Implementierung mit OpenSSL nämlich nur für Tests und Labore geeignet:
"The OpenSSL CA handler is primarily intended for testing and lab environments. It is strongly recommended not to use it in production environments without reviewing the local system configuration and hardening measures."
Falls Sie die hier vorgestellte Installation also produktiv einsetzen wollen, sollten Sie Härtungsmaßnahmen ergreifen und den administrativen Zugriff darauf stark einschränken.
Die Installation mittels docker-compose geht schnell von der Hand. Laden Sie zunächst das Projekt in der aktuellen Version als ZIP-Datei von https://github.com/grindsa/acme2certifier/releases herunter. Entpacken Sie diese und wechseln Sie in das Verzeichnis examples/Docker. Dort finden Sie die Datei docker-compose.yml.
Falls diese auf Ihrem Docker-Host Port 80 und 443 noch nicht in Verwendung sind, dann sollten Sie in dieser Datei die Portzuordnung anpassen – Standardmäßig wird dort nämlich lokal der Port 22280 für HTTP und 22433 für HTTPS verwendet.
Standardmäßig erwartet das Compose-File ein Netzwerk mit dem Namen acme. Damit der Container erstellt werden kann müssen Sie entweder dieses anlegen:
docker network create acme
Oder den Wert auf ein existierendes Netzwerk Ihrer Umgebung anpassen.
Damit acme2certifer die korrekte Zeitzone verwendet (standardmäßig UTC), müssen Sie nun noch die Datei docker-compose.override.yml mit folgendem Inhalt anlegen:
version: '3.2'
services:
acme-srv:
environment:
TZ: "Europe/Berlin"
Anschließend können Sie den Container mit dem nachstehenden Befehl erzeugen:
$ docker-compose build --no-cache
Weitere Details finden Sie in der folgenden Anleitung:
https://github.com/grindsa/acme2certifier/tree/master/examples/Docker
Überprüfen Sie schließend, ob der Container erwartungsgemäß läuft:
$ docker-compose ps
Läuft alles wie gewünscht, können Sie den Dienst bereits abfragen, zum Beispiel mit folgendem Kommando:
$ docker run -it --rm --network acme curlimages/curl \
http://acme-srv/directory | python -m json.tool
{
"newAuthz": "http://acme-srv/acme/new-authz",
"newNonce": "http://acme-srv/acme/newnonce",
"newAccount": "http://acme-srv/acme/newaccount",
"newOrder": "http://acme-srv/acme/neworders",
"revokeCert": "http://acme-srv/acme/revokecert",
"keyChange": "http://acme-srv/acme/key-change",
"renewalInfo": "http://acme-srv/acme/renewal-info",
"meta": {
"home": "https://github.com/grindsa/acme2certifier",
"author": "grindsa <grindelsack@gmail.com>",
"name": "acme2certifier",
"version": "0.37.1"
},
"4cdb723a1033437db2131948073b3253": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417"
}
Der Container läuft zwar nun und antwortet auch auf Anfragen (siehe oben), kann aber noch keine Zertifikate ausstellen, da lediglich eine Dummy-Konfiguration hinterlegt ist. Dies ändern wir nun. Die Konfiguration besteht dabei aus drei Schritten:
1. CA-Handler kopieren
2. acme_srv-Konfiguration anpassen
3. OpenSSL-Konfiguration anlegen & CA Zertifikat kopieren
Bei acme2certifier verfügt jede CA über ihr eigenes Python-Skript, das Sie ganz einfach unter dem Namen ca_handler.py ablegen müssen. Nutzen Sie für OpenSSL einfach das nachstehende Kommando:
$ cp ../ca_handler/openssl_ca_handler.py data/ca_handler.py
Passen Sie nun die Beispiel-Konfiguration acme_srv.cfg aus dem Volume (/data) des Containers an und ergänzen Sie den Abschnitt CAhandler wie folgt:
[CAhandler]
handler_file: acme_srv/ca_handler.py
issuing_ca_key: volume/ca/ca-key.pem
issuing_ca_key_passphrase:<PASSPHRASE>
issuing_ca_cert: volume/ca/ca-cert.pem
issuing_ca_crl: volume/ca/crl.pem
cert_validity_days: 30
cert_validity_adjust: True
cert_save_path: volume/ca/certs
ca_cert_chain_list: [""]
openssl_conf: volume/openssl.cnf
allowed_domainlist: ["example.org"]
save_cert_as_hex: True
cn_enforce: True
cn_validity_adjust: True
Die meisten Parameter sind sprechend und Sie müssen lediglich die Passphrase (Zeile 4) angeben und die Liste der Domains (Zeile 12) anpassen. Wie der Parametername bereits vermuten lässt, können dort Domänen angegeben werden, für die Ihr ACME-Server die Ausstellung von Zertifikaten zulässt. Alternativ könnten Sie auch mit blocked_domainlist Domänen angeben, die abgewiesen werden sollen – dann ist der Parameter allowed_domainlist nicht erforderlich. Wir empfehlen aber ausdrücklich den Weg über die Freigabe.
Zum Abschluss müssen Sie nur noch die OpenSSL-Konfigurationsdatei an den Bestimmungsort bringen (/data/openssl.cnf). Diese sollte folgenden Inhalt enthalten:
[extensions]
subjectKeyIdentifier = hash, issuer:always
keyUsage = digitalSignature, keyEncipherment
basicConstraints = critical, CA:FALSE
authorityKeyIdentifier = keyid:always, issuer:always
extendedKeyUsage = critical, clientAuth, serverAuth
Selbstverständlich können Sie hier auch Anpassungen und Erweiterungen vornehmen.
Wenn Sie nun noch Ihr CA-Zertifikat unter /data/ca/ca-cert.pem und den dazugehörigen Schlüssel unter /data/ca/ca-key.pem ablegen, sind Sie schon fast am Ziel. Es fehlt nur noch der Neustart des Containers, damit die Änderungen an der Konfiguration auch geladen werden:
$ docker-compose restart
Falls Sie mal nicht weiter wissen, dann hilft es in der acme_srv.cfg den Debug-Modus in der Sektion Default auf True zu setzen. Achtung: Dann protokolliert acme2certifiert (fast) alles und das Log wird schnell voll! Meistens finden Sie dort aber Anhaltspunkte, warum etwas nicht wie erwartet läuft.
Im Prinzip kann acme2certifier mit allen Tools, die das Protokoll implementiert haben, arbeiten. Unter nachstehender URL finden Sie für ein paar gängige Tools sogar die passenden Kommandos: https://github.com/grindsa/acme2certifier/blob/master/docs/acme-clients.md
Noch ein Tipp zum Abschluss. Falls Sie acme2certifier erweitern wollen, so dass zum Beispiel bestimmte Skripte vor, während oder nach einer Zertifikatsausstellung gestartet werden sollen, so können Sie dafür Hooks verwenden. Wie Sie eigene Hooks erstellen können erfahren Sie hier: https://github.com/grindsa/acme2certifier/blob/master/docs/hooks.md
Autor: Daniel von Soest, Teamlead Consulting (Heinlein Support)
Kommentare