Jak działa przełączanie certyfikatów HTTPS (jak na such.org)?

20

Dla tych, którzy nie wiedzą, czym jest Suche.org, jest to strona internetowa, która ma doskonałą ocenę A + w SSL Labs w każdej kategorii: (wynik Suche.org SSL Labs ). Dowiedziałem się o tej stronie, kiedy otworzyłem kolejny bilet na certyfikaty ECC niedziałające w Chrome , a jeden z respondentów wykorzystał tę stronę jako przykład.

To, co mnie dezorientuje, to fakt, że chociaż Protocol Supportsekcja raportu mówi, że strona używa tylko TLSv1.2 ...

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

Wyraźnie tak nie jest, ponieważ w tej Handshake Simulationsekcji pokazano, że niektórzy symulowani starsi klienci używają TLSv1.0 do łączenia ...

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

Jest to trochę frustrujące, ponieważ jeśli wyłączę TLSv1.0 na mojej stronie testowej tak ...

# Apache example
SSLProtocol all -SSLv3 -SSLv2 -TLSv1

Uruchomienie skanowania SSL Labs na mojej stronie testowej daje następujące wyniki dla niektórych starszych klientów:

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

Jak można jednocześnie zezwalać tylko na połączenia TLSv1.2, a jednocześnie obsługiwać starszych klientów?

Scott Crooks
źródło
Czy tytuł powinien być bardziej ogólny, coś w rodzaju „logiki przełączania certyfikatu HTTPS”?
gf_
1
@gf_ Dobry pomysł. Gotowy.
Scott Crooks,

Odpowiedzi:

17

Jestem pewien, że sprawdzają możliwości klienta i działają odpowiednio, jak wyjaśniono w wątku powiązanym z odpowiedzią @Jeff .

Aby dowiedzieć się, jak to szczegółowo może wyglądać, spójrz na to . Pokazuje implementację wykonaną w HAProxycelu obsługi różnych klientów różnych certyfikatów, w zależności od ich możliwości. Zrobiłem pełną kopię / wklej, aby zapobiec gniciu linków, a ponieważ uważam, że to pytanie może być interesujące w przyszłości:

Certyfikaty SHA-1 są w drodze do wyjścia i należy jak najszybciej uaktualnić do certyfikatu SHA-256 ... chyba że masz bardzo starych klientów i musisz zachować zgodność z SHA-1 przez jakiś czas.

Jeśli jesteś w takiej sytuacji, musisz albo zmusić swoich klientów do uaktualnienia (trudne) lub zaimplementować logikę wyboru certyfikatu: nazywamy to „przełączaniem certyfikatu”.

Najbardziej deterministyczną metodą selekcji jest obsługa certyfikatów SHA-256 klientom, którzy prezentują WITAMI KLIENTÓW TLS1.2, którzy jawnie ogłaszają wsparcie dla SHA256-RSA (0x0401) w rozszerzeniu algorytm podpisu.

rozszerzenia algorytmu podpisu

Nowoczesne przeglądarki internetowe wyślą to rozszerzenie. Jednak nie znam żadnego modułu równoważenia obciążenia typu open source, który obecnie jest w stanie sprawdzić zawartość rozszerzenia podpis_algorytmy. Może przyjść w przyszłości, ale na razie najłatwiejszym sposobem na przełączenie certyfikatu jest użycie list ACL HAProxy SNI: jeśli klient przedstawia rozszerzenie SNI, skieruj go do backendu, który przedstawia certyfikat SHA-256. Jeśli nie przedstawia rozszerzenia, załóż, że jest to stary klient, który mówi SSLv3 lub jakąś zepsutą wersję TLS, i przedstaw mu certyfikat SHA-1.

Można to osiągnąć w HAProxy, łącząc frontend i backendy:

Przełączanie certyfikatu HAProxy

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

Powyższa konfiguracja odbiera ruch przychodzący w interfejsie o nazwie „https-in”. Ten interfejs jest w trybie TCP i sprawdza, czy CLIENT HELLO pochodzi od klienta pod kątem wartości rozszerzenia SNI. Jeśli ta wartość istnieje i jest zgodna z naszą witryną docelową, wysyła połączenie do zaplecza o nazwie „jve_https”, który przekierowuje do interfejsu o nazwie również „jve_https”, w którym certyfikat SHA256 jest skonfigurowany i podawany klientowi.

Jeśli klient nie zaprezentuje WITA KLIENTA z SNI lub przedstawi SNI, który nie pasuje do naszej strony docelowej, zostanie przekierowany do backendu „https_jve_sha1”, a następnie do odpowiedniego interfejsu, na którym jest obsługiwany certyfikat SHA1. Ten interfejs obsługuje również starszą wersję szyfrowania, aby pomieścić starszych klientów.

Oba interfejsy ostatecznie przekierowują do jednego backendu o nazwie „jve”, który wysyła ruch do docelowych serwerów WWW.

Jest to bardzo prosta konfiguracja, która ostatecznie może zostać ulepszona za pomocą lepszych list ACL (HAproxy regularnie dodaje wiadomości), ale w przypadku podstawowej konfiguracji przełączania certyfikatów zadanie to się robi!

gf_
źródło
9

Podobne pytanie zadano na https://community.qualys.com/thread/16387

Myślę, że ta odpowiedź jest rozwiązaniem:

suche.org to sprytna implementacja. O ile rozumiem, sprawdza możliwości klienta, a następnie oferuje tylko najlepsze dostępne, aby usunąć wszelkie wątpliwości.

Jeff
źródło
2
„odpytuje możliwości klienta”, ale nie jest to przydatny opis. Nie ma wystarczająco dużo informacji, aby ktokolwiek inny mógł wykonać własną implementację.
womble