Wie funktioniert das Umschalten von HTTPS-Zertifikaten (wie auf suche.org)?

20

Für diejenigen, die nicht wissen, was Suche.org ist, ist es eine Website, die in jeder Kategorie ein perfektes A + Rating für SSL Labs aufweist: ( Ergebnis von Suche.org SSL Labs ). Ich wurde auf diese Website aufmerksam, als ich ein weiteres Ticket für ECC-Zertifikate öffnete , das nicht in Chrome funktioniert , und einer der Responder die Website als Beispiel verwendete.

Was mich verwirrt ist, dass obwohl der Protocol SupportAbschnitt des Berichts sagt, dass die Website nur TLSv1.2 verwendet ...

TLS 1.2 Yes
TLS 1.1 No
TLS 1.0 No
SSL 3   No
SSL 2   No

Dies ist eindeutig nicht der Fall, da in diesem Handshake SimulationAbschnitt angezeigt wird, dass einige der simulierten älteren Clients TLSv1.0 verwenden, um eine Verbindung herzustellen.

Android 4.0.4   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.1.1   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.2.2   EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.3     EC 384 (SHA256)     TLS 1.0 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   ECDH secp521r1  FS
Android 4.4.2   EC 384 (SHA256)     TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   ECDH secp521r1  FS

Das ist ein bisschen frustrierend, denn wenn ich TLSv1.0 auf meiner Test-Website wie folgt deaktiviere ...

# Apache example
SSLProtocol all -SSLv3 -SSLv2 -TLSv1

Das Ausführen des SSL Labs-Scans auf meiner Testwebsite führt bei einigen älteren Clients zu folgenden Ergebnissen:

Android 4.0.4   Server closed connection
Android 4.1.1   Server closed connection
Android 4.2.2   Server closed connection
Android 4.3     Server closed connection
Android 4.4.2   EC 384 (SHA256)     TLS 1.2 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   ECDH secp256r1  FS

Wie ist es möglich, gleichzeitig nur TLSv1.2-Verbindungen zuzulassen, aber auch ältere Clients zu unterstützen?

Scott Crooks
quelle
Sollten wir den Titel allgemeiner gestalten, so etwas wie "HTTPS cert switching logic"?
gf_
1
Gute Idee. Getan.
Scott Crooks

Antworten:

17

Ich bin mir ziemlich sicher, dass sie die Client-Funktionen überprüfen und entsprechend handeln, wie in dem in der Antwort von @Jeff verlinkten Thread erläutert .

Um eine Vorstellung davon zu bekommen, wie dies im Detail aussehen könnte, werfen Sie einen Blick darauf . Es zeigt eine Implementierung, die HAProxyfür die Bedienung verschiedener Clients je nach ihren Fähigkeiten erstellt wurde. Ich habe ein vollständiges Kopieren / Einfügen durchgeführt, um das Verrotten von Links zu verhindern, und weil ich denke, dass diese Frage in Zukunft von Interesse sein könnte:

SHA-1-Zertifikate sind auf dem Weg nach draußen, und Sie sollten so bald wie möglich ein Upgrade auf ein SHA-256-Zertifikat durchführen, es sei denn, Sie haben sehr alte Clients und müssen eine Weile die SHA-1-Kompatibilität beibehalten.

Wenn Sie sich in dieser Situation befinden, müssen Sie entweder ein Upgrade Ihrer Clients erzwingen (schwierig) oder eine Form von Zertifikatauswahllogik implementieren: Wir nennen dies "Zertifikatvermittlung".

Die deterministischste Auswahlmethode besteht darin, SHA-256-Zertifikate für Clients bereitzustellen, die ein TLS1.2 CLIENT HELLO präsentieren, das explizit ihre Unterstützung für SHA256-RSA (0x0401) in der Erweiterung "signature_algorithms" ankündigt.

Signaturalgorithmus-Erweiterungen

