Goodbye #letsencrypt? At least for now.
"We have been made aware of a potential incident and are shutting down all issuance."
Goodbye #letsencrypt? At least for now.
"We have been made aware of a potential incident and are shutting down all issuance."
(264.6 MB) 00:38:36
2018-07-01 10:00 🛈In den letzten Jahren hat sich im Bereich der herstellerübergreifenden Hausautomation MQTT als Protokoll verbreitet. Schauen wir mal wie das Protokoll funktioniert, wie wir selbst einen Server aufsetzen und diesen absichern und letztentlich wie wir mit ESP8266 und HomeAssistant einen eigenen Sensor implementieren können.
Demo-Quellcode:
https://gist.github.com/adlerweb/807aee4a79a8dee043113d86172e7792
BitBastelei #290 – MQTT (Protokoll, Mosquitto, ESP8266, HomeAssistant, TLS) weiterlesen
(26.1 MB) 00:07:18
2015-09-20 10:00 🛈Part 1: Warum verschlüsseln, Symmetrisch vs. Asymmetrisch
Part 2: RSA, PFS, DHE, ECDHE und sonstige Innereien
HTTPS dürften die meisten kennen, TLS (früher SSL genannt) vielleicht auch, wie sieht es mit RSA, DHE oder ECDHE aus? Alle Begriffe sind Techniken um Zugriffe auf Webseiten zu gegen unberechtigtes Mitlesen abzusichern.
Warnung wie immer: Alles nur als Überblick – die Erklärungen sind stark vereinfacht, teilweise unvollständig und können Fehler enthalten.
Ich hab doch nichts zu verbergen!
So heißt es vielfach, wenn man über Verschlüsselung diskutiert. Aber ist das wirklich so? Selbst wenn man selbst sein ganzes Leben zugänglich macht, so gibt es dennoch Gründe nicht alle Daten unverschlüsselt zu übermitteln. Klassisches Beispiel: Zugangsdaten. Werden diese ungeschützt übertragen können sie von Dritten abgefangen werden. Unerwünschte Posts können schnell mit Stress im Freundeskreis oder gar vor Gericht enden. Und das Konto wäre vermutlich ebenso schnell leer. Hätte man die Daten besser mal verborgen.
Bild: https://www.adlerweb.info/blog/wp-content/uploads/2015/09/3-mettbook-userpass-300×227.png
Fangen wir mit dem einfachsten an: Symmetrische Kryptografie. Hierunter versteht man Verfahren, bei denen z.T. ein Text mit einem Passwort verschlüsselt wird. Das Ergebnis ist für Außenstehende nicht zu entziffern und somit wertlos. Wer jedoch den Schlüssel kennt kann aus dem Kauderwelsch wieder den ursprünglichen Text reproduzieren.
Bild: https://www.adlerweb.info/blog/wp-content/uploads/2015/09/sym7-300×169.png
Solche Verfahren sind natürlich schön für Dokumente, jedoch Problematisch für Webseiten: Entweder müssten alle Besucher das selbe Kennwort kennen – könnten also auch die Daten der anderen entschlüsseln – oder man müsste für jeden Besucher ein eigenes Passwort aushandeln. Nur wie, wenn der Besucher zum ersten mal die Seite aufruft? Etwas anderes muss her.
Klassischerweise wird zum Schlüsseltausch im Internet ein asymmetrisches Verfahren verwendet. Hierbei hat der Betreiber der Webseite einen „Schlüssel“ erstellt, welcher aus zwei Teilen besteht: Einem privaten Teil, welcher geheim gehalten wird, und einem öffentlichen Teil, welcher allen Besuchern weitergegeben wird. Dahinter steckt eine Einwegfunktion – sozusagen eine mathematische Einbahnstraße. Mit dem öffentlichen Teil lässt sich ein Text einfach verschlüsseln, jedoch das Ergebnis nach aktuellem Stand nicht mehr Zurückrechnen. Hat man jedoch den privaten Teil, so hat man auch die fehlenden Informationen um aus dem zuvor berechneten Wirrwarr wieder den ursprünglichen Text zu erhalten. Der Client kann also dem Server verschlüsselte Nachrichten zukommen lassen, ohne die Gefahr des Mitlesens.
Ebenfalls möglich ist eine andere Richtung: Mit dem privaten Schlüssel kann der Server eine Nachricht unterschreiben, also bestätigen, dass diese von ihm so gewollt ist. Der Client kann mit dem öffentlichen Teil am Ende prüfen, ob die Unterschrift tatsächlich vom Absender stammt und der Text unterwegs nicht verändert wurde.
Bild: https://www.adlerweb.info/blog/wp-content/uploads/2015/09/asym12-300×169.png
Wem ist etwas aufgefallen? Wir benötigen öffentliche Schlüssel für alle verschlüsselten Webseiten. Doch wo kommen sie her? Nun – das ist schnell gelöst: Der Server schickt uns diese beim Verbinden. Klingt praktisch, hat aber einen Nachteil: Wir können nicht sicher sein, dass das Ziel tatsächlich unser Server und nicht ein Angreifer zwischendrin ist. Der Lösungsansatz lautet X.509, oder kurz: Zertifikate. Diese Zertifikate enthalten nicht nur den Schlüssel, sondern auch weitere Informationen wie den Servernamen, die zugehörige Organisation, ein Haltbarkeitsdatum und einen Fingerabdruck. Zusätzlich sind diese Zertifikate zum Nachweis der Identität des Betreibers von einer weiteren Firma, der so genannten Certificate Authority (CA) unterschrieben. Alle aktuellen Browser und Betriebssysteme haben eine Liste mit Firmen, welche solche Unterschriften leisten dürfen, im Lieferumfang. Ist das Zertifikat von einer dieser Firmen unterschrieben, so vertraut der Browser diesem ohne weitere Nachfrage. Ist die Unterschrift unbekannt erhält man eine passende Warnung. In diesem Fall kann man natürlich trotzdem z.B. den erhaltenen Fingerabdruck telefonisch mit dem Betreiber abgleichen und so die Identität selbst feststellen.
Langsam aber sicher setzt sich die verschlüsselte Kommunikation per TLS auch auf Internetseiten (HTTPS) durch. Gut konfiguriert verhindert sie effektiv das Mitlesen der gesendeten Informationen und Einschleusen fremder Codestücke. Wichtig hierbei ist, dass der zugehörige Webserver richtig konfiguriert ist. Ich werde hier auf den aktuellsten Ableger des Apache HTTPd, die Version 2.4, eingehen. Alle Einstellungen werden im jeweiligen virtual Host vorgenommen und sollten teilweise bereits vorhanden sein. Bei Arch Linux befindet sich die SSL-Konfiguration unter /etc/httpd/conf/extra/httpd-ssl.conf.
Zertifikatstheorie
TLS, und damit auch HTTPS, arbeiten mit einem hierarchisch organisierten System. Viele Browser und Betriebssysteme liefern eine Liste mit vertrauenswürdigen Organisationen mit – ist das eigene Zertifikat nicht, zumindest indirekt, von einer dieser Organisationen unterschrieben, so wird eine Sicherheitswarnung angezeigt. Ob dies Sinnvoll ist kann kritisch beäugt werden, vor allem wenn man bedenkt, dass z.B. auch diverse Banken, Regierungen oder Organisationen, welche in der Vergangenheit eher durch Sicherheitsmängel aufgefallen sind, auf dieser Liste stehen. Generell erstell man selbst einen Key, den privaten Schlüssel des Zertifikates, und leitet hiervon einen Request (CSR) ab. Letzterer – und nur dieser – wird an die Zertifizierungsstelle (CA) zum Unterschreiben gegeben. Nachdem die eigene Identität nachgewiesen wurde wird aus Request und Unterschrift das eigentliche, öffentliche Zertifikat, welches das eigene, zweiteilige Schlüsselpaar komplettiert. Als Betreiber hat man hier mehrere Möglichkeiten ein solches SSL-Zertifikat zu erhalten:
Wir basteln einen Request
Welchen weg auch immer man geht: Wir brauchen einen Key und den passenden Request. Fangen wir mit ersterem an:
cd /etc/ssl/private openssl genrsa -out server.key 4096
Der Schlüssel nutzt den RSA-Algorithmus mit einer Länge von 4096 Bit. Empfohlen wird >=2048 Bit, wer aber nicht unbedingt auf die letzten CPU-Takte Performance schaut sollte diese zugunsten der vermutlich längeren Zukunftssicherheit investieren.
Auf Basis dieses Schlüssels wird nun der Request erstellt:
openssl req -new -key server.key -out server.csr -sha512
Die Attribute wie Adresse sollten passend den eigenen Angaben ausgefüllt werden. Wichtigster Punkt: Der „Common Name“ (CN) muss dem Servernamen entsprechen.
Diesen Request übersendet man nun der Zertifizierungsstelle, die Antwort wird als „server.crt“ im selben Verzeichnis gespeichert. Sollte man ein so genanntes „intermediate“ benötigen (Das eigene Zertifikat wurde von jemandem unterschrieben welcher selbst nicht vertrauenswürdig ist aber eine Unterschrift einer anderen, vertrauenswürdigen Stelle hat), so werden diese Zertifikate einfach am Ende der Textdatei drangehangen.
Apache-Konfiguration
Erster Schritt: Wir schalten „SSL“ (so hies TLS früher mal, Apache hat die Namen beibehalten) ein und geben den Pfad zum Zertifikat an.
SSLEngine on
SSLCertificateFile /etc/ssl/private/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.crt
Als Nächstes werden die möglichen Protokollversionen und Algorithmen festgelegt. Bei ersterem sollte alles mit SSL abgeschaltet werden – diese haben bekannte Sicherheitslücken. Auch zu TLSv1 gibt es einige Bedenken, jedoch noch keinen praxisrelevanten Angriff – wer auf Nummer sicher gehen will kann auch dies Abschalten, jedoch sperrt man hiermit möglicherweise ältere Geräte und Browser aus. Bei den Ciphern ist die Reigenfolge entscheidend – der erste Eintrag, welcher von Server und Client unterstützt wird, wird verwendet. Einträge mit *DHE* bieten „perfect forward secrecy“ (PFS) – hierbei wird für jede Verbindung ein temporäres Passwort abgewandelt. Liest ein Bösewicht die verschlüsselten Daten mit kann er sie später, auch wenn er den Server knackt und so an die Schlüssel kommt, nicht mehr entschlüsseln. RC4 und MD5 werden wegen ihrer hohen Geschwindigkeit zwar gerne von Großkonzernen und einigen Banken verwendet, haben aber bekannte Lücken, sodass sogar das Bundesamt für Sicherheit in der Informationstechnik (BSI) vor deren Einsatz warnt. Die SSL-Kompression hat ebenfalls eine gewisse Angriffsfläche und sollte abgeschaltet werden. Wie immer gilt: Je mehr man auf Sicherheit Wert legt, desto mehr alte Geräte sperrt man aus.
SSLProtocol all -SSLv3 -TLSv1
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
SSLHonorCipherOrder on
SSLCompression off
Bei neueren Servern kann man die Ladezeit des Besuchers noch etwas drücken: Dessen Browser geht üblicherweise hin und fragt nach der Verbindung bei der Zertifizierungsstelle, welche die Unterschrift geleistet hat, nach, ob diese überhaupt noch gültig ist. Mit OCSP-Stapeling fordert unser Server regelmäßig eine kleine, unterschriebene „Notiz“ der Zertifizierungsstelle an, in welchem die Gültigkeit mit der aktuellen Uhrzeit hinterlegt ist. Diese senden wir gleich mit – ist dem Browser diese Info aktuell genug und die Unterschrift OK muss er nicht extra nochmal nachfragen.
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
Letzter Punkt: HSTS – HTTP Strict Transport Security. Hiermit sagen wir dem Browser, dass wir für die nächste Zeit ausschließlich per HTTPS arbeiten wollen. Alle zukünfigen Zugriffe werden automatisch per HTTPS abgewickelt, auch wenn der Nutzer nicht per Hand https anfordert. Im Gegensatz zu den gängigen HTTP-Umleitungen spart es einen unverschlüsselten Request, welcher ggf. auch als Angriffspunkt dienen kann. Wenn man seine Webseite absichtlich per HTTP und HTTPS anbieten möchte sollte man den Header natürlich überspringen.
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
Header always set Strict-Transport-Security "max-age=15768000"
Der Rest
Eine gute Ressource um zwischen Sicherheit und Kompatibilität abzuwähen oder die Konfiguration für andere Webserver und Funktionen anzupassen ist der Mozilla SSL Configuration Generator, auf dessen Ausgaben auch das hiesige Beispiel basiert.
Sollen alle Anfragen über HTTPS laufen kann man den HTTP-Listener anweisen für alle Anfragen mir einer Umleitung auf die HTTPS-Seite zu antworten. Hierzu reicht folgende Zeile im zuständigen VHost:
Redirect / https://testserver.adlerweb.info/
Wer testen möchte, ob alles Funktioniert hat und welche Geräte und Browser zu alt sind um auf die Webseite zugreifen zu können, kann die SSL-Tester von SSLLabs nutzen – dieser generiert einen ausführlichen und gut verständlichen Report und gibt weitere Tipps bei möglichen Problemen.
Huh? Bei einer Neueinrichtung ließ sich Pidgin nicht dazu überzeugen eine Verbindung zu meinem XMPP(/Jabber)-Server herzustellen – SSL fehler. Ursache ist offenbar, dass das verwendete Zertifikat nicht von einer CA signiert wurde, der das System standardmäßig vertraut.
Erste Möglichkeit: Die CA bzw. das selbstsignierte Zertifikat im System importieren. Auf den meisten Systemen sind hierzu jedoch Systemverwalterrechte erforderlich, sodass diese Methode nicht immer machbar ist – also schnell weiter zu…
Zweite Möglichkeit: Per Hand. Hierzu benötigen wir ebenfalls erst mal das Zertifikat. Hat man dies nicht zu Hand kann man sich mit OpenSSL behelfen. Als Client instrutiert wird u.A. das Zertifikat in ASCII ausgegeben:
openssl s_client -host myjabber.server -port 5222 -starttls xmpp -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
Dieses Zertifikat – inklusive der BEGIN/END CERTIFICATE-Header – kopiert man in eine Textdatei und speichert sie als *.pem-Datei auf der Festplatte ab. Um dieses Zertifikat nun in Pidgin zu erlauben öffnet man Werkzeuge->Zertifikate und wählt unter hinzufügen die zuvor gespeicherte Datei aus.
Bild: https://adlerweb.info/blog/wp-content/uploads/2015/08/sslpidgin-300×120.png
Nun sollte die Verbindung korrekt funktionieren. Schade, dass hier keine einfachere Nachfrage implementiert wurde, welche beim ersten Verbinden ohne weiteren Eingriff eine Zertifikatsausnahme zulässt.
Viele Banken haben sich schon drum gekümmert, doch Nachschub ist in Sicht: Die estnische BigBank glänzt üblicherweise mit hohen Zinssätzen und einer relativ guten Reputation. Leider kann sie Serverseitig dem Ruf nicht gerecht werden: 3DES und RC4 finden sich als bevorzugte SSL-Ciphers, obwohl TLS_RSA_WITH_AES_256_CBC_SHA bereits unterstützt wird und sich mit TLS_DHE_RSA_WITH_AES_256_CBC_SHA sogar Cipher mit Forward-Secrecy finden lassen. Leider geht diese Fehlkonfiguration der Cipher Suite Priority so weit, dass es teilweise sogar zu Protokollfehlern kommt und der Loginserver nicht mit jedem Browser fehlerfrei aufgerufen werden kann.
Wie üblich wurde die Bank von mir ausführlich – und mit Verweis auf BSI & Co – über meine Bedenken Informiert und um Stellungnahme gebeten. Mein Geld bekommen sie jedenfalls erst mal nicht.
OK, Zertifikate erneuert, dann auch noch „schnell mal“ HTTPs im Blog einschalten. Oder auch nicht…
Ich habe bereits seit langem den Adminbereich meines Blogs über HTTPS eingebunden, hierzu ist lediglich ein einfaches
define('FORCE_SSL_ADMIN', true);
in der wp-config.php notwendig. Den Blog selbst hatte ich seinerzeit auf HTTP gelassen, denn nicht jeder hat die von mir verwendete Zertifizierungsstelle CACert installiert was zu unschönen Warnungen führen würde. Optional wäre toll, aber damals zeigte sich schnell, dass die SEO-Funktionen von WordPress aus dieser einfachen Sache mal wieder eine lange Geschichte machen. Anstatt Anfragen einfach zu verarbeiten wird zur Optimierung der Suchmaschinenplatzierung alles unbekannte auf die konfigurierte Hauptadresse umgeleitet – incl. dem für WordPress unbekannten https://….
Im Netz findet man häufig kleine Codefragmente, welche in der wp-config.php die interenen Adressen bei HTTPS-Zugriffen umbiegen sollen. In meinem Fall biss sich diese Methode leider mit dem verwendeten Cache-Plugins. Fündig geworden bin ich im Plugin „WP-SSL„. Über wenige Filter werden die Adressen direkt über die API ersetzt. Da so auch die Cacher entsprechende Ausgaben erhalten ist auch der parallele Einsatz kein Problem. Das Plugin ist für mich eher Vorlage als Fertiglösung gewesen – einige Zeilen für alternative URLs und Plugins musste ich ergänzen, aber generell ist die Methode praktisch und schnell zu verstehen.
Rekonfiguration erfolgreich – somit ist diese Seite jetzt auch offiziell (auf Wunsch) per HTTPS erreichbar – selbstverständlich auch mit PFS und paranoiden Schlüssellängen, auch wenn es wohl für einen einfachen Blog nicht wirklich etwas zur Sache tut ;).
Anm: Offenbar gibt es doch noch den ein oder anderen Client (IE auf WinXP, Android 2.3), welche noch kein SNI unterstützen – für die heißt es: „Sorry, aber ohne Update geht’s nur ohne“…