SNI-Zertifikate

Durch die Funktion "Server Name Indication" gibt es eine neue Möglichkeit hinter einer IP-Adresse mehrere Webseiten mit unterschiedlichen Namen zu verbergen.

SNI wurde schon 2003 als RFC 3546 definiert.

Die Problematik

Um Datenübertragungen über das Internet zu verschlüsseln, kommt HTTPS, also HTTPS over SSL zum Einsatz. Dazu verbindet sich der Client zum Server in der Regel über Port 443, macht einen TLS Handshake, bei dem vom Server das Zertifikat gesendet wird und der Client nach der erfolgreichen Prüfung von Name, Gültigkeit, Aussteller, CRL dann über die etablierte verschlüsselte Verbindung die eigentliche HTTP-Anfrage, eventuell mit Hostheader sendet.

Der Client kennt in dem Fall nur den Namen des Zielsystems und der Webserver muss dem Client ein Zertifikat senden, indem der angesprochene Name enthalten ist. Normal kennt der Webserver zu dem frühen Zeitpunkt des TLS-Handshake aber gar nicht den Namen, den der Client angesprochen hat. Ein Reverse Proxy kann aus dem entschlüsselten Datenverkehr natürlich den HostHeader ermitteln und die Anfragen an den richtigen "Bakend Server" weiter leiten, aber die Namen aller möglichen Hosts müssen erst mal im Zertifikat enthalten sein, damit der Client überhaupt die TLS-Verbindung aufbauen kann. Also muss es Lösungen geben um z.B. die folgenden beiden Probleme zu entschärfen:

  • IPv4 Knappheit
    Dass die IPv4-Adressen knapp werden, ist kein Geheimnis mehr. Auch wenn viele Webseiten ganz ohne SSL laufen, kann heute auf einer IP-Adresse bei Nutzung von normalen Zertifikaten immer nur genau eine Webseite betrieben werden. Das "kostet" natürlich viele Adressen und erschwert auch den Betrieb mehrerer Webserver auf dem gleichen Shared-Server.
  • Wildcard Zert
    Wer nun ein Wildcard-Zertifikat einsetzen will, wird sehr schnell merken, dass so ein Zertifikat immer auf eine Domäne gebunden ist. So lange sie viele Web-Dienste mit unterschiedlichen Namen in der gleichen Domäne auf der gleichen IP-Adresse betreiben wollen, ist das noch möglich, zumindest wenn der Client mit Wildcard zufrieden ist.
    Aber sobald nun Dienste aus unterschiedlichen Domänen erreichbar sein sollen, funktioniert dies nicht mehr
  • SAN-Zertifikate
    Es gibt schon länger die Möglichkeit, dass in einem Zertifikat mehrere Namen auch aus unterschiedlichen Domänen enthalten sind. Abgesehen, dass Sie teurer sind sind sie zumindest für einen Hoster kaum zu managen, denn sobald ein Name zusätzlich hinzukommen oder wieder entfernt werden soll, muss das komplette Zertifikat neu ausgestellt werden. Zudem wird die ausstellende CA natürlich alle Namen darin überprüfen. Ist dann nur ein Zonenverwalter nicht erreichbar, verzögert sich die veränderte Ausstellung.

Schon länger gibt es daher die Überlegung, wie der Client schon mit dem TLS-Handshake auch den Hostnamen mit senden kann, so dass ein Webserver dann schon analog zum HostHeader die richtige Webserverinstanz auswählen und dessen passendes Zertifikat verwenden kann

Server Name Indication

Und genau dieses Verfahren ist mit "Server Name Indication" gemeint. Der Clients sendet schon mit dem TLS-Handshake auch den Name des angesprochenen Servers mit. Hier am Beispiel einer neu gestarteten HTTPS-Verbindung zu Google.

Die ersten drei Pakete sind der TCP-Handshake um dann als Paket 4 mit dem "ClientHello" zu starten. In diesem Paket ist unter dem Feld "ClientHelloExtension" auch der Servername enthalten. Der Name des "Hosts" taucht ansonsten hier an keiner Stelle mehr auf. Erst später nach dem die SSL-Verbindung steht, wird der Name als Hostheader wieder mit dem HTTP-GET verwendet. Dann ist aber der Tunnel schon aufgebaut.

Ein entsprechend vorbereiteter Dienst auf der Serverseite kann anhand diese ersten Pakets den richtigen virtuellen Server zuordnen und dessen Zertifikat heran ziehen. So kann jeder "Kunde" seine eigenen Zertifikate bereit legen und der Provider kann mehrere Server mit eigenen Zertifikaten alle hinter einer IP-Adresse verbergen.

