Wie kann ich feststellen, ob ein Server SNI für HTTPS verwendet?

41

Ich suche nach einer einfachen Möglichkeit, um festzustellen, ob ein Server die SSL-Erweiterung "Server Name Indication" für sein HTTPS-Zertifikat auf einer Website verwendet. Eine Methode, die entweder einen Browser oder eine Unix-Befehlszeile verwendet, ist in Ordnung.

Vielen Dank!

spookylukey
quelle

Antworten:

20

SNI wird vom Client initiiert, daher benötigen Sie einen Client, der dies unterstützt. Sofern Sie nicht mit Windows XP arbeiten, funktioniert dies in Ihrem Browser. Wenn Ihr Client das Debuggen von SSL-Verbindungen ordnungsgemäß zulässt (leider nicht einmal die CLI-Befehle gnutls / openssl), können Sie im erweiterten Hallo sehen, ob der Server ein Feld server_name zurücksendet. Beachten Sie, dass das Fehlen dieses Felds nur bedeutet, dass der Server den Servernamen im Client nicht verwendet hat, um ein Zertifikat auszuwählen, und nicht, dass es dieses nicht unterstützt.

In der Praxis ist es also am einfachsten, eine Verbindung herzustellen. Dazu müssen Sie zwei Namen kennen, die sich zu derselben IP auflösen, zu der eine SSL-Verbindung hergestellt werden kann. https ist am einfachsten, da Sie dann einfach zu beiden Namen navigieren und feststellen können, ob Ihnen das richtige Zertifikat vorliegt.

Es gibt drei Ergebnisse:

  • Sie erhalten ein Wildcard-Zertifikat (oder eines mit einem subjectAltName), das beide Namen abdeckt: Sie lernen nichts
  • Für mindestens eines von ihnen erhalten Sie das falsche Zertifikat: Entweder unterstützt der Server kein SNI oder es wurde falsch konfiguriert
  • Sie erhalten zwei verschiedene Zertifikate, beide für den richtigen Namen: SNI wird unterstützt und korrekt konfiguriert.

Ein etwas komplizierterer Test, der mehr Informationen liefert, besteht darin, dass wireshark geöffnet ist und beim Browsen erfasst wird. Sie können dann die relevanten Pakete finden, indem Sie nach ssl.handshake filtern. Die folgenden Screenshots zeigen ein Beispiel für ein Client-Hallo / Server-Hallo-Paar, bei dem SNI unterstützt wird:

Kunde hallo Hallo Server

Auch hier bedeutet das Fehlen eines server_name-Felds im server hello natürlich nicht, dass SNI nicht unterstützt wird. Lediglich, dass der vom Client bereitgestellte Servername bei der Entscheidung, welches Zertifikat verwendet werden soll, nicht verwendet wurde.

Dennis Kaarsemaker
quelle
9
Dennis - nicht einverstanden openssl. Einige Details sind verfügbar: openssl s_client -servername alice.sni.velox.ch -tlsextdebug -msg -connect alice.sni.velox.ch:443Einige Hinweise zur Verwendung von SNI werden während des Qualys SSL-Tests gegeben .
Deer Hunter
Ah, das habe ich auf der Manpage verpasst. Danke für den Zusatz.
Dennis Kaarsemaker
26

Der eine Liner, nach dem Sie wahrscheinlich suchen, um das Vorhandensein eines Erweiterungsheaders für die SSL / TLS-Servername-Anzeige zu erkennen, ist:

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

Dabei www.SERVERNAME.comhandelt es sich um den SNI-Wert, den Sie testen, und www.YOURSERVER.comum den Domänennamen oder die IP-Adresse des TLS-fähigen Servers, den Sie testen.

Die Befehlszeile verwendet openssl's s_client(siehe s_client (1) ), um eine Verbindung zum Server an einem www.YOURSERVER.comPort herzustellen443 . Die -tlsextdebugOption aktiviert die TLS-Erweiterungs-Debugging-Ausgabe. Die -servernameOption weist das s_clientProgramm an, www.SERVERNAME.comwährend des TLS-Handshakes als Wert des SNI-Felds im ClientHello-Paket zu übergeben.

