Como funciona a troca de certificados HTTPS (como em suche.org)?

20

Para aqueles que não sabem o que é o Suche.org, é um site com uma classificação A + perfeita no SSL Labs em todas as categorias: ( resultado do Suche.org SSL Labs ). Tomei conhecimento deste site quando abri outro ticket sobre certificados ECC que não funcionavam no Chrome e um dos respondentes usou o site como exemplo.

O que me confunde é que, embora a Protocol Supportseção do relatório diga que o site usa apenas o TLSv1.2 ...

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

Esse claramente não é o caso, pois, na Handshake Simulationseção, ele mostra que alguns dos clientes mais antigos simulados estão usando o TLSv1.0 para conectar-se ...

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

Isso é um pouco frustrante, porque se eu desativar o TLSv1.0 no meu site de teste, assim ...

# Apache example
SSLProtocol all -SSLv3 -SSLv2 -TLSv1

A execução da varredura do SSL Labs no meu site de teste gera o seguinte para alguns dos clientes mais antigos:

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

Como é possível permitir simultaneamente apenas conexões TLSv1.2, além de oferecer suporte a clientes mais antigos?

Scott Crooks
fonte
Devemos tornar o título mais genérico, algo como "lógica de comutação de certificado HTTPS"?
gf_ 01/09/19
11
@gf_ Boa ideia. Feito.
Scott Crooks

Respostas:

17

Tenho certeza de que eles estão verificando os recursos do cliente e agem de acordo, conforme explicado no tópico vinculado na resposta de @Jeff .

Para ter uma idéia de como isso pode parecer em detalhes, dê uma olhada nisso . Ele mostra uma implementação feita HAProxypara atender diferentes clientes, diferentes certificados, dependendo de suas capacidades. Fiz uma cópia / colar completa, para evitar a podridão do link, e porque acho que essa pergunta pode ser interessante no futuro:

Os certificados SHA-1 estão saindo e você deve atualizar para um certificado SHA-256 assim que possível ... a menos que tenha clientes muito antigos e mantenha a compatibilidade com o SHA-1 por um tempo.

Se você estiver nessa situação, precisará forçar seus clientes a atualizar (difícil) ou implementar alguma forma de lógica de seleção de certificado: chamamos isso de "comutação de certificado".

O método de seleção mais determinístico é servir certificados SHA-256 para clientes que apresentam uma TLS1.2 CLIENT HELLO que anuncia explicitamente seu suporte ao SHA256-RSA (0x0401) na extensão signature_algorithms.

extensões de algoritmo de assinatura

Navegadores modernos enviarão esta extensão. No entanto, não conheço nenhum balanceador de carga de código aberto que atualmente possa inspecionar o conteúdo da extensão signature_algorithms. Pode vir no futuro, mas, por enquanto, a maneira mais fácil de obter a troca de certificado é usar ACLs HAProxy SNI: se um cliente apresentar a extensão SNI, direcione-a para um back-end que apresente um certificado SHA-256. Se não apresentar a extensão, suponha que seja um cliente antigo que fale SSLv3 ou alguma versão quebrada do TLS e apresente um certificado SHA-1.

Isso pode ser alcançado no HAProxy, encadeando o front-end e o back-end:

Comutação de certificado 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

A configuração acima recebe tráfego de entrada no front-end chamado "https-in". Esse frontend está no modo TCP e inspeciona o CLIENT HELLO vindo do cliente quanto ao valor da extensão SNI. Se esse valor existir e corresponder ao nosso site de destino, ele envia a conexão ao back-end chamado "jve_https", que redireciona para um front-end também chamado "jve_https", em que o certificado SHA256 é configurado e enviado ao cliente.

Se o cliente falhar em apresentar um CLIENT HELLO com SNI ou apresentar um SNI que não corresponda ao nosso site de destino, ele será redirecionado para o backend "https_jve_sha1" e, em seguida, para o frontend correspondente, onde um certificado SHA1 é servido. Esse front-end também suporta um ciphersuite mais antigo para acomodar clientes mais antigos.

Os dois front-end eventualmente redirecionam para um único back-end chamado "jve", que envia tráfego para os servidores da web de destino.

Essa é uma configuração muito simples e, eventualmente, pode ser aprimorada usando ACLs melhores (o HAproxy regularmente adiciona novas), mas para uma configuração básica de troca de certificado, ele faz o trabalho!

gf_
fonte
9

Uma pergunta semelhante foi feita em https://community.qualys.com/thread/16387

Penso que esta resposta é a solução:

suche.org é uma implementação inteligente. Tanto quanto eu entendo, ele consulta as capacidades do cliente e oferece apenas o melhor disponível, para tirar qualquer dúvida.

Jeff
fonte
2
"consulta as capacidades do cliente" não é exatamente uma descrição útil. Não há informações suficientes para que mais alguém faça sua própria implementação.
Womble