SSL via StartSSL

SSL via StartSSL

Diesen Beitrag schrieb ich 8 Jahre und 8 Monate zuvor; die nachfolgenden Ausführungen müssen heute weder genau so nach wie vor funktionieren, noch meiner heutigen Meinung entsprechen. Behalte das beim Lesen (und vor allem: beim Nachmachen!) bitte stets im Hinterkopf.

Geschätzte Lesezeit: 5 Minuten

Ich brauch doch kein HTTPS?!

Die meisten Blog-Betreiber scheinen davon auszugehen, dass der Einsatz von SSL auf ihren Webseiten wenig sinnvoll ist: immerhin werden doch keine sensiblen Daten übertragen, oder? Und die Inhalte sind doch ohnehin für jeden im Netz abrufbar?

Nun – nein. Denn überlege mal, wie du neue Artikel erstellst: richtig, du loggst dich in das Backend des Systems ein. Und ganz gleich, was du verwendest – WordPress, TYPO3, Drupal etc. – du gibst hier sehr wohl sensible Daten an, nämlich einen Usernamen, ein Passwort… Damit ist das erste Argument, das gegen den Einsatz von SSL sprechen soll, widerlegt. Und das zweite? Die Verbindung über HTTPS zu ermöglichen ist ein Mehrwert für jeden Besucher deiner Webseite, denn er kann nun darauf vertrauen, dass die empfangenen Daten echt sind, unterwegs nicht manipuliert wurden – dass die Daten genau die sind, die dein Server abschickte. Vor allem in öffentlichen WLANs und ähnlichem ein nicht zu unterschätzender Vorteil! Und: verschlüsselte Seiten werden inzwischen sogar beim Suchmaschinen-Ranking bevorzugt.

„Der Einsatz von Verschlüsselung ist sinnvoll, grundsätzlich und in jeder Umgebung.“

Die Ressourcen für die Verwendung von HTTPS (in Form von RAM und CPU) sind heutzutage vernachlässigbar. Zum Testen ist ein Self-Signed-Zertifikat schon ausreichend: du kannst es selbst erstellen, es fallen keine Kosten an, und es tut seinen Zweck. Der Nachteil hierbei ist jedoch: der Browser wird eine Warnung anzeigen, dass das Zertifikat von einer nicht vertrauenswürdigen Stelle ausgestellt wurde und somit unsicher ist. Der Besucher der Website hat dann zwei Möglichkeiten: die Webseite nicht zu besuchen (was nicht in deinem Interesse ist) oder das unsichere Zertifikat dennoch akzeptieren (was nicht in des Users Interesse ist).

„Im produktiven Einsatz haben Self-Signed-Zertifikate nichts verloren.“

Ich habe früher meine Zertifikate über CAcert beantragt, doch die haben es bis heute nicht geschafft, fest in den Browsern integriert zu werden. Hier muss der Besucher das CAcert-Root-Zertifikat in sein System importieren, was in den meisten Fällen zuviel des Guten ist. Für Angebote von Nerds für Nerds ganz okay sozusagen – ich möchte mich aber einer breiteren Öffentlichkeit zuwenden. Mit Let’s encrypt! wird eine interessante Alternative an den Start gehen, welche jedoch noch nicht verfügbar ist.

Königsdisziplin ist sicherlich ein offizielles Zertifikat von Thawte, GeoTrust oder einem ähnlichen Anbieter zu kaufen – jedoch liegen die Kosten hier für die Laufzeit eines Jahres durchaus dreistellig, was sich wiederum für kleinere Präsenzen wirklich nicht rechnet. Ich habe mich für einen Mittelweg über StartSSL entschieden: ich erhalte hier ein für spiller.me sowie www.spiller.me für ein Jahr gültiges kostenfreies Zertifikat (Class 1). Die Verbindung wird im Browser grün angezeigt, da Zertifikate von dieser Stelle per default als vertrauenswürdig angesehen werden (auch netzpolitik.org nutzt ein StartSSL-Zertifikat, mindestens Class 2). Ich möchte dir hier zeigen, wie du das Zertifikat erstellst und anschließend einbindest. Alle Daten werden in einem Verzeichnis gesammelt – wo genau ist Geschmackssache. Ich nutze nginx und habe die Zertifikate dort hin gepackt, für apache2 analog. Die Pfade musst du in der Konfiguration deines Webservers entsprechend anpassen.

$ mkdir /etc/nginx/ssl

Account bei StartSSL erstellen und Domain validieren

