SSL Labs Test: Bewertung 100% A+

Eine Anleitung für starke Verschlüsselung für Webserver, um beim Qualys SSL Labs Webserver Test die höchstmögliche Bewertung von 100% A+ zu erhalten. Ob die Bestnote wirklich für jede Website möglich ist hängt von den benötigten Anwendungen ab. Manchmal gibt es Situationen wo ältere Software unbedingt erforderlich ist, sodaß deswegen Abstriche gemacht werden müssen.

Jedenfalls gilt: je besser die Bewertung, desto sicherer die Website. Dies gilt besonders für Websites wo Benutzer sensible Daten an den Webserver senden, wie z. B. Finanztransaktionen.

Im Großen und Ganzen wird die Bestnote erzielt durch eine starke Cipher Suite, 4096 bit Schlüssel, Forward Secrecy, AEAD, HSTS und mehr. Wie das genau konfiguriert wird ist auf dieser Seite zu sehen.

Ziel ist

  • Certificate 100%
  • Protocol Support 100%
  • Key Exchange 100%
  • Cipher Strength 100%

Natürlich muß auch die verwendete Software (Apache 2.4.18, OpenSSL 1.0.2g) auf dem letzten Stand sein, um Sicherheitslücken wie Heartbeat, Heartbleed, Ticketbleed etc. ausschließen zu können.

All die genannten Faktoren und mehr fließen bei der Bewertung von SSL Labs ein. Genaueres über die Bewertung ist im SSL Labs Blog nachzulesen.

Die hier gelisteten Apache Code Snippets können sich in verschiedenen Dateien befinden, je nach Konfiguration des Webservers:

  • /etc/apache2/conf-available/ssl-params.conf
  • /etc/apache2/sites-available/domain.xx.conf
  • /var/www/domain.xx/web/.htaccess
  • /var/www/domain.xx/ssl/

Achtung: Die hier angeführten Maßnahmen sollten nur von erfahrenen Systemadministratoren vorgenommen werden, da sonst unter Umständen die Website für eine lange Zeit nicht mehr erreichbar ist (siehe HSTS)!

SSL-Zertifikat

Voraussetzung ist ein korrekt installiertes SSL-Zertifikat. Am besten ein kostenloses von Let’s Encrypt installieren.

  • Der Domainname im Zertifikat muß mit dem des Webservers übereinstimmen.
  • Die Certificate Chain muß gültig sein.
    Siehe SSL Certificate Chain Checker & Generator: whatsmychaincert.com.
  • Das Zertifikat darf nicht abgelaufen sein.
  • Muß von einer vertrauenswürdigen CA (Certificate Authority) stammen.
  • Darf nicht selbst signiert sein.
  • Soll 4096 bit haben.
    Es gibt also 24096 = 1,044 × 101233 verschiedene Möglichkeiten für einen 4096-Bit Schlüssel.

Apache-Beispielkonfiguration

SSLEngine on
SSLCertificateKeyFile /var/www/domain.xx/ssl/domain.xx.key
SSLCertificateFile /var/www/domain.xx/ssl/domain.xx.crt
SSLCertificateChainFile /var/www/domain.xx/ssl/domain.xx.chain.crt

Beispiel für falsch konfiguriertes SSL-Zertifikat

Hier stimmt die Domain im Zertifikat nicht mit der des Webservers überein. Meistens ein Konfigurationsfehler.

Falsch konfiguriertes SSL-Zertifikat

Weiterleitung http → https

Für ein besseres Ranking bei Google sollte eine automatische 301-Weiterleitung zur verschlüsselten Website erfolgen. Zuerst von http://domain.xx zu http://www.domain.xx und erst danach zu https://www.domain.xx und nicht von http://domain.xx direkt zu https://www.domain.xx.

Apache-Konfiguration

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.xx$ [NC]
RewriteRule ^(.*)$ http://www.domain.xx$1 [R=301,NE,L]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

domain.xx ist durch die richtige Domain zu ersetzen.

SNI-Support (Server Name Indication)

Soll der verschlüsselte Webserver auch mit älteren Browsern bzw. User Agents (z. B. Windows XP) umgehen können, braucht er am besten eine dezidierte IP-Adresse. Oder ein Zertifikat, daß für alle virtuellen Hosts auf dieser IP-Adresse gültig ist (“Wildcard Certificate”) – ein Ding der Unmöglichkeit bei einem Shared-Hoster. Es würde nur funktionieren bei Subdomains, beispielsweise cloud.domain.xx, mail.domain.xx, www.domain.xx.

