mTLS mit CloudFlare PKI/TLS toolkit 

Wenn man Applikation entwickelt, die sich gegenseitig über mTLS authentifizieren müssen, benötigt man ein Tripel von x509-Zertifikatsdateien: Eine Root-CA, Client-Zertifikate und Server-Zertifikate und die entsprechenden Schlüsseldateien. Eine Möglichkeit, diese Dateien zu erstellen, ist die Verwendung von openssl, aber das ist ziemlich mühsam, da man eine Menge konfigurieren muss. Eine elegantere Lösung ist die Verwendung des CloudFlare PKI/TLS toolkit (kurz CFSSL).

In diesem Post erkläre ich wie man alle Zertifikate erstellt, die zum Testen einer mTLS-Verbindung benötigt werden.

Setup

Um CFSSL zu installieren, kann man entweder brew verwenden oder es direkt mit der go Toolchain installieren.

Installation mit brew:
brew install cfssl

Für die Installation von CFSSL mit der go Toolchain sei auf offizielle Dokumentation verwiesen.

Root CA

Zunächst benötigt man eine Root CA (Certificate Authority), von der alle anderen Zertifikate abgeleitet werden.
CFSSL unterstützt die Konfiguration von Variablen für Zertifikate in einem JSON-Format. Also erstellen wir zunächst eine JSON-Datei mit Variablen für unsere CA:

kopieren
{
"CN": "www.radile.net",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "DE",
"L": "Cologne",
"O": "Martin Radile",
"OU": "cfssldemo",
"ST": "NRW"
}
]
}

Um die CA-Dateien zu erstellen, führt man den folgenden Befehl aus:

mkdir -p certs
cfssl gencert -initca \
configs/ca.json | cfssljson -bare certs/ca

Dadurch wird eine neue CA mit den in configs/ca.json konfigurierten Variablen erstellt. Um den Inhalt des CA-Zertifikats anzuzeigen, kann man openssl verwenden:

openssl x509 -in certs/ca.pem -text

Die Ausgabe wird in etwa so aussehen:

kopieren
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
01:02:c7:ec:cc:d9:20:af:c5:f9:7c:34:79:eb:f6:6c:74:30:12:ca
Signature Algorithm: sha512WithRSAEncryption
Issuer: C=DE, ST=NRW, L=Cologne, O=Martin Radile, OU=cfssldemo, CN=www.radile.net
Validity
Not Before: Jan 31 20:42:00 2022 GMT
Not After : Jan 30 20:42:00 2027 GMT
Subject: C=DE, ST=NRW, L=Cologne, O=Martin Radile, OU=cfssldemo, CN=www.radile.net
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)

Profile

Mit der neuen CA kann man jetzt die Zertifikate für die Client- und Serveranwendungen erstellen. Wir erstellen wieder eine neue Konfigurationsdatei, um Profile für die Zertifikatserstellung zu definieren. Auf diese Profile wird später bei der Erstellung der Client- und Serverzertifikate verwiesen.

kopieren
{
"signing": {
"profiles": {
"client": {
"usages": ["client auth"],
"expiry": "8760h"
},
"server": {
"usages": ["server auth"],
"expiry": "8760h"
}
}
}
}

Die Konfiguration enthält zwei Profile mit den Namen client und server. Die Namen können beliebig gewählt werden. Das client Profil bestimmt, dass die erstellten Zertfikate für die Authentifizierung als Client verwendet werden können. Mit dem server Profil kann CFSSL Zertifikate für eine Serveranwendung erstellen. Beide Profile sind so konfiguriert, dass die Zertifikate eine Gültigkeit von einem Jahr haben.

Client Zertifikate

Wir brauchen wieder eine Konfigurationsdatei mit Parametern für unsere Zertifikate:

kopieren
{
"CN": "client.cfssldemo.radile.net",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "DE",
"L": "Cologne",
"O": "Martin Radile",
"OU": "client cfssl demo",
"ST": "NRW"
}
]
}

Mit dem folgenden Befehl werden die Clientzertifikate erstellt:

Wir verweisen auf die CA-Dateien und unser zuvor erstelltes client Profil. Der letzte Parameter für cfssljson certs/client ist das Ausgabeverzeichnis und das Präfix der Dateinamen für die Zertifikate.

Server Zertifikate

Die Konfiguration für die Serverzertifikate sieht fast identisch aus. Der einzige Unterschied ist das Feld hosts. Hier können die Hosts hinzufügt werden, für die das generierte Zertifikat gültig sein soll.

Wenn in der TLS Konfiguration der Client-Anwendung eine Option für strict host checking aktiviert ist, würde der Verbindungsaufbau abgelehnt werden wenn die Hostnamen nicht passen. Der konfigurierte Hostname sollte also passend zum Hostnamen sein unter dem der Server später zu erreichen ist. Es ist auch möglich IP Adressen und Wildcard Hosts zu konfigurieren wie z.B.  *.cfssldemo.radile.net.

kopieren
{
"hosts": [
"server.cfssldemo.radile.net",
"127.0.0.1",
"localhost"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "DE",
"L": "Cologne",
"O": "Martin Radile",
"OU": "server cfssl demo",
"ST": "NRW"
}
]
}

Mit dem folgenden Befehl werden die Serverzertifikate erstellt:

Die Hostnamen werden in das SAN-Feld (Subject Alternative Name) des Zertifikats aufgenommen:

Dateiübersicht

Nach dem alle Schritte ausgeführt wurden sollten die folgenden Dateien vorhanden sein:

Vollständiger Code

Den vollständigen Code mit einem Makefile findet ihr hier github.com/mradile/cfssl-mtls-demo.

Ihre Ansprechpersonen zum Thema

Sie haben Fragen an unsere Expertinnen und Experten? Oder möchten mehr über unsere digitalen Lösungen erfahren?
Kontaktieren Sie uns gerne!

Martin Radile, Aleri Solutions GmbH

Martin Radile

Technology Lead: DevSecOpsmartin.radile@aleri.de
Seite teilen