In Zeiten der Vollüberwachung durch die NSA und andere Geheimdienste weltweit sind auch die bekannten Certificate Authorities (CA) wie z.B. Verisign nicht mehr wirklich vertrauenswürdig. Man kann davon ausgehen, dass die NSA auch Zugriff auf die Schlüssel dieser CAs hat, sodass sie gefälschte Zertifikate ausstellen kann. Diese können dann dazu dienen, Datenverkehr zu manipulieren und mitzuschneiden. So ist die Verschlüsselung natürlich nutzlos und private Daten gelangen in falsche Hände.
Wer sich unabhängig von den großen, offiziellen Certificate Authorities machen will, kann ganz einfach seine eigene eröffnen. Dazu braucht es nicht mehr als eine Ubuntu / Linux – Installation und das OpenSSL Paket, das alles mitbringt, was wir für das Erzeugen der Zertifizierungsstelle und das Signieren von Serverzertifikaten brauchen. Diese selbst erstellten Zertifizierungsstellen und die von ihnen signierten Zertifikate sind natürlich nicht von Browsern und Betriebssystemen anerkannt, sodass diese Warnmeldungen ausgeben. Das kann man aber verhindern, indem man auf diesen Computern das CA Root Zertifikat installiert.
Stellt zuerst sicher, dass OpenSSL installiert ist:
sudo apt-get install openssl
Ihr solltet euch gerade im Homeverzeichnis befinden. Dort erstellen wir jetzt einen Ordner für unsere Zertifizierungsstelle, in dem sich später alle benötigten Dateien befinden werden.
mkdir ca
cd ca
mkdir certs newcerts private
In diesem CA Ordner werden außerdem drei weitere Ordner erstellt. “certs” und “private” enthalten später das Root-Zertifikat der Certificate Authority und “private” die streng geheime private Schlüsseldatei. Diese wird besonders gut geschützt:
chmod 600 private
Damit das Script zur Generierung der Certificate Authority funktioniert, werden außerdem noch zwei Dateien benötigt, die so erzeugt werden:
echo '01' > serial
touch database.txt
Die Dateistruktur im Homeverzeichnis sollte jetzt so aussehen:
- Home
- ca
- certs
- newcerts
- private
- serial
- database.txt
CA Konfiguration erstellen
Als nächstes muss die Konfigurationsdatei “caconfig.cnf” erstellt werden, in die die Einstellungen für die Zertifizierungsstelle geschrieben werden:
nano caconfig.cnf
Inhalt der Datei:
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/database.txt
new_certs_dir = $dir/newcerts
certificate = $dir/certs/cacert.pem
serial = $dir/serial
private_key = $dir/private/cakey.pem
x509_extensions = usr_cert
default_days = 3650
default_md = sha1
preserve = no
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 4096
default_keyfile = cakey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only
req_extensions = v3_req
[ req_attributes ]
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = DE
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Germany
localityName = Locality Name (city, district)
organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
commonName = Common Name (hostname, FQDN, IP, or your name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 40
[ usr_cert ]
basicConstraints= CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
nsComment = ''OpenSSL Generated Certificate''
subjectAltName=email:copy
issuerAltName=issuer:copy
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:TRUE
Die Konfiguration könnt ihr so 1:1 übernehmen.
Certificate Authority generieren
… die Generierung der CA beginnt mit der Erzeugung eines Private Keys, der unter private/cakey.pem gespeichert wird.
openssl req -new -x509 -days 3650 -config caconfig.cnf -keyform PEM -keyout private/cakey.pem -outform PEM -out certs/cacert.pem
Dieser Befehl erzeugt Zertifikate mit einer Gültigkeitsdauer von 10 Jahren. Das sollte erst einmal reichen ;)
Ihr werdet nach verschiedenen Daten gefragt. Zuerst müsst ihr eine PEM Passphrase vergeben, mit der die Cert. Auth. vor unbefugten Zugriffen geschützt wird. Dieses Passwort sollte möglichst lang und komplex sein.
Danach werdet ihr nach verschiedenen Attributen gefragt, die die CA haben soll. Dazu gehören Länderkürzel, Land, Stadt, Firmen- oder Organisationsname, Name des Erstellers der Zertifizierungsstelle und E-Mail Adresse. Ihr könnt hier eintragen, was ihr wollt. Seid kreativ!
Das war’s auch schon. Die Certificate Authority ist jetzt erstellt und Root-Zertifikat und der dazugehörige Private Key liegen in den entsprechenden Ordnern, die wir vorher angelegt haben. Das öffentliche Root-Zertifikat liegt jetzt in “certs” und der private Schlüssel in “private”. An dieser Stelle ist es sinnvoll, ein Backup von beiden Dateien zu machen. Gehen die Dateien verloren, kann man mit dieser CA keine Zertifikate mehr erstellen und muss eine neue CA aufbauen. Dabei müssen dann ggf. auch alle bisher ausgestellten Serverzertifikate erneuert werden. Also: Unbedingt den CA Ordner sichern!
Das öffentliche Zertifikat (certs/cacert.pem) muss später auf alle Rechner importiert werden, auf denen man später keine SSL Warnungen bekommen will. Wie zu Beginn schon erklärt, ist die selbst erstellte CA nämlich nicht von Betriebssystemen und Browsern anerkannt, sodass es zu Warnmeldungen kommt. Installiert man dagegen das Root-Zertifikat der CA, ist auch die selbst erstellte CA Browsern und Betriebssystem bekannt und wird akzeptiert.
Unser Root-Zertifikat liegt im .pem Format vor. Windows beispielsweise nimmt aber nur Zertifikate im DER Format an, sodass man das .pem Zertifikat konvertieren muss:
openssl x509 -in certs/cacert.pem -outform der -out certs/cacert.crt
Jetzt liegen Zertifikate beider Typen im Ordner “certs” und können auf andere Computer übertragen werden, wo man sich dann importieren kann.
(CA Root Zertifikate können in Mozilla Firefox über “Einstellungen => Erweitert => Verschlüsselung => Zertifikate anzeigen => Zertifizierungsstellen => Importieren” importiert werden.)
Serverzertifikate generieren
Die Zertifizierungsstelle ist jetzt fertig und einsatzbereit. Fehlen noch die Zertifikate, die dann von der Certificate Authority signiert werden können und schließlich zum Einsatz kommen. Mit diesen Zertifikaten kann dann beispielsweise ein Webserver abgesichert werden.
Für die Arbeit mit den Serverzertifikaten wird ein weiteres Verzeichnis “myssl” neben dem “ca” Verzeichnis erstellt:
mkdir myssl
cd myssl
Innerhalb dieses myssl Ordners gibt es zwei Unterordner “private” und “public”. Wie die Namen schon vermuten lassen, enthält der “private” Ordner den privaten, geheimen Schlüssel, der später zum öffentlichen Zertifikat passt, welches sich in “public” befinden wird. Dieser private Schlüssel, von dem die Rede ist, ist übrigens ein ganz anderer, als der der Zertifizierungsstelle. CA und Serverzertifikate müssen streng getrennt betrachtet werden. Wir sind hier gerade mit den Serverzertifikaten beschäftigt.
Erstellen wir also die eben angesprochenen Unterordner:
mkdir private public
Wie bei der Generierung der CA muss auch hier ein zufälliger Private Key erzeugt werden:
openssl genrsa -out private/privkey.pem 4096
… der ebenfalls gut geschützt wird:
chmod 600 private/privkey.pem
Im nächsten Schritt wird eine Zertifikatsanfrage gestellt, welche dann von der CA verarbeitet werden wird:
openssl req -new -key private/privkey.pem -out cert-req.pem
Wieder werden einige Attribute zum Zertifikat abgefragt. Mit einem Unterschied: Das Feld “Common Name / FQDN” muss den Domainnamen enthalten, für den das SSL Zertifikat gelten soll. Will ich also meine Domain meinedomain.tld absichern, muss das so eingegeben werden. Ohne Protokoll; einfach nur “meinedomain.tld”. Subdomains wie z.B. “rss.meinedomain.tld” kann man mit einem Wildcard-Zertifikat absichern, das dann für alle Subdomains gilt (auch www.meinedomain.tld). Dazu schreibt man “*.meinedomain.tld”.
Schließlich erhält man die Zertifikatsanfrage “cert-req.pem”.
Um die Anfrage zu bearbeiten und das Zertifikat von der Certificate Authority signieren zu lassen, wechseln wir wieder in das CA Verzeichnis:
cd ../ca/
… und führen folgenden Befehl aus:
openssl x509 -days 3650 -CA certs/cacert.pem -CAkey private/cakey.pem -req -in ../myssl/cert-req.pem -outform PEM -out ../myssl/public/cert.pem -CAserial serial
Man wird nach der PEM Passphrase der Certificate Authority gefragt und muss den Vorgang zwei mal mit “y” bestätigen. Damit wird das öffentliche Zertifikat für die angegebene Domain erzeugt und landet in myssl/public/cert.pem
Die Zertifikatsanfrage kann jetzt wieder gelöscht werden; sie wird nicht mehr benötigt:
cd ../myssl/
rm cert-req.pem
Nach jedem Unterzeichnungsvorgang kann dann das fertige, öffentliche Zertifikat (myssl/public/cert.pem) zusammen mit dem immer gleich bleibendem private Key (myssl/private/privkey.pem) exportiert werden und auf einem Webserver benutzt werden. Dazu auch: Webserver absichern mit SSL. (Artikel ab Aktivierung von mod_ssl) Danach kann man das öffentliche Zertifikat ebenfalls löschen.
rm public/cert.pem
Für alle weiteren Zertifikate, die erstellt werden sollen verfährt man genauso. Nur der Private Key muss nicht mehr erzeugt werden. Der Ablauf für jedes weitere Zertifikat ist also wie folgt:
- Zertifikatsanfrage stellen und Daten eingeben (Auf Domainnamen achten!)
- Zertifikatsanfrage von der Certificate Authority verarbeiten lassen
- cert.pem und eine Kopie von privkey.pem auf den Webserver kopieren, wo SSL genutzt werden soll
- Zertifikatsanfrage und öffentliches Zertifikat können wieder gelöscht werden.
Der Ordner für die Zertifizierungsstelle bleibt unverändert. Hier also bitte nichts löschen ;)
Ich hoffe, ich habe die Vorgänge ausreichend genau und verständlich erklärt. Sollten dennoch Fragen offen geblieben sein, einfach Fragen ;)
Wenn ihr Fehler in der Anleitung findet, bitte gleich in den Kommentaren melden! Danke!