Teilen sich mehrere Domains eine einzige IP-Adresse (“Name Based Virtual Hosts”), wird SSL zwar funktionieren, aber nur mit SNI-fähigen Browsern. Da heutzutage alle modernen Browser SNI unterstützen, wird das bei der Bewertung Qualys SSL Labs zwar nicht einbezogen, aber durch die Warnmeldung “This site works only in browsers with SNI support” angezeigt.

This site works only in browsers with SNI support

Kann auch durch Konfigurationsfehler entstehen oder durch das CDN, ersichtlich bei Certificate #2. (CDN = Content Delivery Network, siehe cdncomparison.com für einen Vergleich von CDNs).

Korrekt ausgestellt

Korrekt ausgestelltes SNI Zertifikat

Fehlerhaft

Fehlerhaftes SNI Zertifikat

SNI Server Test

openssl s_client -servername www.domain.xx -tlsextdebug -connect 0.0.0.0:443 2>/dev/null

0.0.0.0 ist durch die tatsächliche IP-Adresse des Webservers zu ersetzen.

Enthält die Ausgabe eine Zeile wie

TLS server extension "server name" (id=0), len=0

dann wird die SNI-Erweiterung vom Server unterstützt.

Reverse IP Lookup

Zeigt an, welche Domains auf ein und der selben IP-Adresse gehostet sind

Apache-Konfiguration

SSLEngine on
SSLStrictSNIVHostCheck on

Ist die Direktive auf on, dürfen nicht-SNI-Clients nicht auf den virtuellen Host zugreifen.

SSL Compression

Wird von CRIME-Attack ausgenützt, also die Kompression für SSL ausschalten

Apache-Konfiguration

SSLEngine on
SSLCompression off

Protokolle

Zur Zeit gibt es SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2 und TLSv1.3.

Stand der Technik ist TLSv1.2, also alle anderen Protokolle abschalten, da veraltet und manche mit Sicherheitslücken. TLSv1.3 ist noch experimentiell, wird aber in absehbarer Zeit zum Standard werden.

Apache-Konfiguration

SSLEngine on
SSLProtocol TLSv1.2

SSL Protokolle

Ein Fressen für Hacker

SSLv3 unsicher

SSLv3 ist unsicher – Poodle-Attack!

NMAP Test

nmap --script ssl-enum-ciphers -p 443 192.168.169.170 | grep TLSv
| TLSv1.2:

Schlüsselaustausch (Handshake)

Bevor Client und Server verschlüsselt kommunizieren können, müssen zuerst die Schlüssel ausgetauscht werden. Genau das ist die Schwachstelle: wenn der Schlüsselaustausch unverschlüsselt erfolgt und jemand unbefugter schneidet die Kommunikation mit, ist die nachfolgende Verschlüsselung sinnlos. So in etwa wenn man den Haustorschlüssel außen im Schloß stecken läßt.

Deswegen muß der Schlüsselaustausch chiffriert stattfinden, mit dem Diffie-Hellmann Algorithmus auf Basis elliptischer Kurven mit mindestens 384 bit. Diffie-Hellmann, kurz DH, ist ein Protokoll zur Schlüsselvereinbarung. Es ermöglicht den sicheren Schlüsselaustausch über eine unverschlüsselte (abhörbare) Leitung. Das DH-Verfahren existiert seit dem Jahr 1976.

Schlüssel mit 1024 bit oder weniger sind heutzutage leicht zu knacken, daher einen DH-Key mit mindestens 2048 oder besser 4096 bit (für 100% A+ Bewertung) Schlüssel generieren. Ein Schlüssel unter 2048 bit wird mit “This server supports weak Diffie-Hellman (DH) key exchange parameters. Grade capped to B.” bewertet. Siehe weakdh.org (Weak Diffie-Hellman and the Logjam Attack).

Weak Diffie-Hellmann Key Exchange Parameters

4096 bit Diffie-Hellman Schlüssel erzeugen

openssl dhparam -out /etc/ssl/certs/dhparams4096.pem 4096

Dauert ein paar Minuten!

Apache-Konfiguration

SSLEngine on
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparams4096.pem"
SSLOpenSSLConfCmd ECDHParameters secp384r1
SSLOpenSSLConfCmd Curves secp521r1:secp384r1
Handshake Simulation
R = Referenzbrowser, mit dem eine bessere effektive Sicherheit erwartet wird | ECDH = Elliptic Curve Diffie-Hellman | FS = Forward Secrecy

