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 HAProxy
fü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.
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:
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!