Client Support

Ehe ein Server überhaupt für den Client das richtige Zertifikat auswählen kann, muss der Client den gewünschten Namen natürlich erst mal "mit senden". Ob der Client dies tut, sehen Sie beim TLS-Handshake mit einem Netzwerk Monitor. Hier eine unvollständige Liste:

Produkt SNI Nutzung
Outlook 2013 RPC/HTTP auf Windows 7 Ja, SNI wird gesendet
IE 7 und neuer Nur auf Vista oder höher
Chrome Windows nur auf Vista oder höher
Opera Ab 8.0
Firefox 2.0 (und andere die auf Mozilla Platform asieren) Ab Mozilla Platform rv:1.8.
Safari 3.2.1 Windows nur auf Vista oder höher
Lync Communicator 2003 (15.0.4615.1000 auf Win 7) Ich denke dass alle Clients ab Vista den Server_Name mitsenden
Lync 2013 Edge (Ausgehende Anfragen Ja, leider versteht der Edge als Server eingehend noch kein SNI
Android 2.3.7 Nein
Android 4.0.4, 4.1.1., 4.2.2, 4.3 Ja
Android 4.4.2 Ja
Chrome 37 / OS X Ja
Firefox 24.2.0 ESR / Win 7 Ja
Firefox 32 / OS X Ja
Googlebot Jun 2014 Ja
IE 6/8 auf XP Nein
IE 7 / Vista Ja
IE 8-10 / Win 7 Ja
IE 11 / Win 7 Ja
IE 11 / Win 8.1 Ja
IE Mobile 10 / Win Phone 8.0 Ja
IE Mobile 11 / Win Phone 8.1 Ja
Java 6u45 Nein
Java 7u25 Ja
Java 8b132 Ja
OpenSSL 0.9.8y Ja
OpenSSL 1.0.1h Ja
Safari 5.1.9 / OS X 10.6.8
Safari 6.0.4 / OS X 10.8.4
Ja
Safari 7 / OS X 10.9 Ja
Safari 6/7/8 auf iOS 6.0.1 und höher Ja

Weitere Applikationen werden ich bei Gelegenheit addieren.

Server Support

Wenn ein Client den gewünschten Servernamen mit sendet, dann kann der Server natürlich das richtige Zertifikat an den Client senden, so er denn eines hat und er diese Funktion unterstützt.

Produkt SNI Nutzung
IIS 6, 7, 7.5 Nein. versteht kein SNI
IIS 8 (Windows 2012) SNI wird ausgewertet.
Web Application Proxy (Windows 2012R2) SNI wird ausgewertet.
ADFS 2012R2 (Windows 2012) SNI wird ausgewertet.
Apache 2.2.12 In Verbindung mit mod_ssl
Exchange 2013 OWA Nur mit IIS8 auf Windows 2012
Exchange 2010 OWA Nur mit IIS8 auf Windows 2012
Exchange IMAP Konnte noch keine Information dazu finden
Exchange POP3 Konnte noch keine Information dazu finden
Lync WebServices Nur mit IIS8 auf Windows 2012
OpenSSL ab 0.9.8f SNI kann aktiviert werden
ab 0.9.8j SNI ist per Default aktiviert
Lync Edge Server 2013 Nein. versteht kein SNI, sendet ausgehend aber SNI mit.

Bislang ist SNI natürlich primär ein Thema für Browser und Webserver. Sobald der Webserver SNI unterstützt, können auch die darauf aufsetzenden Skripte (PHP, Perl etc.) damit arbeiten. Interessanter wird es natürlich für andere Dienste und Protokolle, die z.B. nicht auf dem IIS basieren.

SNI Reverse Proxy

Auch wenn die verschiedenen Dienste z.B., noch kein SNI selbst unterstützen, so dürften die meisten Dienste sowieso nicht "ungeschützt" irgendwo rumstehen. Es steht also in der Regel ein Reverse Proxy davor, der die SSL-Verbindung annimmt, optional terminiert und nach hinten weiter gibt. Das kann ein TMG sein, der leider kein SNI unterstützt) oder ein WAP - Web Application Proxy, der SNI seit Windows 2012R2 schon kann. Aber auch andere Reverse Proxies können hier genutzt werden. Besonders interessant wird es, wenn diese Dienste nicht nur HTTP sondern beliebige SSL-Verbindungen weiter geben können. Und damit stehen wir beim Thema Loadbalancer, die SSL terminieren können. Hierbei sind aber drei Faktoren zu prüfen:

  • SNI bei eingehenden HTTP
    Die meisten Protokolle nutzen heute HTTPS, und speziell Loadbalancer terminieren den SSL-Tunnel um anhand der Inhalte dann die Lastverteilung zu optimieren. Eine Unterstützung an dieser Stelle ist natürlich primär.
  • SNI bei anderen Protokollen
    Aber auch andere Protokolle nutzen TLS, z.B. SIP (Lync Edge), SMTP etc. Auch hier könnte das "Sharen" von IP-Adressen relevant sein. Ein Loadbalancer darf hier natürlich kein "HTTP" sprechen, sondern eher macht eher ein NAT
  • SNI zum Backend
    Es kann ja sein, dass die veröffentlichten Server ebenfalls mehrere Zertifikat mit SNI nutzt, um mehrere Dienste zu unterscheiden. Wenn ein Loadbalancer nach "hinten" nun die Erreichbarkeit eines Dienstes prüft, muss hier natürlich als Client einen Hostnamen mitliefern, um den richtigen Backend-Service zu prüfen.