Cipher Suite

SSL Labs degradiert die Bewertung zur Note “B”, wenn Forward Secrecy und AEAD nicht unterstützt wird.

Forward Secrecy

Auch “Perfect Forward Secrecy”, PFS. Bezeichnet in der Kryptographie ein Protokoll, welches für jede Sitzung einen eigenen, geheimen Sitzungsschlüssel vereinbart. Dadurch wird vermieden, daß eine aufgezeichnete Sitzung mit dem (geheimen) privaten Schlüssel (der “long-term Key”) nachträglich entschlüsselt werden kann. Daher spricht man auch von “Folgenlosigkeit”, da ein späteres Entschlüsseln der Sitzung(en) mit dem privaten Schlüssel ohne Folgen für die Sicherheit der früheren Sitzung(en) bleibt.

Der weit verbreitete RSA-Schlüsselaustausch bietet keine Forward Secrecy, weshalb man Cipher Suites mit ECDH bevorzugen sollte.

AEAD

AEAD (Authenticated Encryption with Associated Data) ist zur Zeit der einzige Verschlüsselungsansatz ohne bekannte Schwächen. AEAD-Suites bieten starke Authentifizierung, Schlüsselaustausch, Forward Secrecy und Verschlüsselung von mindestens 128 Bit. TLS 1.3 unterstützt ausschließlich AEAD-Suites.

Apache-Konfiguration

Alle Cipher Suites unter 256 bit entfernen, für Handshake nur Ephemeral Keys (“flüchtig”) verwenden (DH und ECDH) da sonst kein Forward Secrecy möglich. Schwache und unsichere Cipher Suites entfernen.

SSLSessionTickets

Die Direktive SSLSessionTickets ist in der Apache-Konfiguration standardmäßig aktiviert. D. h., die Verwendung ohne Neustart des Webservers mit einer angemessenen Häufigkeit (z.B. täglich) gefährdet die Forward Secrecy, also sicherheitshalber die Direktive ausschalten.

SSLEngine on
SSLSessionTickets Off
SSLHonorCipherOrder on
SSLCipherSuite "HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128:!AES256-SHA:!AES256-SHA256:!AES256-GCM-SHA384:!AES256-CCM8:!AES256-CCM"
Cipher Suites

Zwischenergebnis

Ohne Security Header wird das SSL-Zertifikat mit Hilfe obiger Maßnahmen mit Note 100% A bewertet.100% A

Securitiy Header

Die Bestnote von 100% A+ wird erst durch die HSTS-Header (HTTP Strict Transport Security) erzielt.

Apache-Konfiguration

Falls noch nicht geschehen, zuerst mod_headers einschalten

a2enmod headers
service apache2 restart

Jetzt kann der Header gesetzt werden

Header set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS

HSTS ist nicht der einzige HTTP Header, der die Sicherheit und Privatsphäre der Website verbessert. Da diese aber tatsächlich nichts mit dem SSL-Zertifikat zu tun haben, werden diese in gesonderten Artikeln behandelt, nämlich unter Security Header und Privacy Header.

WordPress

Für WordPress gibt es das Plugin HTTP Headers. Damit werden die HTTP Header verwaltet und in der .htaccess eingetragen.

Zusammenfassung für Apache

a2enmod headers
<IfModule mod_ssl.c>
  SSLEngine on
  SSLStrictSNIVHostCheck on
  SSLCompression off
  SSLProtocol TLSv1.2
  SSLSessionTickets Off
  SSLCipherSuite "HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128:!AES256-SHA:!AES256-SHA256:!AES256-GCM-SHA384:!AES256-CCM8:!AES256-CCM"
  SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparams.pem
  SSLOpenSSLConfCmd ECDHParameters secp384r1
  SSLOpenSSLConfCmd Curves secp521r1:secp384r1
  SSLHonorCipherOrder on
  SSLCertificateFile /var/www/clients/client1/web1/ssl/domain.xx-le.crt
  SSLCertificateKeyFile /var/www/clients/client1/web1/ssl/domain.xx-le.key
  SSLCertificateChainFile /var/www/clients/client1/web1/ssl/domain.xx-le.bundle
  SSLUseStapling on
  SSLStaplingResponderTimeout 5
  SSLStaplingReturnResponderErrors off
  <IfModule mod_headers.c>
    Header always add Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
  </IfModule>
</IfModule>
service apache2 restart

Siehe auch