- Mitglied seit
- 01. Sep 2012
- Beiträge
- 17.485
- Punkte für Reaktionen
- 8
- Punkte
- 414
Moin moin,
viele nutzen ja (hoffentlich) inzwischen einen verschlüsselten Zugriff auf den Webserver der DS. Seit Snowdens Enthüllungen laufen seit einigen Monaten erste Ergebnisse auf, die einer weiteren Erhöhung der Sicherheit von TLS dienen. DANE gehört dazu, ist aber noch nicht weit verbreitet bei den Hostern, und ebenso Certificate Pinning, dessen Unterstützung auf der Client-Seite inzwischen recht gut ist und wohl sehr schnell erweitert wird, so dass Sinn macht, sich damit einmal zu beschäftigen. Letzteres ist auch insofern interessant, weil man es im Gegensatz zu DANE als Server-Betreiber in seiner eigenen Hand hat.
Certificate Pinning, beschrieben in der RFC 7469, basiert im Rahmen eines TOFU-Ansatzes (Trust On First Use) darauf, dass der Webserver beim ersten Aufruf als weitere Headerinformationen einen oder mehrere Pins liefert, die der Client-Browser für den weiteren Zugriff befolgen wird - auf diese Weise lassen sich also Man-in-the-Middle-Attacken aushebeln. Bei einem solchen Pin handelt es sich um einen Base64-kodierten Hash-Wert (SHA-256) zu einem Zertifikat der Zertifikatskette - entweder direkt für das Server-Zertifikat oder aber eines der Zertifikate bis hin zum CA-Rootzertifikat. Die Header-Informationen sehen in ihrem Aufbau aus wie bspw.
In den "" eingeschlossen findet sich ein entsprechender Pin zum gepinnten Zertifikat. Hinzu kommt, analog wie bei der Strict-Transport-Security-Definition HSTS, eine Angabe in Sekunden, für die der Client diese Zertifikatseinschränkung befolgt, sowie bei Bedarf ein Hinweis, auch Subdomains zu erfassen.
Auf diese Weise sind Man-in-the-Middle-Attacken nach dem ersten Zugriff ausgeschlossen (sofern man innerhalb der Zeitangabe max-age wiederholt zugreift), weil ein zwischengeschalteter SSL-Proxy ein anderes Zertifikat an den Client liefern würde - selbst wenn dieses andere Zertifikat gültig ist, würde der Browser (wenn er Certificate Pinning auswertet) einen Fehler auswerfen und den Zugriff nicht zulassen. Bei den Desktop-Browsern wird Certificate Pinning bisher von Chrome und Firefox unterstützt, dagegen werten IE11, Edge und Apple Safari das bisher nicht aus (ein Zugriff mit diesen Browser ist aber natürlich dennoch möglich, sie ignorieren die Information, könnten so aber auf eine MitM-Attacke hereinfallen). Bei den Mobil-Browsern werten bisher ebenfalls Firefox (Android) sowie Chrome (Android, iOS) gepinnte Zertifikate aus.
Was muss man also tun?
Das Ganze ist recht einfach umzusetzen. Zunächst muss man sich entscheiden, welches Zertifikat man pinnen möchte. Das höchste Maß an Sicherheit erreicht man, wenn man das Server-Zertifikat selbst pinnt - denn eben jenes hat man ja unter voller Kontrolle. Dabei gilt es aber zu beachten, dass ein Browser, der einmal per https zugreift, dabei für die festgelegte Zeit fest auf dieses Zertifikat festgelegt wird. Crasht bspw. der Server und setzt man ihn mit einem neuen Zertifikat auf (weil man zB. nicht an genau dieses bisherige gepinnte Zertifikat über ein Backup herankommt), bleiben die Browser, die zuvor über einen https-Zugriff gepinnt sind, während der festgesetzten Zeit max-age nach dem letzten Zugriff für den https-Zugriff außen vor.
Alternativ kann man natürlich auch ein Intermediate- oder CA-Root-Zertifikat pinnen - was einen Zertifikatswechsel zwar leichter macht, wenn man wieder die gleiche CA nutzt, aber damit auch die Sicherheit wieder etwas reduziert... denn verschafft sich ein Angreifer ebenfalls ein Zertifikat, welches aus dieser CA stammt, bemerkt man den MitM-Angriff wieder nicht. Zumal wird gerade ein Intermediate/Signierzertifikat gelegentlich getauscht, was einem dann ebefalls in die Suppe spuckt.
Erwähnenswert ist es in diesem Zusammenhang, dass die RFC 7469 vorsieht, mehrere Pins auszuliefern, die dann alle geprüft werden, wobei mindestens ein Pin korrekt sein muss - was man natürlich nutzen kann, neben dem Server-Zertifikat auch weitere Teile der Zertifikatskette zu pinnen. Genaugenommen verlangt die RFC allerdings auch, dass mindestens ein Pin nicht Teil der aktuellen Zertifikatskette sein darf (wobei bisher kein Browser diesen Zwang prüft) - dieses ist sozusagen eine Backupmöglichkeit. Man kann nämlich auf diese Weise den Pin eines Reserve-Zertifikats hinterlegen oder - was aus Kostensicht erfreulich ist - den Pin eines entsprechenden CSR (d.h. man kann sich für den Notfall, ohne bereits ein Reserve-Zertifikat bezahlen zu müssen, einen CSR erzeugen und dafür den entsprechenden Pin ermitteln).
Hat man sich entschieden, was genau man pinnen möchte, ermittelt man dazu die entsprechenden Pins. Das kann man bspw. mit OpenSSL tun:
Dabei ist cert.pem das Serverzertifikat im PEM-Format (auf der DS zu finden unter /usr/syno/etc/ssl/ssl.crt/server.crt ). Die Ausgabe ist dann etwas wie bspw. dJlH...hsnY= (endet aber immer mit einem "=") und stellt den Pin dar. Will man den Pin für einen CSR erzeugen, ersetzt man einfach das x509 durch req .
Alternativ erledigt dieses auch eine kleine JavaScript-Routine unter https://projects.dm.id.lv/s/pkp-online/calculator.html . Dort läßt sich auch gleich die Gültigkeitsdauer in Stufen auswählen und der fertige HTTP Header ausgeben.
Diesen HTTP Header muss man dann in den entsprechenden Webserver verankern (Details). Bei dem Apachen der DS, der standardmäßig das notwendige Modul mod_headers.so lädt, erfolgt das in der ssl-Sektion der Konfig (denn nur für https ist die Festlegung RFC-konform), d.h. um bspw. den User-Apache abzusichern, ergänzt man in der Datei /etc/httpd/conf/extra/httpd-ssl.conf-user ein
Wichtig ist dabei, die Anführungszeichen, in denen die Pins (hier als ... dargestellt) eingeschlossen sind, mit einem \ zu escapen. Hier sind im Beispiel zwei Pins aufgeführt, die Gültigkeit ist dabei 7 Tage.
Danach ist der Webserver bzw. am besten gleich die DS neuzustarten.
Kleiner Tipp: man sollte vorsichtig anfangen beim Testen und zunächst kleine max-age von vielleicht eine Stunde wählen - ist man sich dann sicherer, kann man das erhöhen auf Wochen bzw. Monate.
Diese Informationen kann der interessierte Benutzer ausführlicher in der aktuellen c't 23/2015 auf den Seiten 118-125 nachlesen.
viele nutzen ja (hoffentlich) inzwischen einen verschlüsselten Zugriff auf den Webserver der DS. Seit Snowdens Enthüllungen laufen seit einigen Monaten erste Ergebnisse auf, die einer weiteren Erhöhung der Sicherheit von TLS dienen. DANE gehört dazu, ist aber noch nicht weit verbreitet bei den Hostern, und ebenso Certificate Pinning, dessen Unterstützung auf der Client-Seite inzwischen recht gut ist und wohl sehr schnell erweitert wird, so dass Sinn macht, sich damit einmal zu beschäftigen. Letzteres ist auch insofern interessant, weil man es im Gegensatz zu DANE als Server-Betreiber in seiner eigenen Hand hat.
Certificate Pinning, beschrieben in der RFC 7469, basiert im Rahmen eines TOFU-Ansatzes (Trust On First Use) darauf, dass der Webserver beim ersten Aufruf als weitere Headerinformationen einen oder mehrere Pins liefert, die der Client-Browser für den weiteren Zugriff befolgen wird - auf diese Weise lassen sich also Man-in-the-Middle-Attacken aushebeln. Bei einem solchen Pin handelt es sich um einen Base64-kodierten Hash-Wert (SHA-256) zu einem Zertifikat der Zertifikatskette - entweder direkt für das Server-Zertifikat oder aber eines der Zertifikate bis hin zum CA-Rootzertifikat. Die Header-Informationen sehen in ihrem Aufbau aus wie bspw.
Code:
Public-Key-Pins: pin-sha256="..."; max-age=604800; includeSubDomains
Auf diese Weise sind Man-in-the-Middle-Attacken nach dem ersten Zugriff ausgeschlossen (sofern man innerhalb der Zeitangabe max-age wiederholt zugreift), weil ein zwischengeschalteter SSL-Proxy ein anderes Zertifikat an den Client liefern würde - selbst wenn dieses andere Zertifikat gültig ist, würde der Browser (wenn er Certificate Pinning auswertet) einen Fehler auswerfen und den Zugriff nicht zulassen. Bei den Desktop-Browsern wird Certificate Pinning bisher von Chrome und Firefox unterstützt, dagegen werten IE11, Edge und Apple Safari das bisher nicht aus (ein Zugriff mit diesen Browser ist aber natürlich dennoch möglich, sie ignorieren die Information, könnten so aber auf eine MitM-Attacke hereinfallen). Bei den Mobil-Browsern werten bisher ebenfalls Firefox (Android) sowie Chrome (Android, iOS) gepinnte Zertifikate aus.
Was muss man also tun?
Das Ganze ist recht einfach umzusetzen. Zunächst muss man sich entscheiden, welches Zertifikat man pinnen möchte. Das höchste Maß an Sicherheit erreicht man, wenn man das Server-Zertifikat selbst pinnt - denn eben jenes hat man ja unter voller Kontrolle. Dabei gilt es aber zu beachten, dass ein Browser, der einmal per https zugreift, dabei für die festgelegte Zeit fest auf dieses Zertifikat festgelegt wird. Crasht bspw. der Server und setzt man ihn mit einem neuen Zertifikat auf (weil man zB. nicht an genau dieses bisherige gepinnte Zertifikat über ein Backup herankommt), bleiben die Browser, die zuvor über einen https-Zugriff gepinnt sind, während der festgesetzten Zeit max-age nach dem letzten Zugriff für den https-Zugriff außen vor.
Alternativ kann man natürlich auch ein Intermediate- oder CA-Root-Zertifikat pinnen - was einen Zertifikatswechsel zwar leichter macht, wenn man wieder die gleiche CA nutzt, aber damit auch die Sicherheit wieder etwas reduziert... denn verschafft sich ein Angreifer ebenfalls ein Zertifikat, welches aus dieser CA stammt, bemerkt man den MitM-Angriff wieder nicht. Zumal wird gerade ein Intermediate/Signierzertifikat gelegentlich getauscht, was einem dann ebefalls in die Suppe spuckt.
Erwähnenswert ist es in diesem Zusammenhang, dass die RFC 7469 vorsieht, mehrere Pins auszuliefern, die dann alle geprüft werden, wobei mindestens ein Pin korrekt sein muss - was man natürlich nutzen kann, neben dem Server-Zertifikat auch weitere Teile der Zertifikatskette zu pinnen. Genaugenommen verlangt die RFC allerdings auch, dass mindestens ein Pin nicht Teil der aktuellen Zertifikatskette sein darf (wobei bisher kein Browser diesen Zwang prüft) - dieses ist sozusagen eine Backupmöglichkeit. Man kann nämlich auf diese Weise den Pin eines Reserve-Zertifikats hinterlegen oder - was aus Kostensicht erfreulich ist - den Pin eines entsprechenden CSR (d.h. man kann sich für den Notfall, ohne bereits ein Reserve-Zertifikat bezahlen zu müssen, einen CSR erzeugen und dafür den entsprechenden Pin ermitteln).
Hat man sich entschieden, was genau man pinnen möchte, ermittelt man dazu die entsprechenden Pins. Das kann man bspw. mit OpenSSL tun:
Code:
openssl x509 -in cert.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Alternativ erledigt dieses auch eine kleine JavaScript-Routine unter https://projects.dm.id.lv/s/pkp-online/calculator.html . Dort läßt sich auch gleich die Gültigkeitsdauer in Stufen auswählen und der fertige HTTP Header ausgeben.
Diesen HTTP Header muss man dann in den entsprechenden Webserver verankern (Details). Bei dem Apachen der DS, der standardmäßig das notwendige Modul mod_headers.so lädt, erfolgt das in der ssl-Sektion der Konfig (denn nur für https ist die Festlegung RFC-konform), d.h. um bspw. den User-Apache abzusichern, ergänzt man in der Datei /etc/httpd/conf/extra/httpd-ssl.conf-user ein
Code:
<VirtualHost *:443>
ServerName *
ServerAlias *
SSLEngine on
...
[COLOR=#b22222] Header always set Public-Key-Pins "pin-sha256=\"...\"; pin-sha256=\"...\"; max-age=604800; includeSubDomains"[/COLOR]
...
</VirtualHost>
Danach ist der Webserver bzw. am besten gleich die DS neuzustarten.
Kleiner Tipp: man sollte vorsichtig anfangen beim Testen und zunächst kleine max-age von vielleicht eine Stunde wählen - ist man sich dann sicherer, kann man das erhöhen auf Wochen bzw. Monate.
Diese Informationen kann der interessierte Benutzer ausführlicher in der aktuellen c't 23/2015 auf den Seiten 118-125 nachlesen.
Zuletzt bearbeitet: