Ziel: Entwurf einer eigenen Root-CA mit vertrauenswürdigen SSL-Zertifikaten
Should you consider using self-signed certificate chains when free and widely recognized certificates are readily available?
- Self-signed certificates can be just as secure as publicly trusted certificates.
- They establish a chain of trust, where each party is well-known and directly controlled.
- You have full control of the PKI and the validity of each certificate. No external party can invalidate the certificates.
The whole foundation of Web Public Key Infrastructure (PKI) is built upon chains of trust:
“I trust this certificate as it has been issued by a reputable authority that I know I can trust.”
But for internal domains there is really no need to use a public issuer as the domains are accessed in a controlled environment. A good alternative is to roll your own PKI with a private Root Certificate Authority.
Also keep in mind that using a public CA for internal certificates will reveal more of your internal infrastructure, as details will be readily available on sites such ascrt.sh
.
Seit den “Snowden”-Enthüllungen im Jahr 2013 ist klar, dass nur mit einer echten Ende-zu-Ende-Verschlüsselung eine wirklich vertrauliche Datenübertragung in jedem Netzwerk gewährleistet werden kann.
Dazu braucht man diverse Zutaten, wie eine PKI, eine Hierachie von CAs und X.509-Zertifikate die Chains-of-Trust bilden. Dieser Vortrag soll diese Themen näher beleuchten und die praktische Machbarkeit mit bekannten und neuen Open-Source-Tools (z.B.
cfssl
odersmallstep
) zeigen.
Eine “Public Key Infrastructure” (PKI) ist ein System aus vertrauenswürdigen Zertifizierungsstellen (CAs), die eine hierarchische Vertrauenskette (Chain-of-Trust) bilden, um einem Endgerät und einem Netzwerkserver eine abgesicherte Kommunikation via “Transport Layer Security” (TLS) zu ermöglichen.
TLS (früher SSL) ist die Basis für das HTTPS-Protokoll. Es werden X.509 Zertifikate benutzt, um das Vertrauen zwischen den Kommunikationspartnern herzustellen und danach einen Session-Schlüssel auszutauschen und zu benutzen.
X.509-v3 ist ein ITU-Standard, der das Format von “Public Key Certificates” definiert.
Ein X.509 Zertifikat verknüpft eine Identität mit einem Public Key mittels einer Digital Signature.
X.509 Zertifikate existieren in Base64 Formaten PEM (.pem, .crt, .ca-bundle), PKCS-7 (.p7b, .p7s) und binären Formaten DER (.der, .cer), PKCS-12 (.pfx, .p12).
Die technische Basis für die Erstellung der Public Keys, Private Keys und Digital Signatures ist die asymmetrische Verschlüsselungstechnik. Entweder unter Nutzung des RSA-Algorithmus oder auf Basis von ECC (Elliptic Curve Cryptography). Übersichten über beide Verfahren können hier oder hier eingesehen werden.
Im Blog von Bityard gibt’s eine gute Zusammenfassung und Übersicht zum Thema.
openssl
benutzt.A certificate contains an identity (hostname, organization, etc.) and a public key (RSA, DSA, ECDSA, ed25519, etc.), and is either signed by a Certificate Authority or is Self-Signed.
openssl
¶1openssl genrsa -aes256 -out ca-key.pem 4096
1openssl req -new -x509 -sha256 -days 365 -key ca-key.pem -out ca.pem
1openssl x509 -in ca.pem -text
2openssl x509 -in ca.pem -purpose -noout -text
1openssl genrsa -out cert-key.pem 4096
subject
or common name.1openssl req -new -sha256 -subj "/CN=yourcn" -key cert-key.pem -out cert.csr
extfile
with all the SANs (subject alternative names)1echo "subjectAltName=DNS:your-dns.record,IP:257.10.10.1" >> extfile.cnf
2# optional
3echo "extendedKeyUsage = serverAuth" >> extfile.cnf
1openssl x509 -req -sha256 -days 365 -in cert.csr -CA ca.pem -CAkey ca-key.pem \
2 -out cert.pem -extfile extfile.cnf -CAcreateserial
COMMAND | CONVERSION |
---|---|
openssl x509 -outform der -in cert.pem -out cert.der |
PEM to DER |
openssl x509 -inform der -in cert.der -out cert.pem |
DER to PEM |
openssl pkcs12 -in cert.pfx -out cert.pem -nodes |
PFX to PEM |
1openssl verify -CAfile ca.pem -verbose cert.pem
easy-rsa
¶Easy-rsa
ist ein Shell-Skript und Frontend für openssl
.
cfssl
von Cloudflare macht’s einfacher ¶Cfssl
ist ein Tool von Cloudflare aus dem Jahr 2014, welches ohne die Verwendung von openssl
auskommt.
Da die offizielle Dokumentation von
cfssl
etwas dürftig ist, sind diese privaten Blog-Artikel sehr hilfreich!
1{
2 "CN": "my-service.fqdn.tld",
3 "key": {
4 "algo": "ecdsa",
5 "size": 256
6 },
7 "names": [
8 {
9 "C": "DE",
10 "ST": "RLP",
11 "L": "Ludwigshafen",
12 "O": "AG MicroComputer",
13 "OU": "Pagong"
14 }
15 ],
16 "hosts": [
17 "my-service.fqdn.tld",
18 "10.12.13.14"
19 ]
20}
1$ cfssl genkey my-service-csr.json | cfssljson -bare my-service
22025/03/21 15:14:28 [INFO] generate received request
32025/03/21 15:14:28 [INFO] received CSR
42025/03/21 15:14:28 [INFO] generating key: rsa-2048
52025/03/21 15:14:28 [INFO] encoded CSR
6
7$ ls -l
8-rw-r--r-- 1 pagong users 1155 Mar 21 15:14 my-service.csr
9-rw-r--r-- 1 pagong users 322 Mar 21 15:08 my-service-csr.json
10-rw------- 1 pagong users 1679 Mar 21 15:14 my-service-key.pem
11
12$ cfssl certinfo -csr my-service.csr
openssl
oder step-ca
oder OPNsense
cfssl
: siehe nächster Abschnitt1$ cp my-service.pem my-service.crt
2$ cfssl certinfo -cert my-service.crt
1$ cfssl gencert -ca my-ca.pem -ca-key my-ca-key.pem my-service-csr.json |
2 cfssljson -bare my-service
1$ cfssl gencert -remote=remote_server my-service.csr.json |
2 cfssljson -bare my-service
1$ ls my-service*
2my-service.csr
3my-service-csr.json
4my-service-key.pem
5my-service.pem
6
7$ cp my-service.pem my-service.crt
8$ cfssl certinfo -cert my-service.crt
cfssl sign
Vorgang kann auch noch eine JSON-Konfigurationsdatei cfssl-cfg.json
mit Profile-Definitionen genutzt werden, um das “Finetuning” des Verwendungszwecks (oder anderer Parameter) des Zertifkats anzupassen.1$ cfssl sign -config cfssl-cfg.json -profile profile_name \
2 -ca ca.pem -ca-key ca-key.pem my-service.csr |
3 cfssljson -bare my-service
Dieses Beispiel wurde von Rob Blackbourn übernommen.
1{
2 "CN": "Custom Widgets Root CA",
3 "key": {
4 "algo": "rsa",
5 "size": 4096
6 },
7 "names": [
8 {
9 "C": "GB",
10 "L": "London",
11 "O": "Custom Widgets",
12 "OU": "Custom Widgets Root CA",
13 "ST": "England"
14 }
15 ]
16}
1$ cfssl genkey -initca root-ca-csr.json |
2 cfssljson -bare root-ca
3
4$ ls root-ca*
5root-ca.csr
6root-ca-csr.json
7root-ca-key.pem
8root-ca.pem
1$ cp root-ca.pem root-ca.crt
2$ cfssl certinfo -cert root-ca.crt
Dieses Beispiel wurde ebenfalls von Rob Blackbourn übernommen.
1{
2 "CN": "Custom Widgets Branch CA",
3 "key": {
4 "algo": "rsa",
5 "size": 2048
6 },
7 "names": [
8 {
9 "C": "GB",
10 "L": "London",
11 "O": "Custom Widgets",
12 "OU": "Custom Widgets Branch CA",
13 "ST": "England"
14 }
15 ],
16 "ca": {
17 "expiry": "42720h"
18 }
19}
1$ cfssl gencert -initca branch-ca-csr.json |
2 cfssljson -bare branch-ca
1$ cfssl sign -config cfssl-cfg.json -profile branch_ca \
2 -ca root-ca.pem -ca-key root-ca-key.pem branch-ca.csr |
3 cfssljson -bare branch-ca
4
5$ ls branch-ca*
6branch-ca.csr
7branch-ca-csr.json
8branch-ca-key.pem
9branch-ca.pem
1$ cp branch-ca.pem branch-ca.crt
2$ cfssl certinfo -cert branch-ca.crt
Dies erfolgt ähnlich zum Vorgang der Signierung der Branch-CA durch die Root-CA. Nur wird in diesem Fall die Leaf-CA durch die Branch-CA signiert.
1{
2 "CN": "Custom Widgets Leaf CA",
3 "key": {
4 "algo": "ecdsa",
5 "size": 384
6 },
7 "names": [
8 {
9 "C": "GB",
10 "L": "London",
11 "O": "Custom Widgets",
12 "OU": "Custom Widgets Leaf CA",
13 "ST": "England"
14 }
15 ],
16 "ca": {
17 "expiry": "8760h"
18 }
19}
1$ cfssl gencert -initca leaf-ca-csr.json |
2 cfssljson -bare leaf-ca
1$ cfssl sign -config cfssl-cfg.json -profile leaf_ca \
2 -ca branch-ca.pem -ca-key branch-ca-key.pem leaf-ca.csr |
3 cfssljson -bare leaf-ca
4
5$ ls leaf-ca*
6leaf-ca.csr
7leaf-ca-csr.json
8leaf-ca-key.pem
9leaf-ca.pem
1$ cp leaf-ca.pem leaf-ca.crt
2$ cfssl certinfo -cert leaf-ca.crt
Umwandeln von KEY- und CRT-Dateien zu Kubernetes secrets
zur Verwendung in einem mit TLS abgesicherten Web-Service.
1$ CRT="$SRCDIR/my-service.crt"
2$ KEY="$SRCDIR/my-service.key"
3$ kubectl -n my-namespace create secret tls my-service-tls --cert="$CRT" --key="$KEY"
4$ kubectl -n my-namespace describe secret my-service-tls
OPNsense
ist eine Firewall-Software, die auf FreeBSD basiert. Neben der Aufgabe als Firewall können damit über Plugins auch viele andere Netzwerk-Dienste (u.A. DNS, DHCP, NTP, VPN, etc.) eingerichtet und verwaltet werden.
OPNsense enthält Plugins, die ein grafisches Frontend zu openssl
und ACME
bieten:
HowTo “Setup Self-Signed Certificate Chains”
Online-Artikel zur Nutzung von OPNsense als CA:
Online-Blog-Artikel zum Plugin acme-client
:
Links zur Online-Dokumentation von OPNsense:
acmeclient
trust
Im MatrixPost-Blog wird die Nutzung der PKI Möglichkeiten in Windows Server gezeigt.
THEMA | LINK |
---|---|
PKI Design | Part 1 |
Offline Root CA | Part 2 |
Intermediate CA | Part 3 |
Client Certificates | Part 4 |
Auto Enrollment | Part 5 |
cert-manager
¶Der cert-manager
wird für das automatisierte Anfordern und Erneuern von Zertifikaten in Kubernetes-Clustern benutzt.
Smallstep
¶Während der Vorbereitung dieses Vortrags bin ich auf ein “YouTube”-Video und Blog gestossen, in welchem Open-Source-Tools der Firma Smallstep zum Aufbau einer privaten CA benutzt wurden:
Bei der weiteren Recherche habe ich dieses Dokument des Firmengründers Mike Malone gefunden. Dort werden alle Eigenschaften von X.509v3-Zertifikaten und deren Life-Cycle klar und präzise erläutert:
Server-Tool:
step-ca
zum Betreiben einer Certificate Authority CA.Client-Tool:
step
zum Anfordern und Verwalten von Zertifikaten aller Art.Diese Artikel im Smallstep-Blog werden als Basis und Inspiration für meine Experimente dienen.
Das Projekt “Let’s Encrypt” hat zum Ziel, dass alle Web-Seiten und sämtlicher Internet-Traffic nur noch in verschlüsselter Form (per TLS-Protokoll) übertragen werden.
Zur Überprüfung, dass ein Webseiten-Betreiber tatsächlich die Kontrolle über den FQDN der Webseite hat, wurde das ACME-Protokoll eingeführt, welches “Domain-Validation” DV benutzt:
Both step
and step-ca
are natively integrated with the ACME protocol. step
can be used to request ACME certificates from any ACME server, while step-ca
is a fully functional private ACME server that works with all popular ACME clients.
Im “Caddy” Webserver ist, anstelle von “Let’s Encrypt”, der Zertifikatsprovider “Zero-SSL” automatisch aktiviert.
Certbot is EFF’s tool to obtain certs from “Let’s Encrypt”. It’s written in Python.
It can also act as a client for any other CA that uses the ACME protocol.
Let’s Encrypt/ACME client and library written in Go.
A pure Unix shell script implementing ACME client protocol.
My-CA.pem
) or (My-CA.crt
) to /etc/pki/trust/anchors/
1sudo update-ca-certificates
Refer to documentation here and here. See also Blog post.
My-CA.pem
) to /etc/pki/ca-trust/source/anchors/
or /usr/share/pki/ca-trust-source/anchors/
1sudo update-ca-trust
Refer to documentation here. See also Blog post.
My-CA.pem
) or (My-CA.pem
) into /usr/local/share/ca-certificates/
.1sudo update-ca-certificates
Refer to documentation here and here.
System-wide – Arch(p11-kit)
(From arch wiki)
1trust anchor --store My-CA.crt
/etc/ca-certificates/trust-source/anchors/
directory.1sudo update-ca-trust
wiki page here
See also:
Assuming the path to your generated CA certificate as C:\My-CA.pem
, run:
1Import-Certificate -FilePath "C:\My-CA.pem" -CertStoreLocation Cert:\LocalMachine\Root
-CertStoreLocation
to Cert:\CurrentUser\Root
in case you want to trust certificates only for the logged in user.OR
In Command Prompt, run:
1certutil.exe -addstore root C:\My-CA.pem
certutil.exe
is a built-in tool (classic System32
one) and adds a system-wide trust anchor.Siehe auch “Step 4 – Import root certificate to users devices” im Kapitel “openssl” bzw. den “Step 5” im Kapitel “cfssl” in einer anderen Fundstelle.
For Windows:
1mmc
Auch im “Proxmox”-Wiki gibt es einen Artikel zum Hinzufügen von Zertifikaten zum Windows Trust-Store.
Assuming the path to your generated CA certificate is ~/My-CA.pem
, run (as root):
1security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/My-CA.pem
A dialog box will appear asking for an administrator’s username and password. Enter it, and it will be stored in the system keychain. This can be verified by opening the Keychain Access
application (/Applications/Utilities/Keychain Access.app
). On the sidebar under System Keychains
select System
, and the new certificate should be listed.
Siehe auch “Step 4 – Import root certificate to users devices” im Kapitel “openssl” bzw. den “Step 5” im Kapitel “cfssl” in einer anderen Fundstelle.
For MAC OS:
Auch im “Proxmox”-Wiki gibt es einen Artikel zum Hinzufügen von Zertifikaten zum Trust-Store von macOS.
The exact steps vary device-to-device, but here is a generalised guide:
Encryption and Credentials
section. It is generally found under Settings > Security > Encryption and Credentials
Install a certificate
CA Certificate
My-CA.pem
on your SD Card/Internal Storage using the file manager.Apple makes this far more difficult than it should be:
My-CA.pem
to the iOS device through iCloud, AirDrop, or a direct download from your server.Profile Downloaded
item will be at the top. If it is not there, you may find it in General → VPN & Device Management
.Install
.Install
again.Install
twice wasn’t enough, a confirmation button will appear at the bottom of the screen. Click Install
one last time.Tipps von Mozilla:
To import a client certificate to Firefox, open the menu and select Preferences.
Navigate to the Certificates tab and click View Certificates, then Your Certificates, and finally, Import.
Locate your PKCS12 file (.p12 or .pfx), enter the password, and confirm the import.
Your certificate will appear under Your Certificates in Firefox Certificate Manager.
Viele Quellen sagen, dass “Chrome” (und “Edge”, etc.) den Trust-Store des Betriebssystems nutzen!
For Linux, Chrome uses its own certificate store. You can import your Root CAs in Chrome directly.
In Chrome open Settings –> Privacy and security –> Security –> Manage certificates –> Authorities
Die Bilder stammen aus dieser guten Anleitung von MatrixPost!