Como posso detectar se um servidor está usando o SNI para HTTPS?

41

Estou procurando uma maneira simples de saber se um servidor está usando a extensão SSL de Indicação de Nome de Servidor para seu certificado HTTPS em um site. Um método que usa um navegador ou uma linha de comando do Unix é bom.

Obrigado!

spookylukey
fonte

Respostas:

20

O SNI é iniciado pelo cliente, portanto, você precisa de um cliente que o suporte. A menos que você esteja no Windows XP, seu navegador funcionará. Se o seu cliente permitir depurar conexões SSL corretamente (infelizmente, mesmo os comandos da CLI gnutls / openssl não), você poderá ver se o servidor envia de volta um campo server_name no hello estendido. Observe que a ausência desse campo significa apenas que o servidor não usou o server_name no hello do cliente para ajudar a escolher um certificado, não que não o suporte.

Portanto, na prática, o teste mais fácil é simplesmente tentar se conectar. Para isso, é necessário conhecer dois nomes que resolvem o mesmo IP, aos quais uma conexão SSL pode ser feita. https é mais fácil, pois você pode simplesmente procurar os dois nomes e ver se recebe o certificado correto.

Existem três resultados:

  • Você recebe um certificado curinga (ou um com um subjectAltName) que abrange os dois nomes: você não aprende nada
  • Você obtém o certificado errado para pelo menos um deles: o servidor não suporta SNI ou foi configurado errado
  • Você recebe dois certificados diferentes, ambos com o nome correto: SNI é suportado e configurado corretamente.

Um teste um pouco mais complicado que trará mais informações é ter o wireshark aberto e capturado durante a navegação. Você pode encontrar os pacotes relevantes filtrando ssl.handshake. As capturas de tela abaixo são um exemplo de um par de hello cliente / servidor hello em que o SNI é suportado:

Olá cliente Olá servidor

Novamente, é claro que a ausência de um campo server_name no hello do servidor não indica que o SNI não é suportado. Apenas que o server_name fornecido pelo cliente não foi usado para decidir qual certificado usar.

Dennis Kaarsemaker
fonte
9
Dennis - discordo openssl. Alguns detalhes estão disponíveis: openssl s_client -servername alice.sni.velox.ch -tlsextdebug -msg -connect alice.sni.velox.ch:443Alguma indicação do uso de SNI é fornecida durante o teste SSL da Qualys .
Deer Hunter
Ah, eu senti falta disso na página de manual. Obrigado pela adição.
Dennis Kaarsemaker
26

O liner que você provavelmente está procurando para detectar a presença de um cabeçalho de extensão de indicação de nome de servidor SSL / TLS é:

openssl s_client -servername www.SERVERNAME.com -tlsextdebug -connect www.YOURSERVER.com:443 2>/dev/null | grep "server name"

onde www.SERVERNAME.comestá o valor SNI que você está testando e www.YOURSERVER.comé o nome de domínio ou o endereço IP do servidor compatível com TLS que está testando.

A linha de comando usa openssl's s_client(consulte s_client (1) ) para conectar-se ao servidor na www.YOURSERVER.comporta 443. A -tlsextdebugopção ativa a saída de depuração da extensão TLS. A -servernameopção informa ao s_clientprograma para passar www.SERVERNAME.comcomo o valor do campo SNI no pacote ClientHello durante o handshake TLS.

Por fim, 2>/dev/nullsimplesmente oculta a saída stderr (que pode ser barulhenta) e o | grep "server name"pipeline filtra o stdout para exibir a extensão TLS chamada "nome do servidor" na s_clientsaída de depuração da extensão TLS.

Se você vir uma linha de saída como

TLS server extension "server name" (id=0), len=0

o servidor retornará as informações do cabeçalho SNI em sua resposta ServerHello. Caso contrário, é possível que o servidor não seja compatível com SNI ou não tenha sido configurado para retornar informações SNI, com o nome que você está solicitando. Nesse caso, verifique se você está usando um nome de domínio na -servernameopção sobre a qual o servidor deve responder com informações SNI.

Meitar
fonte
1
A saída é a mesma, seja eu correta -servernameou não. -servername sdfsdlkfjsdf23.somedomain.somewhere -connect realhost.somedomain.somewhere= TLS server extension "server name" (id=0), len=0(E a mesma saída, se corresponderem.) Como você verifica se não corresponde a um host no servidor a partir da saída?
bshea 9/01
1
@bshea Você precisa passar -msgalém dos parâmetros acima e grep para "Alert". Se -servernameestiver errado, você receberá algo como TLS 1.2 Alert ... warning unrecognized_namedo servidor. @ Meitar Eu acho que se você adicionar isso à resposta, será útil para outras pessoas.
Viktor Nonov
@ViktorNonov O -msgswitch simplesmente adiciona um hexdump de mensagens do protocolo TLS. Não é necessário observar um erro de handshake do TLS; portanto, seria incorreto adicionar essa resposta. Além disso, erros de handshake TLS como este são impressos em STDOUT, o que significa que 2>/dev/nullseria necessário remover a resposta para que fosse processada grepem primeiro lugar. O que a @bshea está realmente pedindo é "Como faço para detectar erros do TLS?" que é uma pergunta totalmente diferente da pergunta "Este servidor utiliza o recurso SNI do protocolo TLS?" qual é o tópico aqui.
Meitar 28/02
@ Meitar, não consegui encontrar outra maneira de observar as mensagens de handshake TLS. Além disso, mesmo que eu o redirecione STDERRpara um arquivo de texto, não estou recebendo esse erro lá. Sem -msgeu não consegui encontrar outra opção que mostre as mensagens do aperto de mão. (usando o openssl 1.0.2q). Contanto que a relevância para a resposta esteja correta.
Viktor Nonov
-2

Você pode usar opensslpara buscar e consultar o certificado.

  • buscar o certificado com openssl s_client -connect
  • analisar o certificado com openssl x509
  • grep para encontrar as informações "DNS:"

openssl s_client -connect alice.sni.velox.ch:443 | openssl x509 -noout -text | grep DNS:

% openssl s_client -connect alice.sni.velox.ch:443 | openssl x509 -noout -text | grep DNS:
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = BM, O = QuoVadis Limited, CN = QuoVadis Global SSL ICA G2
verify return:1
depth=0 C = CH, ST = Zuerich, L = Zuerich, O = Kaspar Brand, CN = alice.sni.velox.ch
verify return:1
                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch

A última linha mostra todas as entradas SNI presentes no certificado:

                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch
spazm
fonte
O que estou procurando nessa saída? O fato de vários domínios estarem presentes?
Spookylukey 16/05
As DNS:... entradas na última linha mostram todos os nomes SNI válidos no certificado.
Spazm
4
SANs em um certificado e suporte a SNI em um servidor são coisas diferentes, o uso de SANs para host virtual HTTPS é algo de hack que antecede o SNI. Para o SNI, você não precisa de um certificado com SANs porque o servidor pode selecionar um certificado individual que corresponda às expectativas de nomenclatura dos clientes.
precisa saber é o seguinte