SNI (Server Name Indication), istemcinin TLS el sıkışması sırasında ulaşmaya çalıştığı hostname'i belirtmesini sağlayan bir TLS uzantısıdır; böylece proxy'ler tek bir IP adresinde barındırılan birden fazla alan adı için TLS bağlantılarını doğru şekilde yönlendirebilir veya sonlandırabilir.
SNI'dan önce, aynı sunucuda birden fazla güvenli web sitesi barındırılıyorsa sunucu her SSL sertifikası için ayrı bir IP adresi gerektiriyordu. Bu kısıtlama, TLS el sıkışmasının HTTP Host başlığı gönderilmeden önce gerçekleşmesinden ve sunucunun hangi sertifikayı sunacağını bilememesinden kaynaklanıyordu. RFC 6066'da tanımlanan SNI, istenen hostname'i ClientHello mesajına ekleyerek bunu çözer ve sunucunun (ya da proxy'nin) doğru sertifika ve yapılandırmayı seçmesine olanak tanır.
SNI nasıl çalışır
İstemci, hedef hostname'i ClientHello mesajı içindeki server_name uzantısının extension_data alanına ekler. Bu, herhangi bir şifreli veri alışverişinden ve sunucunun sertifikasını sunmasından önce gerçekleşir.
ClientHello
Version: TLS 1.2
Random: ...
Session ID: ...
Cipher Suites: ...
Extensions:
...
Server Name (SNI)
Server Name Type: host_name (0)
Server Name: example.com
...
Sunucu veya aradaki bir proxy bu ClientHello mesajını alır ve example.com hostname'ini çıkarabilir. Bu bilgi daha sonra hangi TLS sertifikasının sunulacağını ve devam eden bağlantının nasıl yönlendirileceğini veya işleneceğini belirlemek için kullanılır.
Proxy'lerin SNI'ı ele alışı
Proxy'ler SNI ile tiplerine, çalışma moduna ve TLS sonlandırma mı yoksa passthrough mu yaptıklarına göre farklı şekilde etkileşir.
Şeffaf proxy'ler
Şeffaf bir proxy, istemci onu kullanmak üzere açıkça yapılandırılmadan trafiği yakalar. TLS trafiği için şeffaf proxy genellikle Katman 4'te (TCP) çalışır. Tipik olarak ham TCP akışını, SNI içeren ClientHello mesajı da dahil, doğrudan hedef sunucuya iletir.
- SNI görünürlüğü: Şeffaf bir proxy, SNI hostname'ini çıkarmak için
ClientHellomesajını inceleyebilir. Bu, yük şifreli kalsa bile hedef alan adına dayalı temel yönlendirme, günlükleme veya filtreleme kurallarına imkân verir. - TLS sonlandırma: Şeffaf proxy'ler, derin paket incelemesi (DPI) veya man-in-the-middle (MITM) işlemleri için özellikle yapılandırılmadıkça istemci için TLS'i genellikle sonlandırmaz; bu işlemler istemcinin proxy'nin kök CA'sına güvenmesini gerektirir. Standart şeffaf kurulumda proxy
ClientHellomesajını kaynak sunucuya iletir ve TLS el sıkışmasını kaynak sunucu doğrudan istemciyle yapar.
Forward proxy'ler
Forward proxy, dış sunuculardan kaynak isteyen istemciler için aracı görevi görür. İstemciler forward proxy'yi kullanmak üzere açıkça yapılandırılır.
CONNECT yöntemi
HTTPS trafiği için istemciler genellikle HTTP CONNECT yöntemini kullanarak forward proxy'ye hedef sunucuya bir TCP tüneli kurmasını söyler.
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Proxy-Connection: Keep-Alive
CONNECT isteği başarılı olduktan sonra (proxy HTTP/1.1 200 Connection established yanıtını verir), istemci kurulan tünel üzerinden doğrudan hedef sunucuyla TLS el sıkışmasını başlatır.
- SNI görünürlüğü (araya girme olmadan): Bu modda forward proxy, yalnızca ham şifreli TCP akışını aktardığı için
ClientHellomesajındaki SNI değerini genellikle işlemez. Hedef hostname'iCONNECTisteği sağlar ve proxy bunu yönlendirme için kullanır. - TLS sonlandırma: Proxy TLS'i sonlandırmaz; TLS el sıkışması istemci ile kaynak sunucu arasında uçtan uca gerçekleşir.
TLS araya girme (MITM)
Bazı forward proxy'ler TLS araya girme (SSL inceleme veya MITM proxy olarak da bilinir) için yapılandırılır. Bu, proxy'nin istemcinin TLS bağlantısını sonlandırıp kaynak sunucuya yeni bir TLS bağlantısı kurmasını içerir.
- İstemci proxy ile TLS el sıkışmasını başlatır: İstemci proxy'ye bir
ClientHellogönderir. - Proxy SNI'ı çıkarır: Proxy,
ClientHelloiçindeki SNI hostname'ini okur. - Proxy sertifika üretir: Kendi CA sertifikasını kullanarak (istemcinin güvendiği), proxy SNI hostname'i için dinamik olarak bir sunucu sertifikası üretir.
- Proxy istemciyle el sıkışmasını tamamlar: Proxy, ürettiği sertifikayı istemciye sunar.
- Proxy kaynağa yeni bir TLS bağlantısı kurar: Proxy, çıkardığı SNI hostname'ini kendi
ClientHellomesajında kullanarak gerçek kaynak sunucuyla yeni bir TLS el sıkışması başlatır. - Proxy trafiği çözer/yeniden şifreler: Proxy istemci trafiğini çözer, inceler ve kaynağa göndermeden önce yeniden şifreler; ters yönde de aynısını yapar.
- SNI kullanımı: SNI, TLS araya girme için kritiktir. Proxy, SNI değerini şunlar için kullanır:
- İstemciye karşı hangi hostname'i taklit edeceğini belirlemek.
- Kaynak sunucudan hangi hostname'i isteyeceğini belirlemek.
- Güvenlik etkileri: İstemcinin proxy'nin kök CA'sına güvenmesini gerektirir. Bu mod proxy'ye şifreli trafiğe tam görünürlük sağlar.
Reverse proxy'ler
Reverse proxy, bir veya daha fazla web sunucusunun önünde durur ve istemci isteklerini uygun arka uç sunucusuna yönlendirir. İstemciler reverse proxy'ye bağlanır ve arka uç mimarisinden habersizdir.
- SNI kullanımı: İstemci reverse proxy ile TLS el sıkışması başlattığında, proxy SNI hostname'ini içeren
ClientHellomesajını alır. Reverse proxy bu SNI değerini şunlar için kullanır:- Birden fazla alan adı barındırıyorsa istemciye sunulacak doğru sunucu sertifikasını seçmek.
- İsteği uygun arka uç sunucusuna veya uygulama havuzuna yönlendirmek.
- Alan adına özgü politikaları uygulamak (örneğin WAF kuralları, önbellekleme, yük dengeleme).
- TLS sonlandırma: Reverse proxy'ler istemcilerden gelen TLS bağlantılarını neredeyse her zaman sonlandırır. Trafiği çözer, işler ve ardından arka uç sunucularla iletişim için yeniden şifreleyebilir (yeniden şifreleme veya arka uç TLS).
Örnek: SNI ile Nginx reverse proxy
http {
# Default server for requests without SNI or for unknown 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 for 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; # Pass SNI to backend
}
}
# Backend for 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; # Pass SNI to backend
}
}
}
Bu Nginx yapılandırmasında server_name yönergesi istemcinin sunduğu SNI ile eşleşir. Nginx ardından ilgili ssl_certificate'ı kullanır ve isteği belirtilen proxy_pass arka ucuna yönlendirir. proxy_ssl_server_name on, Nginx'in arka uca yeni bir TLS bağlantısı kurarken SNI hostname'ini eklemesini sağlar.
SNI ve Katman 4 ile Katman 7 proxy'leri
Katman 4 (TCP) ve Katman 7 (uygulama) proxy'leri arasındaki ayrım da SNI'ın ele alınışını etkiler.
-
Katman 4 proxy'leri: TCP seviyesinde çalışır. Tüm TLS akışını çözmeden
ClientHellopaketini inceleyip SNI'ı çıkarabilirler. Bu, TLS'i sonlandırmaya gerek kalmadan, el sıkışma tamamlanmadan önce SNI tabanlı yönlendirme veya filtreleme yapılmasına imkân verir. TCP modundaki HAProxy bunu yapabilir.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 based on 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
Bu HAProxy yapılandırması,ClientHelloiçindeki SNI'ı incelemek içinreq_ssl_snikullanır ve TLS'i kendisi sonlandırmadan TCP bağlantısını buna göre yönlendirir. -
Katman 7 proxy'leri: Uygulama katmanında çalışır (örneğin HTTP/HTTPS). Uygulama katmanı başlıklarına (HTTP Host, URL yolu vb.) erişmek için TLS'i sonlandırmaları gerekir. TLS'i sonlandırdıklarında, doğru sunucu sertifikasını seçmek için ilk
ClientHelloiçindeki SNI'ı kullanır ve ardından çözülmüş HTTP isteğini işlemeye geçerler. Reverse proxy'ler tipik olarak L7 proxy'lerdir. TLS araya girme yapan forward proxy'ler de L7'dir.
Karşılaştırma: proxy SNI ele alma modları
| Özellik | Şeffaf proxy (L4 passthrough) | Forward proxy (CONNECT, MITM yok) | Forward proxy (TLS araya girme/MITM) | Reverse proxy (TLS sonlandırma) |
|---|---|---|---|---|
| İstemci TLS'i şurada sonlanır | Kaynak sunucu | Kaynak sunucu | Proxy | Proxy |
| Proxy TLS'i şurada sonlanır | Yok (passthrough) | Yok (passthrough) | Kaynak sunucu | Yok (arka uç TLS varsa yenisini başlatır) |
| Proxy için SNI görünürlüğü | Evet (ClientHello'da açık metin) | Hayır (CONNECT sonrası) | Evet (ClientHello'da açık metin) | Evet (ClientHello'da açık metin) |
| Proxy'nin SNI kullanımı | Yönlendirme, günlükleme, temel filtreleme | Doğrudan ClientHello'dan değil | Sertifika üretimi, kaynak seçimi | Sertifika seçimi, yönlendirme, politika uygulama |
| Proxy trafiği çözer mi | Hayır | Hayır | Evet | Evet |
| İstemci güven gereksinimi | Yok | Yok | Proxy'nin kök CA'sı | Kaynağın sertifikası (proxy tarafından sunulur) |
Güvenlik ve gizlilik değerlendirmeleri
SNI, tasarımı gereği ClientHello mesajı içinde açık metin olarak iletilir. Bu, proxy'ler ve ISP'ler dahil ağdaki aracıların, TLS iletişiminin geri kalanı şifreli olsa bile istemcinin hangi hostname'e bağlanmaya çalıştığını görebileceği anlamına gelir.
Bu açık metin ifşası gizlilik açısından sonuçlar doğurur. IETF bunu ele almak için Encrypted SNI (ESNI) geliştirdi ve bu, Encrypted Client Hello (ECH) biçimine evriliyor. ESNI/ECH, ClientHello mesajındaki Server Name uzantısını şifreleyerek pasif gözlemciler için okunamaz hale getirir.
- Proxy'lere etkisi: ESNI/ECH, proxy'lerin (özellikle L4 proxy'lerin veya tam TLS sonlandırma olmadan SNI tabanlı yönlendirme yapanların) çalışma biçimini önemli ölçüde değiştirir. SNI şifreliyse proxy bunu açık metin yönlendirme kararları için kullanamaz. ESNI/ECH destekleyebilen proxy'lerin anahtar değişimine katılması, ilk yönlendirme için başka mekanizmalara (örneğin IP adresi, DNS) dayanması ya da hedeflenen ECH uç noktasıysa ECH'yi çözmesi gerekir. TLS sonlandıran proxy'lerin (reverse proxy'ler veya MITM forward proxy'ler gibi) sertifika seçimi ve yönlendirme için hedeflenen hostname'i öğrenmek üzere yine de ECH'yi çözmesi gerekir.
