Mein Server, meine Domain, mein SSL-Zertifikat

firefox_untrusted

Wer auf seine Owncloud, den eigenen Email-Server oder auch den Admin-Bereich von WordPress und Co. über das Internet zugreifen möchte, sollte die Kommunikation tunlichst absichern. Ansonsten können Dritte etwa per Man in the middle-Angriff die komplette Kommunikation mitlesen und dabei auch die Login-Daten abgreifen. Die Technologie der Wahl, unter den Akronymen SSL bzw. TLS bekannt, ist in letzter Zeit zwar heftig unter die Räder gekommen, aber noch alternativlos. Sie setzt auf Verschlüsselung und auf Zertifikate, um die Vertrauenswürdigkeit der Verbindung zu beglaubigen. Allerdings gehen diese Zertifikate kräftig ins Geld, wenn man sie von einem reputierten kommerziellen Anbieter erwirbt. Eine Alternative zum Nulltarif, für persönliche Zwecke absolut ausreichend, ist ein selbst signiertes Zertifikat.

Wobei die Betonung auf „persönlich“ liegt: Ein selbst signiertes Zertifikat taugt nicht zur Absicherung von für die Öffentlichkeit gedachten Websites. Weil das Zertifikat nicht von einer bekannten Instanz ausgestellt wurde, wird der Webbrowser – wie im Bild oben Firefox – meckern, die aufgerufene Seite sei nicht vertrauenswürdig. Als Aussteller des Zertifikats weiß ich, was ich gemacht habe, und vergleiche sicherheitshalber noch einmal den Fingerprint, bevor ich den Browser anweise, meinem Zertifikat in Zukunft zu vertrauen; dies muss ich für jeden Browser/Client/App (PC, Smartphone, iPad …), der/die über SSL Kontakt aufnehmen soll, ebenfalls einmalig tun.

Ein fremder Besucher wird dieses Vertrauensbekenntnis nicht ablegen, wenn er gut bei Trost ist – schließlich kennt er den Aussteller des Zertifikates (mich) nicht. Ich jedenfalls würde mich auf einer fremden Website, deren Betreiber sich kein offizielles Zertifikat leisten mag, nicht registrieren. Nur das Zertifikat kann mir garantieren, dass die Gegenstelle authentisch ist, dass also beispielsweise die Bank-Website, die ich gerade ansurfe, wirklich meine Bank ist und nicht eine gekaperte Domain. Dass einige von den Browser-Herstellern als vertrauenswürdig eingestufte Zertifizierungsstellen mit laxen Praktiken selbst ihre Vertrauenswürdigkeit und damit die Vertrauenswürdigkeit des gesamten Systems auf Spiel setzen, dass schließlich der Heartbleed-Bug in Openssl wie eine Bombe ins Web of Trust eingeschlagen ist, könnte Fatalisten zu der Annahme provozieren, dass man seine Zertifikate dann auch gleich selbst signieren kann … Unter dem Strich verschlüsseln jedenfalls beide – das selbst erstellte wie das von einer Zertifizierungsstelle beglaubigte Zertifikat – die Web-Kommunikation genauso gut, solange sie nicht kompromittiert sind.

Ein selbst erstelltes Zertifikat ist auf einer Linux-Maschine schnell angefertigt. Der Einfachheit halber kann man das aus der Ferne direkt auf seinem Web-Server erledigen. Voraussetzung ist die openssl-Software, die unter Debian, Ubuntu und Co. von der Kommandozeile als Root-User bzw. per sudo wie folgt installiert wird:

$ apt-get install openssl

Es gibt keinen standardmäßigen Platz, wo selbst erstellte Zertifikate gespeichert werden. Das Debian-Wiki schlägt als Speicherort ein zu erstellendes Verzeichnis /etc/ssl/localcerts vor. Nun denn:

$ mkdir /etc/ssl/localcerts
$ cd /etc/ssl/localcerts

1. Privaten Schlüssel erzeugen

Zunächst erzeugt man sich einen privaten Schlüssel, in diesem Fall mit dem openssl-Kommando genrsa:

$ openssl genrsa -out private.key 2048

Ein solcher nach dem RSA-Verfahren erstellter Schlüssel mit einer Länge von 2048 Bits gilt nach heutigen Maßstäben als sicher, wenngleich Debian inzwischen schon doppelt so große Schlüssel fordert. Klarer Fall: Die Datei private.key darf man nicht aus der Hand geben.

2. CSR-Datei generieren

Der Certificate Signing Request (CSR) bekommt als Argument den soeben erzeugten Key und spuckt das Zertifikat in Form einer csr-Datei aus. Dies ist ein dialogbasierter Befehl, die Abfragen und Eingaben sehen für die fiktive Website example.com wie folgt aus:

$ openssl req -new -key private.key -out example.com.csr
[...]
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Berlin
Locality Name (eg, city) []:Berlin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Wichtig ist, im Dialog als Common name den korrekte Domainnamen anzugeben. Wenn die zu sichernde Domain example.com heißt, das Zertifikat aber auf exmple.com (Tippfehler) oder example.de (andere Top-Level-Domain) ausgestellt ist, so wird diese Unstimmigkeit später im Browser mit einer Fehlermeldung quittiert werden. Deshalb ist auch example.com nicht gleich www.example.com, wenngleich der Webserver so konfiguriert sein mag, dass er für beide Varianten dieselbe Website ausliefert.

Wenn eine Subdomain, z.B. owncloud.example.com, über https laufen soll, dann muss das Zertifikat ebenfalls auf diese Subdomain ausgestellt werden, und nicht auf example.com. Wenn mehrere Subdomains mit demselben Zertifikat abgesichert werden sollen, also etwa owncloud.example.com und blog.example.com, dann hilft ein Wildcard-Zertifikat weiter: Wie oben im Beispiel-Dialog deckt *.example.com alle Fälle ab; das Sternchen ist das Wildcard-Zeichen.

Sollte all das nicht reichen, gibt es auch noch

  • Subject Alternative Names (SAN) zur Verwendung mehrerer Domains/Ressourcen (z.B. Web-, E-Mail-Adresse) mit einem Zertifikat.
  • Server Name Indication (SNI), um auf einer IP-Adresse mehrere Virtual Hosts mit individuellen Zertifikaten auszustatten (wird nicht von alten Webbrowsern und unter Windows XP unterstützt). Ohne SNI geht pro IP-Adresse immer nur ein Zertifikat.

3. Zertifikat signieren

Um das Zertifikat tatsächlich signieren und damit beglaubigen zu lassen, übersendet man die eben erzeugte csr-Datei entweder an einen kommerziellen Anbieter (das Community-betriebene CAcert hat zur Zeit seine eigenen Probleme) – oder man macht es eben selbst:

$ openssl x509 -req -days 730 -in example.com.csr -signkey private.key -out example.com.crt

Dies erstellt ein Zertifikat nach dem Standard X.509, signiert vom eigenen privaten Schlüssel. Das Zertifikat wird in zwei Jahren (730 Tage) ablaufen. Danach kann man es neu signieren.

Einen Signing Request einsehen/prüfen

$ openssl req -in example.com.csr -text -verify -noout

Den Fingerprint eines Zertifikates zum Vergleich kalkulieren

$ openssl x509 -in example.com.crt -noout -fingerprint

Ein Zertifikat zurückziehen

Ein selbst signiertes Zertifikat kann ablaufen, der Eigentümer kann es löschen; zurückgezogen werden kann es nicht. Wie auch? Ein selbst signiertes Zertifikat ist schon Root-Zertifikat; es gibt keine übergeordnete Instanz, die es verwaltet.

$ openssl ca -revoke example.com.csr

Ein Rückruf-Request wie dieser wird mit einem selbst signierten Zertifikat nicht funktionieren. Das ist nicht schlimm, solange man selbst nur dieses Zertifikat nutzt und es im Falle einer Kompromittierung aus dem Verkehr zieht.

SSL auf dem eigenen Webserver konfigurieren

Wie das frisch generierte Zertifikat auf dem eigenen Webserver aktiviert wird, so dass Verbindungen über SSL möglich sind, zeigen diese Konfigurationsbeispiele für Apache und Nginx. Und dabei muss der Poodle natürlich draußen bleiben!

Nur Android macht Ärger

Ein nach der oben geschilderten Methode erzeugtes selbst-signiertes Zertifikat habe ich erfolgreich Windows- und Linux-PCs sowie einem iPad (IOS 7) beibringen können. Sie alle meckerten zunächst über den unbekannten Aussteller, erlaubten aber die Prüfung und Hinzufügung des Zertifikats zum Gerät. Nur unter Android funktioniert solch ein selbst-signiertes Zertifikate nicht. Android-Smartphones wollen Sie nicht importieren, solange nicht zusätzlich das CA-Flag gesetzt ist.

11 comments on “Mein Server, meine Domain, mein SSL-Zertifikat”

  1. Hallo!

    Ein sehr interessanter Artikel! Vielen Dank dafür!
    Ich betreibe zwar keine eigene Seite, spiele aber ab und zu mit meinem System herum und will mir dann auch mal selber ein Zertifikat anlegen und es Apache dann natürlich mal weiterreichen. Der zweite Teil dazu kommt dann noch?

    Beste Grüße aus Frankfurt
    Rudy

  2. Danke für den netten Kommentar. Habe dieser Tage viel zu tun. Deshalb ist es arg ruhig hier im Blog, und die Fortsetzung muss noch warten.

  3. Hey, toller Beitrag.
    Hast du raus gefunden, wie dieses CA Flag gesetzt wird? Hängebda auch gerade bei der APP CAdroid fest…

  4. @Thomas: Stimmt, ich hatte eine Fortsetzung für den Zertifikat-Import unter Android versprochen. Und jetzt steht sie auch im Blog!

Schreibe einen Kommentar