Frage Wie funktioniert die HTTPS-Zertifikatsumschaltung (wie auf suche.org)?


Für diejenigen, die nicht wissen, was Suche.org ist, ist es eine Webseite, die eine perfekte A + Bewertung für SSL Labs in jeder Kategorie hat: (Suche.org SSL Labs Ergebnis). Ich wurde auf diese Website aufmerksam, als ich ein Ticket öffnete ECC-Zertifikate funktionieren nicht in Chromeund einer der Responder verwendete die Site als Beispiel.

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

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

Das ist eindeutig nicht der Fall, da unter der Handshake Simulation In diesem Abschnitt wird angezeigt, dass einige der simulierten älteren Clients TLSv1.0 zum Herstellen einer Verbindung verwenden.

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 ergibt für einige ältere Clients Folgendes:

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, nur TLSv1.2-Verbindungen gleichzeitig zuzulassen, aber auch ältere Clients zu unterstützen?


20
2017-07-25 17:54


Ursprung


Sollten wir den Titel generischer machen, etwa "HTTPS cert switching logic"? - gf_
@gf_ Gute Idee. Erledigt. - Scott Crooks


Antworten:


Ich bin mir ziemlich sicher, dass sie die Client-Fähigkeiten überprüfen und entsprechend handeln, wie im verknüpften Thread erklärt in der Antwort von @Jeff.

Um eine Vorstellung davon zu bekommen, wie dies im Detail aussehen könnte, werfen Sie einen Blick darauf bei diesem. Es zeigt eine Implementierung mit HAProxy je nach ihren Möglichkeiten unterschiedliche Kunden zu betreuen. Ich habe eine vollständige Kopie / Paste erstellt, um Linkfäule zu vermeiden, und weil ich denke, dass diese Frage in der Zukunft von Interesse sein könnte:

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

Wenn Sie in dieser Situation sind, müssen Sie entweder Ihre Clients zwingen, ein Upgrade durchzuführen (schwierig) oder eine Form der Zertifikatsauswahllogik implementieren: Wir nennen das "Cert-Switching".

Die deterministischste Auswahlmethode ist die Bereitstellung von SHA-256-Zertifikaten für Clients, die einen TLS1.2-CLIENT-HELLO bereitstellen, der explizit ihre Unterstützung für SHA256-RSA (0x0401) in der Signature-Algorithmus-Erweiterung ankündigt.

signature algorithm extensions

Moderne Webbrowser senden diese Erweiterung. Mir ist jedoch kein Open-Source-Lastenausgleich bekannt, der derzeit den Inhalt der signature_algorithms-Erweiterung überprüfen kann. Es kann in Zukunft kommen, aber im Moment ist der einfachste Weg, Cert-Switching zu erreichen, HAProxy SNI ACLs zu verwenden: Wenn ein Client die SNI-Erweiterung präsentiert, leiten Sie sie an ein Backend, das ein SHA-256-Zertifikat enthält. Wenn die Erweiterung nicht angezeigt wird, nehmen Sie an, dass es sich um einen alten Client handelt, der SSLv3 oder eine beschädigte Version von TLS verwendet, und legen Sie ihm ein SHA-1-Zertifikat vor.

Dies kann in HAProxy durch Verketten von Frontend und Backends 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 namens "https-in". Dieses Frontend befindet sich im TCP-Modus und überprüft den CLIENT HELLO, der vom Client kommt, auf den Wert der SNI-Erweiterung. Wenn dieser Wert existiert und mit unserem Zielstandort übereinstimmt, sendet er die Verbindung an das Backend namens "jve_https", das zu einem Frontend namens "jve_https" umleitet, wo das SHA256-Zertifikat konfiguriert und dem Client bereitgestellt wird.

Wenn der Client keinen CLIENT HELLO mit SNI präsentiert oder einen SNI präsentiert, der nicht mit unserer Ziel-Site übereinstimmt, wird er zum Back-End "https_jve_sha1" und dann zum entsprechenden Frontend umgeleitet, wo ein SHA1-Zertifikat geliefert wird. Dieses Frontend unterstützt auch eine ältere Cipher-Suite für ältere Clients.

Beide Frontends werden schließlich zu einem einzigen Backend namens "jve" umgeleitet, das Datenverkehr an die Ziel-Webserver sendet.

Dies ist eine sehr einfache Konfiguration und könnte eventuell mit besseren ACLs verbessert werden (HAproxy fügt regelmäßig neue hinzu), aber für eine grundlegende Konfiguration der Cert-Switching wird die Arbeit erledigt!


17
2017-07-25 20:41





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

Meiner Ansicht nach diese Antwort ist die Lösung:

suche.org ist eine clevere Implementierung. Soweit ich es verstehe   fragt die Fähigkeiten des Kunden ab und bietet dann nur das Beste   verfügbar, um jeden Zweifel zu beseitigen.


9
2017-07-25 20:04



"es fragt die Fähigkeiten des Klienten ab" ist nicht gerade eine nützliche Beschreibung, obwohl. Es gibt kaum genug Informationen für irgendjemand anderen, um ihre eigene Implementierung durchzuführen. - womble♦