IDEA I/O home  | about  | cheat sheets  | github

Server Name Indication

Jedem Informatiker ist heute bekannt, dass die Network Adress Translation (NAT) dazu beigetragen hat die IPv4 Adressknappheit zu verzögern. Die zweite Technologie die dies ermöglicht hat, nämlich die Server Name Indication (SNI) ist weniger bekannt.

Um zu verstehen wie SNI funktioniert, muss man sich zuerst den HTTPS Verbindungsaufbau einmal genauer anschauen. Bei HTTPS werden die HTTP Packete im Transport Layer Security Standard (TLS) enkapsuliert. Der TLS Verbindungsaufbau und der SSL Handshake werden also vor dem HTTP Verbindungsaufbau ausgeführt.

Verbindungsaufbau HTTP:

------ (1) HTTP Request ------------->        
Client              Server
<----- (2) HTTP Response -------------  

Verbindungsaufbau HTTPS:

------ (1) TLS Handshake ------------->       
<----- (2) TLS Handshake -------------  
Client              Server
------ (3) HTTP Request ------------->        
<----- (4) HTTP Response -------------  

Der Client teilt dem HTTP Server mit dem HTTP Parameter Hostheader mit, welche Seite des Servers er gerne abrufen möchte. Ruft man z.B. die Website www.google.ch mit cURL auf, sieht das so aus:

GET / HTTP/1.1
User-Agent: curl/7.30.0
Host: www.google.ch
Accept: */*

Damit weiss der Server, dass er die Website www.google.ch ausliefern soll.

Mit dem HTTPS Protokoll gibt es aber nun das folgende Problem. Da der zuerst der TLS Handshake stattfindet, weiss der Server zu diesem Zeitpunkt noch gar nicht, welche Website der Client abrufen will. Er kann den SSL Handshake nicht mit dem entsprechenden Zertifikat der Website ausführen, was zu einem Zertifikatfehler führen wird.

Der Server Name Indicator ist nun der Parameter, mit welchem dem HTTPS Server bereits im TLS Handshake mitgeteilt wird, um welche Website es geht. Der HTTP Server empfängt diese Information also zwei mal. Einmal per Hostheader im HTTP Protokoll und einmal per Server Name Indication im TLS Protokoll.

Den SNI ist im Standard RFC 6066 definiert und existiert seit 2003. Vor dem SNI war es nötig, pro HTTPS Website eine eigene IP Adresse zu verwenden.

SNI an einem Beispiel (google.ch)

Am Beispiel von google.ch läst sich SNI schön an einem Beispiel nachvollziehen. Ruft man die Website mit openssl und ohne SNI auf, erhält man als Antwort in der Certificate chain das Zertifikat von google .com. Weil der Server noch nicht weiss, welche Website er ausliefern soll, liefert er sein Standard Zertifikat aus.

$ openssl s_client -connect www.google.ch:443 
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google
    Inc/CN=google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
...

Ruft man die Website mit dem SNI Parameter auf, ist das Zertifikat von google .ch enthalten.

$ openssl s_client -connect www.google.ch:443 \
-servername www.google.ch
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain 
View/O=Google Inc/CN=*.google.ch
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
...