Nachdem du dir einen Account bei StartSSL erstellt hast, wird für dich ein SSL-Clientzertifikat erzeugt, das du im Browser installieren solltest. Fortan dient es der Authentifizierung auf den Webseiten von StartSSL. Ist dein Account vollständig eingerichtet und freigeschaltet, musst du unter Validations Wizard → Domain Name Validation deine Domain (ohne www oder sonstiges!) hinzufügen. Ein Verfication Code wird an eine Mailadresse gesendet, die du dir aus einer Liste aussuchen kannst – stelle sicher, dass es diese Adresse auch wirklich gibt, denn den Code musst du anschließend eingeben, um die Inhaberschaft der Domain zu bestätigen.

KEY und CSR für StartSSL erstellen

Jetzt erstellst du dir einen Key namens DEINEDOMAIN.key mit 4096 Bit Länge und ohne Passwort, da es in der Praxis ungünstig ist, bei jedem Restart des Webservers ein Passwort angeben zu müssen:

$ cd /etc/nginx/ssl
$ openssl genrsa -out DEINEDOMAIN.key 4096

Sobald das getan ist, kannst du dir einen Certificate Signing Request (CSR) erstellen; er enthält den öffentlichen Schlüssel und Angaben zum Inhaber des Schlüssels. Der Inhalt dieser .csr-Datei ist jener, der an StartSSL übermittelt werden muss!

$ openssl req -new -sha256 -key DEINEDOMAIN.key -out DEINEDOMAIN.csr

Welche Werte du hier einträgst ist im Prinzip gleichgültig; bei Class 1-Zertifikaten werden alle Angaben mit Ausnahme des öffentlichen Schlüssels von StartSSL verworfen, da sie ohnehin nicht verifiziert werden können. Die StartSSL-Webseite bietet dir auch an, sowohl KEY als auch CSR auf deren Seite generieren zu lassen; davon rate ich dir ab! Der KEY ist geheim, und geheim soll er bleiben – generiere ihn selbst, gib ihn nicht aus der Hand, dann kann eigentlich nicht viel schief gehen.

Zertifikat bei StartSSL erstellen

  • Zur Erstellung deines Zertifikats navigierst du auf der Webseite von StartSSL zu Certificates Wizard; als Certificate Target wählst du im Drop-Down den Eintrag Web Server SSL/TLS Certificate.
  • Im nächsten Schritt bietet dir das System an, KEY und CSR zu erstellen – diesen Schritt überspringst du mit einem Klick auf Skip und kopierst den Inhalt deiner DEINEDOMAIN.csr in das Textfeld, das nun erscheint.
  • Anschließend wirst du aufgefordert, aus der Liste der von dir validierten Domains eine auszuwählen, für die das Zertifikat gelten soll; triff diese Auswahl und bestätige sie.
  • Füge nun die Subdomain www hinzu – dein Zertifikat wird nun gelten für DEINEDOMAIN.tld und für www.DEINEDOMAIN.tld.

Nun wird dein Zertifikat im PEM-Format erstellt; kopiere den gesamten Inhalt des Textfeldes in die Zwischenablage und von dort in eine Datei namens /etc/nginx/ssl/DEINEDOMAIN.crt. Anschließend werden noch die Rechte auf diese Dateien eingeschränkt:

$ chmod 0600 DEINEDOMAIN*

StartSSL Intermediate Certificate

Dein Webserver muss das Intermediate Certificate (IM) von StartSSL ausliefern, mit dem dein Zertifikat unterschrieben wurde – nur dann können alle Browser dein frisch erstelltes Zertifikat bis zu einer bekannten vertrauenswürdigen Instanz zurückverfolgen. (Übergehst du diesen Schritt, erhalten deine Besucher weiterhin die oben erwähnte Warnung.) Ziehe dir das Zertifikat vom StartSSL-Server:

$ wget https://www.startssl.com/certs/sub.class1.server.ca.pem

Die Website geht online…

Alle Vorarbeiten sind abgeschlossen; das Zertifikat kann nun in die Konfiguration deines Webservers eingebunden werden. Es ist sinnvoll, das nicht blind zu tun, sondern sich ein wenig zu informieren, was die verschiedenen Parameter bedeuten. Die nachfolgenden Konfigurationsschnipsel für nginx und apache2 sind erstmal sehr grundlegend, schließen aber die unsicheren Protokolle SSLv2 und SSLv3 sowie die veralteten Cipher Suites komplett aus und lenken Anfragen auf HTTP ohne Umschweife auf HTTPS um.

Einbinden in nginx

Für nginx muss das Intermediate Certificate an das eigentliche Server-Zertifikat drangeklebt werden – einen Parameter wie SSLCertificateChainFile unter apache2 gibt es hier nicht.

