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.
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
...