Ich versuche dies in einer Tabelle aktuell zu halten. Hinweise und Korrekturen sind herzlich willkommen.

Produkt SNI mit HTTP SNI mit ANY SNI zum Backend SNI Nutzung
TMG Nein Nein Nein Nein, SNI wird nicht beachtet.
WAP 2012R2 Ja Nein  

SNI wird ausgewertet

KEMP Ja

SNI wird ausgewertet (Ab Firmware 7.0-12a)

Selecting the require Server Name Identifier (SNI) hostname check box means that the hostname
will always be required to be sent in the TLS client hello message.
When Require SNI hostname is disabled, the first certificate in the list of Assigned Certificates as
a host header match is not found.
When Require SNI hostname is enabled, a certificate with a matching host name must be found,
otherwise the connection is dropped. This also supports wildcard certificates.
Quelle: SSL Accelerated Services Feature, Version 1.7, Description July 2014
http://kemptechnologies.com/files/downloads/documentation/7.0/Feature_Description/Feature_Description-SSL_Accelerated_Services.pdf

HAProxy Ja

Ab Version 1.5

F5 Ja Local Traffic Manager Ab Firmware 11.1
Citrix NetScaler Ja Ab Version 9.2 (9.3 Enhanced)
Barracuda Ja Support für Server Name Indication (SNI)
https://www.barracuda.com/blogs/pmblog?bid=818#.VDjvH1phtas.twitter
Nginx Ja     How To Set up Multiple SSL Certificates on One IP with Nginx on ubuntu 12.04
https://www.digitalocean.com/community/tutorials/how-to-set-up-multiple-ssl-certificates-on-one-ip-with-nginx-on-ubuntu-12-04

Dies ist nur eine Momentaufnahme zum Zeitpunkt der letzten Artikelüberarbeitung und keine vollständige Liste. Bitte Fragen Sie den Hersteller ihrer Lösung bezüglich SNI-Support

SNI und das Default Cert

Der Windows Server 2012R2 HTTP-Listener unterstützt die Konfiguration von SNI-Zertifikaten. Damit ist auch klar, dass nicht nur der der IIS8 sondern eben auch der Web Application Proxy sondern auch ADFS 2012R2 die Auswertung von SNI unterstützt. Allerdings kann dies zu unerwarteten Problemen mit Clients führen, die gar keinen Namen mitliefern.

Wenn der HTTP-Listener nämlich "nur" solche Daten annimmt, wenn ein Name im SNI-Feld mitkommt. dann bekommen Clients ohne SNI-Support eine Fehlermeldung. Dann sollten Sie zusätzlich ein "Default Zertifikat" installieren. Das geht per Kommandozeile

netsh http add sslcert ipport=0.0.0.0:443 certhash=thumprint appid={applicationguid}

Die ApplicationID muss man natürlich auch noch ermitteln. Hier schon mal die, die ich selbst einsetze.

Applikation ApplicationID
ADFS 2012R2 {5d89a20c-beab-4389-9447-324788eb944a}
Web Application Proxy {f955c070-e044-456c-ac00-e9e4275b3f04}

Den "Thumbprint" des Zertifikats können Sie in den Eigenschaften des Zertifikats abschreiben oder Sie nutzen einfach die PowerShell:

PS C:\> dir Cert:\LocalMachine\My

  Verzeichnis: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
FFC89CA9E33CCA397122EFE46B092201749FBBF9  CN=pc1.msxfaq.net
D48179D8A67F2E538F8ED645CC1AF5195F906F27  CN=PC1

Weitere Informationen finden Sie z.B. auf:

Weitere Links