Schließlich wird 2>/dev/nulldie stderr-Ausgabe (die laut sein kann) einfach ausgeblendet, und die | grep "server name"Pipeline filtert stdout, um die TLS-Erweiterung mit dem Namen "Servername" in s_clientder TLS-Erweiterungs-Debugging-Ausgabe anzuzeigen .

Wenn Sie eine Ausgabezeile sehen, wie z

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

dann gibt der Server in seiner ServerHello-Antwort SNI-Header-Informationen zurück. Andernfalls unterstützt der Server möglicherweise weder SNI noch wurde er so konfiguriert, dass er SNI-Informationen mit dem von Ihnen gewünschten Namen zurückgibt. Stellen Sie in diesem Fall sicher, dass Sie einen Domänennamen in der -servernameOption verwenden, über die der Server mit SNI-Informationen antworten soll.

Meitar
quelle
1
Die Ausgabe ist die gleiche, ob ich richtig verwende -servernameoder nicht. -servername sdfsdlkfjsdf23.somedomain.somewhere -connect realhost.somedomain.somewhere= TLS server extension "server name" (id=0), len=0(Und dieselbe Ausgabe, wenn sie übereinstimmt.) Wie vergewissern Sie sich, dass die Ausgabe nicht mit einem Host auf dem Server übereinstimmt?
9.
1
@bshea Du musst -msgzusätzlich zu den oben genannten Parametern übergehen und nach "Alert" greifen. Wenn das nicht -servernamestimmt, bekommst du so etwas TLS 1.2 Alert ... warning unrecognized_namevom Server. @Meitar Ich denke, wenn du das zur Antwort hinzufügst, wird es für andere Menschen nützlich sein.
Viktor Nonov
@ViktorNonov Der -msgSwitch fügt einfach einen Hexdump der TLS-Protokollnachrichten hinzu. Es ist nicht erforderlich, einen TLS-Handshake-Fehler zu beobachten, daher wäre es falsch, diese Antwort zu ergänzen. Darüber hinaus werden TLS-Handshake-Fehler wie diese an STDOUT ausgegeben, was bedeuten würde, dass der Name 2>/dev/nullaus der Antwort entfernt werden müsste, damit er überhaupt verarbeitet werden kann grep. Nach was @bshea eigentlich fragt, ist "Wie erkenne ich TLS-Fehler?" Dies ist eine andere Frage als die Frage "Verwendet dieser Server die SNI-Funktion des TLS-Protokolls?". Welches ist das Thema hier.
Meitar
@Meitar, ich konnte keinen anderen Weg finden, um die TLS-Handshake-Nachrichten zu beobachten. Auch wenn ich die STDERRDatei in eine Textdatei umleite, wird dieser Fehler dort nicht angezeigt. Ohne -msgkonnte ich keine andere Option finden, die die Handshake-Nachrichten anzeigt. (unter Verwendung von openssl 1.0.2q). Solange die Relevanz für die Antwort stimmt, haben Sie vielleicht Recht.
Viktor Nonov
-2

Mit können Sie openssldas Zertifikat abrufen und abfragen.

  • hol das Zertifikat mit openssl s_client -connect
  • Parsen Sie das Zertifikat mit openssl x509
  • grep um die "DNS:" Info zu finden

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

Die letzte Zeile zeigt alle im Zertifikat vorhandenen SNI-Einträge:

                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch
spazm
quelle
Was suche ich in dieser Ausgabe? Die Tatsache, dass mehrere Domänen vorhanden sind?
Spookylukey
Die DNS:... Einträge in der letzten Zeile zeigen alle gültigen SNI-Namen im Zertifikat.
Spazm
4
SANs in einem Zertifikat und SNI-Unterstützung auf einem Server sind verschiedene Dinge. Die Verwendung von SANs für das virtuelle HTTPS-Hosting ist eine Art Hack vor SNI. Für SNI benötigen Sie kein Zertifikat mit SANs, da der Server ein einzelnes Zertifikat auswählen kann, das den Namenserwartungen der Clients entspricht.
mr.spuratic