¿Cómo puedo detectar si un servidor está usando SNI para HTTPS?

41

Estoy buscando una manera simple de saber si un servidor está utilizando la extensión SSL de Indicación de nombre de servidor para su certificado HTTPS en un sitio web. Un método que utiliza un navegador o una línea de comandos de Unix está bien.

¡Gracias!

Spookylukey
fuente

Respuestas:

20

El cliente inicia SNI, por lo que necesita un cliente que lo admita. A menos que esté en Windows XP, su navegador funcionará. Si su cliente le permite depurar las conexiones SSL correctamente (lamentablemente, incluso los comandos gnutls / openssl CLI no lo hacen), puede ver si el servidor devuelve un campo nombre_servidor en el saludo extendido. Tenga en cuenta que la ausencia de este campo solo significa que el servidor no usó el nombre_servidor en el saludo del cliente para ayudar a elegir un certificado, no que no lo admita.

Entonces, en la práctica, la prueba más fácil es simplemente intentar conectarse. Para esto, necesita conocer dos nombres que se resuelven en la misma IP, a los que se puede hacer una conexión SSL. https es lo más fácil, ya que puede simplemente buscar ambos nombres y ver si se le presenta el certificado correcto.

Hay tres resultados:

  • Obtiene un certificado comodín (o uno con un subjectAltName) que cubre ambos nombres: no aprende nada
  • Obtiene el certificado incorrecto para al menos uno de ellos: o el servidor no admite SNI o se ha configurado incorrectamente
  • Obtiene dos certificados diferentes, ambos para el nombre correcto: SNI es compatible y está configurado correctamente.

Una prueba un poco más complicada que generará más información es tener cables abiertos y capturar mientras navega. Luego puede encontrar los paquetes relevantes filtrando por ssl.handshake. Las capturas de pantalla a continuación son un ejemplo de un par de saludo de cliente / saludo de servidor donde se admite SNI:

Cliente hola Hola servidor

Nuevamente, por supuesto, la ausencia de un campo nombre_servidor en el servidor hola no indica que SNI no sea compatible. Simplemente que el nombre de servidor proporcionado por el cliente no se usó para decidir qué certificado usar.

Dennis Kaarsemaker
fuente
99
Dennis: no estoy de acuerdo openssl. Algunos detalles están disponibles: se proporciona openssl s_client -servername alice.sni.velox.ch -tlsextdebug -msg -connect alice.sni.velox.ch:443alguna indicación de uso de SNI durante la prueba Qualys SSL .
Deer Hunter
Ah, me perdí eso en la página del manual. Gracias por la adicion.
Dennis Kaarsemaker
26

El único revestimiento que probablemente esté buscando para detectar la presencia de un encabezado de extensión de indicación de nombre de servidor SSL / TLS es:

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

donde www.SERVERNAME.comestá el valor SNI que está probando y www.YOURSERVER.comes el nombre de dominio o la dirección IP del servidor compatible con TLS que está probando.

La línea de comando usa openssl's s_client(vea s_client (1) ) para conectarse al servidor en www.YOURSERVER.comel puerto 443. La -tlsextdebugopción activa la salida de depuración de la extensión TLS. La -servernameopción le dice al s_clientprograma que pase www.SERVERNAME.comcomo el valor del campo SNI en el paquete ClientHello durante el protocolo de enlace TLS.

Finalmente, 2>/dev/nullsimplemente oculta la salida stderr (que puede ser ruidosa), y la | grep "server name"tubería filtra stdout para mostrar la extensión TLS llamada "nombre del servidor" en s_clientla salida de depuración de la extensión TLS.

Si ve una línea de salida como

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

entonces el servidor está devolviendo la información del encabezado SNI en su respuesta ServerHello. Si no lo hace, es posible que el servidor no sea compatible con SNI o que no haya sido configurado para devolver información SNI dado el nombre que está solicitando. En este caso, verifique que esté usando un nombre de dominio en la -servernameopción que el servidor debe responder con información SNI.

Meitar
fuente
1
La salida es la misma si uso correcto -servernameo no. -servername sdfsdlkfjsdf23.somedomain.somewhere -connect realhost.somedomain.somewhere= TLS server extension "server name" (id=0), len=0(Y la misma salida si coinciden). ¿Cómo verifica que no coincide con un host en el servidor de la salida?
bshea
1
@bshea Debe pasar -msgademás de los parámetros anteriores y grep para "Alert". Si -servernameestá mal, obtendrá algo como TLS 1.2 Alert ... warning unrecognized_namedel servidor. @Meitar Creo que si agrega eso a la respuesta será útil para otras personas.
Viktor Nonov
@ViktorNonov El -msginterruptor simplemente agrega un hexdump de mensajes de protocolo TLS. No es necesario observar un error de protocolo de enlace TLS, por lo que sería incorrecto agregar a esta respuesta. Además, los errores de apretón de manos de TLS como este se imprimen en STDOUT, lo que significa que 2>/dev/nulldebería eliminarse de la respuesta para poder procesarla grepen primer lugar. Lo que @bshea realmente está preguntando es "¿Cómo detecto los errores de TLS?" que es una pregunta completamente diferente a la pregunta de "¿Este servidor utiliza la función SNI del protocolo TLS?" cuál es el tema aquí.
Meitar
@Meitar, no pude encontrar otra forma de observar los mensajes de apretón de manos de TLS. Además, incluso si redirijo STDERRa un archivo de texto, no obtengo ese error allí. Sin -msgno pude encontrar otra opción que muestra los mensajes de apretón de manos. (usando openssl 1.0.2q). Siempre y cuando la relevancia para la respuesta tenga razón.
Viktor Nonov
-2

Puede usar opensslpara buscar y consultar el certificado.

  • buscar el certificado con openssl s_client -connect
  • analizar el certificado con openssl x509
  • grep para encontrar la información "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

La última línea muestra todas las entradas de SNI presentes en el certificado:

                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch
Spazm
fuente
¿Qué estoy buscando en esa salida? ¿El hecho de que múltiples dominios están presentes?
spookylukey
Las DNS:... entradas en la última línea muestran todos los nombres SNI válidos en el certificado.
spazm
44
Las SAN en un certificado y la compatibilidad con SNI en un servidor son cosas diferentes, el uso de SAN para alojamiento virtual HTTPS es algo de hack que es anterior a SNI. Para SNI, no necesita un certificado con SAN porque el servidor puede seleccionar un certificado individual que coincida con las expectativas de nombres de los clientes.
Sr.Spuratic