SNI (Server Name Indication) ist eine TLS-Erweiterung, die es einem Client ermöglicht, den Hostnamen anzugeben, den er während des TLS-Handshakes erreichen möchte. Dies ermöglicht Proxys, TLS-Verbindungen für mehrere Domains, die auf einer einzigen IP-Adresse gehostet werden, korrekt weiterzuleiten oder zu terminieren.
Vor SNI benötigte ein Server für jedes SSL-Zertifikat eine eindeutige IP-Adresse, wenn mehrere sichere Websites auf demselben Server gehostet wurden. Diese Einschränkung entstand, weil der TLS-Handshake vor dem Senden des HTTP Host-Headers stattfand und den Server daran hinderte, zu wissen, welches Zertifikat er präsentieren sollte. SNI, spezifiziert in RFC 6066, löst dies, indem es den gewünschten Hostnamen in die ClientHello-Nachricht aufnimmt, wodurch der Server (oder Proxy) das korrekte Zertifikat und die entsprechende Konfiguration auswählen kann.
Wie SNI funktioniert
Der Client fügt den Ziel-Hostnamen in das extension_data-Feld der server_name-Erweiterung innerhalb der ClientHello-Nachricht ein. Dies geschieht, bevor verschlüsselte Daten ausgetauscht werden und bevor der Server sein Zertifikat präsentiert.
ClientHello
Version: TLS 1.2
Random: ...
Session ID: ...
Cipher Suites: ...
Extensions:
...
Server Name (SNI)
Server Name Type: host_name (0)
Server Name: example.com
...
Der Server oder ein intermediärer Proxy empfängt diese ClientHello-Nachricht und kann den Hostnamen example.com extrahieren. Diese Information wird dann verwendet, um zu bestimmen, welches TLS-Zertifikat präsentiert und wie die nachfolgende Verbindung weitergeleitet oder verarbeitet werden soll.
Proxy-Verarbeitung von SNI
Proxys interagieren mit SNI unterschiedlich, basierend auf ihrem Typ, Betriebsmodus und ob sie TLS-Terminierung oder Passthrough durchführen.
Transparente Proxys
Ein transparenter Proxy fängt Traffic ab, ohne dass der Client explizit für dessen Nutzung konfiguriert ist. Für TLS-Traffic arbeitet ein transparenter Proxy oft auf Layer 4 (TCP). Er leitet typischerweise den rohen TCP-Stream, einschließlich der ClientHello-Nachricht mit SNI, direkt an den Zielserver weiter.
- SNI-Sichtbarkeit: Ein transparenter Proxy kann die
ClientHello-Nachricht prüfen, um den SNI-Hostnamen zu extrahieren. Dies ermöglicht grundlegendes Routing, Protokollierung oder Filterregeln basierend auf der Ziel-Domain, auch wenn die Payload selbst verschlüsselt bleibt. - TLS-Terminierung: Transparente Proxys terminieren TLS für den Client typischerweise nicht, es sei denn, sie sind speziell für Deep Packet Inspection (DPI) oder Man-in-the-Middle (MITM)-Operationen konfiguriert, was das Vertrauen des Clients in die Root-CA des Proxys erfordert. In einem Standard-Transparent-Setup leitet der Proxy die
ClientHello-Nachricht an den Ursprungsserver weiter, der dann den TLS-Handshake direkt mit dem Client durchführt.
Forward-Proxys
Ein Forward-Proxy fungiert als Vermittler für Clients, die Ressourcen von externen Servern anfordern. Clients sind explizit für die Nutzung eines Forward-Proxys konfiguriert.
CONNECT-Methode
Für HTTPS-Traffic verwenden Clients typischerweise die HTTP CONNECT-Methode, um den Forward-Proxy anzuweisen, einen TCP-Tunnel zum Zielserver aufzubauen.
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Proxy-Connection: Keep-Alive
Nachdem die CONNECT-Anfrage erfolgreich war (Proxy antwortet mit HTTP/1.1 200 Connection established), initiiert der Client den TLS-Handshake direkt mit dem Zielserver durch den etablierten Tunnel.
- SNI-Sichtbarkeit (ohne Abfangen): In diesem Modus verarbeitet der Forward-Proxy den SNI-Wert aus der
ClientHello-Nachricht im Allgemeinen nicht, da er lediglich den rohen verschlüsselten TCP-Stream weiterleitet. DieCONNECT-Anfrage liefert den Ziel-Hostnamen, den der Proxy für das Routing verwendet. - TLS-Terminierung: Der Proxy terminiert TLS nicht; der TLS-Handshake findet Ende-zu-Ende zwischen Client und Ursprungsserver statt.
TLS-Abfangen (MITM)
Einige Forward-Proxys sind für TLS-Abfangen (auch bekannt als SSL-Inspektion oder MITM-Proxying) konfiguriert. Dies beinhaltet, dass der Proxy die TLS-Verbindung des Clients terminiert und eine neue TLS-Verbindung zum Ursprungsserver aufbaut.
- Client initiiert TLS-Handshake mit Proxy: Der Client sendet eine
ClientHelloan den Proxy. - Proxy extrahiert SNI: Der Proxy liest den SNI-Hostnamen aus der
ClientHello. - Proxy generiert Zertifikat: Unter Verwendung seines eigenen CA-Zertifikats (dem der Client vertraut) generiert der Proxy dynamisch ein Serverzertifikat für den SNI-Hostnamen.
- Proxy schließt Handshake mit Client ab: Der Proxy präsentiert dem Client das generierte Zertifikat.
- Proxy baut neue TLS-Verbindung zum Ursprung auf: Der Proxy initiiert einen neuen TLS-Handshake mit dem tatsächlichen Ursprungsserver, wobei er den extrahierten SNI-Hostnamen in seiner
ClientHelloverwendet. - Proxy entschlüsselt/verschlüsselt Traffic neu: Der Proxy entschlüsselt den Client-Traffic, inspiziert ihn und verschlüsselt ihn dann neu, bevor er ihn an den Ursprung sendet, und umgekehrt.
- SNI-Nutzung: SNI ist entscheidend für das TLS-Abfangen. Der Proxy verwendet den SNI-Wert, um:
- zu bestimmen, welchen Hostnamen er für den Client imitieren soll.
- zu bestimmen, welchen Hostnamen er vom Ursprungsserver anfordern soll.
- Sicherheitsimplikationen: Erfordert, dass der Client der Root-CA des Proxys vertraut. Dieser Modus ermöglicht dem Proxy volle Sichtbarkeit in den verschlüsselten Traffic.
Reverse-Proxys
Ein Reverse-Proxy sitzt vor einem oder mehreren Webservern und leitet Client-Anfragen an den entsprechenden Backend-Server weiter. Clients verbinden sich mit dem Reverse-Proxy, ohne die Backend-Architektur zu kennen.
- SNI-Nutzung: Wenn ein Client einen TLS-Handshake mit dem Reverse-Proxy initiiert, empfängt der Proxy die
ClientHello-Nachricht, die den SNI-Hostnamen enthält. Der Reverse-Proxy verwendet diesen SNI-Wert, um:- das korrekte Serverzertifikat auszuwählen, das dem Client präsentiert werden soll, wenn er mehrere Domains hostet.
- die Anfrage an den entsprechenden Backend-Server oder Anwendungspool weiterzuleiten.
- domänenspezifische Richtlinien (z. B. WAF-Regeln, Caching, Lastverteilung) anzuwenden.
- TLS-Terminierung: Reverse-Proxys terminieren fast immer TLS-Verbindungen von Clients. Sie entschlüsseln den Traffic, verarbeiten ihn und können ihn dann für die Kommunikation mit Backend-Servern neu verschlüsseln (Neuverschlüsselung oder Backend-TLS).
Beispiel: Nginx Reverse Proxy mit SNI
http {
# Standardserver für Anfragen ohne SNI oder für unbekanntes SNI
server {
listen 443 ssl default_server;
server_name _; # Catch-all
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
return 404;
}
# Backend für example.com
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location / {
proxy_pass https://backend_example_com;
proxy_ssl_server_name on; # SNI an Backend weiterleiten
}
}
# Backend für api.example.com
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/api.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/api.example.com.key;
location / {
proxy_pass https://backend_api_example_com;
proxy_ssl_server_name on; # SNI an Backend weiterleiten
}
}
}
In dieser Nginx-Konfiguration stimmt die server_name-Direktive mit dem vom Client präsentierten SNI überein. Nginx verwendet dann das entsprechende ssl_certificate und leitet die Anfrage an das angegebene proxy_pass-Backend weiter. proxy_ssl_server_name on stellt sicher, dass Nginx den SNI-Hostnamen beim Aufbau einer neuen TLS-Verbindung zum Backend einschließt.
SNI und Layer-4- vs. Layer-7-Proxys
Die Unterscheidung zwischen Layer-4- (TCP) und Layer-7- (Anwendung) Proxys beeinflusst auch die SNI-Verarbeitung.
-
Layer-4-Proxys: Arbeiten auf der TCP-Ebene. Sie können das
ClientHello-Paket prüfen, um SNI zu extrahieren, ohne den gesamten TLS-Stream zu entschlüsseln. Dies ermöglicht SNI-basiertes Routing oder Filtern, bevor der TLS-Handshake abgeschlossen ist, ohne TLS terminieren zu müssen. HAProxy im TCP-Modus kann dies leisten.listen https_frontend bind *:443 mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } tcp-request content track-sc0 src # Route basierend auf SNI use_backend backend_example_com if { req_ssl_sni -i example.com } use_backend backend_api_example_com if { req_ssl_sni -i api.example.com } default_backend backend_default
Diese HAProxy-Konfiguration verwendetreq_ssl_sni, um das SNI aus derClientHellozu prüfen und die TCP-Verbindung entsprechend weiterzuleiten, ohne TLS selbst zu terminieren. -
Layer-7-Proxys: Arbeiten auf der Anwendungsschicht (z. B. HTTP/HTTPS). Sie müssen TLS terminieren, um auf Anwendungsschicht-Header (wie HTTP Host, URL-Pfad usw.) zugreifen zu können. Nach der TLS-Terminierung verwenden sie das SNI aus der initialen
ClientHello, um das korrekte Serverzertifikat auszuwählen, und verarbeiten dann die entschlüsselte HTTP-Anfrage. Reverse-Proxys sind typischerweise L7-Proxys. Forward-Proxys, die TLS-Abfangen durchführen, sind ebenfalls L7.
Vergleich: SNI-Verarbeitungsmodi von Proxys
| Merkmal | Transparenter Proxy (L4 Passthrough) | Forward-Proxy (CONNECT, kein MITM) | Forward-Proxy (TLS-Abfangen/MITM) | Reverse-Proxy (TLS-Terminierung) |
|---|---|---|---|---|
| Client-TLS terminiert bei | Ursprungsserver | Ursprungsserver | Proxy | Proxy |
| Proxy-TLS terminiert bei | N/A (Passthrough) | N/A (Passthrough) | Ursprungsserver | N/A (initiiert neu bei Backend-TLS) |
| SNI-Sichtbarkeit für Proxy | Ja (Klartext in ClientHello) | Nein (nach CONNECT) | Ja (Klartext in ClientHello) | Ja (Klartext in ClientHello) |
| SNI-Nutzung durch Proxy | Routing, Protokollierung, grundlegende Filterung | Nicht direkt aus ClientHello | Zertifikatserstellung, Ursprungsauswahl | Zertifikatsauswahl, Routing, Richtliniendurchsetzung |
| Proxy entschlüsselt Traffic | Nein | Nein | Ja | Ja |
| Anforderung an Client-Vertrauen | Keine | Keine | Root-CA des Proxys | Zertifikat des Ursprungs (vom Proxy präsentiert) |
Sicherheits- und Datenschutzaspekte
SNI wird konstruktionsbedingt im Klartext innerhalb der ClientHello-Nachricht übertragen. Dies bedeutet, dass Netzwerk-Intermediäre, einschließlich Proxys und ISPs, beobachten können, mit welchem Hostnamen ein Client versucht, sich zu verbinden, auch wenn der Rest der TLS-Kommunikation verschlüsselt ist.
Diese Klartext-Exposition hat Datenschutzimplikationen. Um dies zu adressieren, hat die IETF Encrypted SNI (ESNI) entwickelt, das sich zu Encrypted Client Hello (ECH) weiterentwickelt. ESNI/ECH verschlüsselt die Server Name-Erweiterung innerhalb der ClientHello-Nachricht und macht sie für passive Beobachter undurchsichtig.
- Auswirkungen auf Proxys: ESNI/ECH verändert die Funktionsweise von Proxys (insbesondere L4-Proxys oder solche, die SNI-basiertes Routing ohne vollständige TLS-Terminierung durchführen) erheblich. Wenn das SNI verschlüsselt ist, kann der Proxy es nicht für Klartext-Routing-Entscheidungen verwenden. Proxys, die ESNI/ECH unterstützen, müssten am Schlüsselaustausch teilnehmen oder sich auf andere Mechanismen (z. B. IP-Adresse, DNS) für das initiale Routing verlassen oder ECH entschlüsseln, wenn sie der vorgesehene ECH-Endpunkt sind. Für TLS-terminierende Proxys (wie Reverse-Proxys oder MITM-Forward-Proxys) müssten sie das ECH weiterhin entschlüsseln, um den beabsichtigten Hostnamen für die Zertifikatsauswahl und das Routing zu erfahren.