Zertifikat bauen
export TARGET=<Rechnername>
mkdir $TARGET
cp config-template.cnf ${TARGET}/${TARGET}.cnf
cd $TARGET
vim ${TARGET}.cnf
# alle FIXME-Zeilen suchen und anpassen
openssl genrsa -out ${TARGET}.key 4096
openssl req -new -sha512 -key ${TARGET}.key -config ${TARGET}.cnf -out ${TARGET}.csr
openssl req -noout -text -in ${TARGET}.csr | less
# nachschauen ob da alle alternativeNames richtig drinstehen, ob hash sha512 ist und ob 4096 bit schluessellaenge sind
pwgen -s 15 | tee ${TARGET}.pin
# .key geheimhalten und auf dem Webserver installieren
# .csr auf der Rechenzentrums-CA-Webseite hochladen, PIN angeben (wird fuer Widerruf gebraucht)
Hinweise
- komplette chain installieren im apache; das
check_http
im CIP verifiziert die chain nicht! - im zweifel auf https://ssllabs.com o.Ä. checken
Benutzer-Zertifikat
Geht genauso wie ein Serverzertifikat oben. Hochladen auch ueber das o.g. Serverzertifikats-Formular, als Zertifikatsprofile "User" angeben. Als Konfigurationstemplate folgendes verwenden: Benutzer-Konfigurations-Vorlage
Key-Pinning
ab hier nur fuer Leute, die das auch wirklich brauchen
TLSA / DANE
Funktioniert:
- https
- smtp
- nur mit DNSSEC
- braucht fertiges Zertifikat
empfohlene Vorgehensweise:
openssl rsa -in example.com.key -outform der -pubout | openssl sha256
(stdin)= 3d17d0dd8541772799bc3a5faf32e812e0baafccf7c35d0447977217db21420f
resultierender Record:
_443._tcp.www.example.com. IN TLSA 1 1 1 3d17d0dd8541772799bc3a5faf32e812e0baafccf7c35d0447977217db21420f
Erklaerung der Optionen siehe unten
funktioniert auch
openssl x509 -in ${TARGET}.crt -outform DER | openssl sha256
(stdin)= a1895145a50e0941f88db075ea25af57204907537602df1f80f2584346c794ca
# statt ${TARGET}.crt geht auch cert-$serial.pem wie vom DFN verteilt, ist dasselbe
resultierender Record:
_443._tcp.www.example.com. IN TLSA 1 0 1 a1895145a50e0941f88db075ea25af57204907537602df1f80f2584346c794ca
Erklaerungen dazu
- 443 fuer https, mit _25 geht SMTP, etc., _tcp dito
- Die Optionen haben Bedeutung:
- 3 als erste Ziffer bedeutet "Domain issued", die Zertifikatskette wird nicht unbedingt zusaetzlich geprueft. Das Zertifikat ist direkt das Serverzertifikat
- erste Ziffer 2 heisst, dass die Zertifikatskette ebenfalls nicht geprueft wird, das Zertifikat ist ein CA-Zertifikat mit dem das Serverzertifikat signiert ist
- erste Ziffer 1 heisst, es ist das Serverzertifikat und die Zertifikatskette muss zusaetzlich noch valide von einer oeffentlich bekannten CA signiert sein (empfohlen)
- erste Ziffer 0 heisst, es ist das CA-Zertifikat und die Zertifikatskette muss zusaetzlich noch von einer oeffentlich bekannten CA signiert sein
- Die zweite Ziffer gibt an, ob im Record das ganze Zertifikat (0) oder nur der Pubkey (1) gehasht/angegeben wird
- Die dritte Ziffer gibt an, welcher Hash-Typ oder ob das komplette Zertifikat direkt im Record steht (empfohlen: 1 - SHA256)
Pinning auf die FAU-CA
_443._tcp.example.com. IN TLSA 0 0 1 989a3aaa5862dede9b42d6f05eabd639a60f5d526c4ae128b98aa18fbc2f0f4a
# aus: openssl x509 -in fau-ca.txt -outform DER | openssl sha256
Das gibts als kurzes praktisches Makro im Uni-DNS:
TLSA_PIN_HTTPS_TO_FAUCA(hostname)
Näheres weiss der DNS-Admin deines Vertrauens.
HTTPS Public Key Pinning (HPKP)
Achtung: HPKP ist riskant und es ist sehr leicht moeglich das so kaputtzukonfigurieren, dass ein Hostname auf lange Zeit unbenutzbar "verseucht" ist. Finger weg, ausser du weisst ganz genau was du tust.
Apache-Config sollte irgendwie ungefaehr wie folgt aussehen:
<VirtualHost _default_:443>
Use SSLConfig
# DANGER: remember to add a new certificate in time with a second pin-sha256 statement:
# for testing: only valid for 1h
Header add Public-Key-Pins "pin-sha256=\"Kifsh84a1clurPq6mVDx+O8gbeSPA3zCGXalMAfto6k=\"; max-age=3600"
...
- includeSubDomains kann man angeben (mit
;
getrennt nachmax-age
), ist aber meistens eine schlechte Idee, da es hierarchisch weiter unten stehende Webseiten kaputtmacht. - max-age sollte eigentlich laenger 3600s sein. Aber, wenn mal ein Schluessel kompromittiert wurde, koennte ein zu langes max-age Benutzer aussperren. Man muss daher mehrere Pins angeben und Reserve-Schluessel zu haben. Diese erzeugt man wie folgt:
openssl genrsa -out ${TARGET}.key.reserve-rsa4096 4096
openssl rsa -in ${TARGET}.key.reserve-rsa4096 -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
Falls das eigentliche Zertifikat dann mal kompromittiert wird kann man den Reserve-Schluessel um wie ganz oben beschrieben einen CSR zu erzeugen verwenden. Browser akzeptieren HPKP nur, wenn man mindestens zwei Pins setzt.
- Als Absicherung gegen diverse Versionen der kommenden Cryptocalypse kann man noch andere Typen dazuerzeugen:
# langes RSA, leider atm noch zu lang fuer Apple-Produkte
openssl genrsa -out ${TARGET}.key.reserve-rsa8192 8192
openssl rsa -in ${TARGET}.key.reserve-rsa8192 -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
# elliptische Kurven, "die uebliche die alle koennen" aus NSA Suite B:
openssl ecparam -out ${TARGET}.key.reserve-ecdsa-prime256v1 -name prime256v1 -genkey
# andere Kurve, etwas weniger Suspekt auch laut Bernstein:
openssl ecparam -out ${TARGET}.key.reserve-ecdsa-brainpoolP384t1 -name brainpoolP384t1 -genkey
# digests dazu:
openssl pkey -in ${TARGET}.key.reserve-ecdsa-prime256v1 -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64
openssl pkey -in ${TARGET}.key.reserve-ecdsa-brainpoolP384t1 -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64