Moderne Webbrowser senden diese Erweiterung. Mir ist jedoch kein Open-Source-Load-Balancer bekannt, der derzeit den Inhalt der Erweiterung "signature_algorithms" überprüfen kann. Möglicherweise wird dies in Zukunft der Fall sein. Derzeit ist die Verwendung von HAProxy-SNI-ACLs der einfachste Weg, um einen Zertifikatswechsel zu erreichen: Wenn ein Client die SNI-Erweiterung vorlegt, leiten Sie sie an ein Back-End weiter, das ein SHA-256-Zertifikat vorlegt. Wenn die Erweiterung nicht angezeigt wird, nehmen Sie an, dass es sich um einen alten Client handelt, der SSLv3 oder eine fehlerhafte Version von TLS spricht, und legen Sie ihm ein SHA-1-Zertifikat vor.

Dies kann in HAProxy durch Verketten von Frontend und Backend erreicht werden:

HAProxy Cert Switching

global
        ssl-default-bind-ciphers 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-R
SA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

frontend https-in
        bind 0.0.0.0:443
        mode tcp
        tcp-request inspect-delay 5s
        tcp-request content accept if { req_ssl_hello_type 1 }
        use_backend jve_https if { req.ssl_sni -i jve.linuxwall.info }

        # fallback to backward compatible sha1
        default_backend jve_https_sha1

backend jve_https
        mode tcp
        server jve_https 127.0.0.1:1665
frontend jve_https
        bind 127.0.0.1:1665 ssl no-sslv3 no-tlsv10 crt /etc/haproxy/certs/jve_sha256.pem tfo
        mode http
        option forwardfor
        use_backend jve

backend jve_https_sha1
        mode tcp
        server jve_https 127.0.0.1:1667
frontend jve_https_sha1
        bind 127.0.0.1:1667 ssl crt /etc/haproxy/certs/jve_sha1.pem tfo ciphers 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:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
        mode http
        option forwardfor
        use_backend jve

backend jve
        rspadd Strict-Transport-Security:\ max-age=15768000
        server jve 172.16.0.6:80 maxconn 128

Die obige Konfiguration empfängt eingehenden Datenverkehr im Frontend mit dem Namen "https-in". Dieses Frontend befindet sich im TCP-Modus und überprüft den vom Client kommenden CLIENT HELLO auf den Wert der SNI-Erweiterung. Wenn dieser Wert vorhanden ist und mit unserer Zielwebsite übereinstimmt, wird die Verbindung zum Back-End mit dem Namen "jve_https" gesendet, das zu einem Front-End mit dem Namen "jve_https" umgeleitet wird, in dem das SHA256-Zertifikat konfiguriert und dem Client bereitgestellt wird.

Wenn der Client kein CLIENT HELLO mit SNI vorlegt oder ein SNI vorlegt, das nicht zu unserer Zielwebsite passt, wird es an das Backend "https_jve_sha1" und dann an das entsprechende Frontend weitergeleitet, an dem ein SHA1-Zertifikat bereitgestellt wird. Dieses Frontend unterstützt auch eine ältere Verschlüsselungssuite für ältere Clients.

Beide Frontends leiten schließlich zu einem einzelnen Backend mit dem Namen "jve" weiter, das Datenverkehr an die Ziel-Webserver sendet.

Dies ist eine sehr einfache Konfiguration, die möglicherweise mithilfe besserer ACLs (HAproxy fügt regelmäßig neue hinzu) verbessert werden kann. Bei einer grundlegenden Konfiguration für die Zertifikatsumschaltung ist dies jedoch erledigt!

gf_
quelle
9

Eine ähnliche Frage wurde unter https://community.qualys.com/thread/16387 gestellt

Ich denke, diese Antwort ist die Lösung:

suche.org ist eine clevere Implementierung. Soweit ich weiß, werden die Fähigkeiten des Kunden abgefragt und nur die besten verfügbaren angeboten, um Zweifel auszuräumen.

Jeff
quelle
2
"es fragt die Fähigkeiten des Kunden ab" ist jedoch keine nützliche Beschreibung. Es gibt kaum genug Informationen für andere, um ihre eigene Implementierung durchzuführen.
womble