$ cd /etc/nginx/ssl
$ cat sub.class1.server.ca.pem >> DEINEDOMAIN.crt
## file: "/etc/nginx/sites-available/DEINEDOMAIN"
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
 
server {
  listen 80;
  server_name www.DEINEDOMAIN.tld;
  rewrite ^(.*) https://www.DEINEDOMAIN.tld$1 permanent;
}
 
server {
  listen 443 ssl;
  server_name www.DEINEDOMAIN.tld;
  ssl on;
  ssl_certificate /etc/nginx/ssl/DEINEDOMAIN.crt;
  ssl_certificate_key /etc/nginx/ssl/DEINEDOMAIN.key;
  ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
  ssl_ciphers "HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128";
  ssl_prefer_server_ciphers on;
  ...

Einbinden in apache2

## file: "/etc/apache2/sites-available/DEINEDOMAIN.conf"
<VirtualHost x.x.x.x:443>
  ServerName DEINEDOMAIN.tld
  ServerAdmin webmaster@DEINEDOMAIN.tld
  CustomLog /var/log/apache2/DEINEDOMAIN.log combined
 
  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl/DEINEDOMAIN.key
  SSLCertificateKeyFile /etc/apache2/ssl/DEINEDOMAIN.crt
  SSLCertificateChainFile /etc/apache2/ssl/sub.class1.server.ca.pem
 
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  </IfModule>
 
  ...
## file: "/etc/apache2/mods-available/ssl.conf"
<IfModule mod_ssl.c>
  SSLRandomSeed startup builtin
  SSLRandomSeed startup file:/dev/urandom 512
  SSLRandomSeed connect builtin
  SSLRandomSeed connect file:/dev/urandom 512
  AddType application/x-x509-ca-cert .crt
  AddType application/x-pkcs7-crl .crl
  SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
  SSLSessionCache         shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
  SSLSessionCacheTimeout  300
  SSLHonorCipherOrder on
  SSLCipherSuite "HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128";
  SSLProtocol all -SSLv2 -SSLv3
</IfModule>

Testen via SSL Labs

Sobald du dein Zertifikat eingebunden hast und der Webserver nach einem Restart fehlerfrei läuft (Logfiles beachten!), solltest du das Setup gegentesten – beispielsweise über den Service der SSL Labs. Das Rating ist vergleichbar mit dem der Energieeffizienzklasse – F ist ganz schlecht, A ist ziemlich gut und A+ noch besser.

Einen Protocol Support von 100% könntest du beispielsweise erreichen, indem du als einziges Protokoll TLSv1.2 zulässt; das ist technisch machbar, schließt aber viele (für meine Begriffe zu viele) ältere Clients aus, die deine Webseite dann überhaupt nicht aufrufen können – die Wahl der Ciphers ist ein Trade-Off zwischen Sicherheit und Nutzbarkeit des Systems. Und dass ich lediglich 90% Key Exchange habe begründet sich darauf, dass ich beim Erstellen meines Zertifikats gepennt und eine Schlüssellänge von 2048 Bit (statt 4096) angegeben habe. Grrr. Aber das bestehende Zertifikat einfach so widerrufen und ein neues anfordern ist nicht: das kostet bei StartSSL um die $25. Aber nunja – ich kann damit leben. Schrittweise kannst du anhand des Outputs nun Verbesserungen einführen – beispielsweise, indem du an folgenden Punkten ansetzt:

  • Verwendung eigener Diffie-Hellmann-Parameter: sie werden per openssl dhparam -out dhparams.pem 4096 erstellt und anschließend per ssl_dhparam in die Konfiguration des nginx eingebunden; bei Verwendung von apache2 hilft lediglich ein Upgrade auf eine Version > 2.4.7, dann wird automatisch ein hinreichend starker Key verwendet
  • OCSP (Online Certificate Status Protocol, RFC 6960)
  • HSTS (HTTP Strict Transport Security, RFC 6797)
Alle Bilder dieser Seite: © Marianne Spiller – Alle Rechte vorbehalten
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten

Eure Gedanken zu „SSL via StartSSL“

Ich freue mich über jeden Kommentar, es sei denn, er ist blöd. Deshalb behalte ich mir auch vor, die richtig blöden kurzerhand wieder zu löschen. Die Kommentarfunktion ist über GitHub realisiert, weshalb ihr euch zunächst dort einloggen und „utterances“ bestätigen müsst. Die Kommentare selbst werden im Issue-Tracker und mit dem Label „✨💬✨ comment“ erfasst – jeder Blogartikel ist ein eigenes Issue. Über GitHub könnt ihr eure Kommentare somit jederzeit bearbeiten oder löschen.