SNI (Server Name Indication) é uma extensão do TLS que permite ao cliente indicar o hostname que está tentando acessar durante o handshake TLS, possibilitando que proxies roteiem ou terminem corretamente conexões TLS para múltiplos domínios hospedados em um único endereço IP.
Antes do SNI, um servidor exigia um endereço IP exclusivo para cada certificado SSL quando vários sites seguros eram hospedados no mesmo servidor. Essa limitação existia porque o handshake TLS ocorria antes do envio do cabeçalho HTTP Host, impedindo o servidor de saber qual certificado apresentar. O SNI, especificado na RFC 6066, resolve isso incluindo o hostname desejado na mensagem ClientHello, permitindo que o servidor (ou proxy) selecione o certificado e a configuração corretos.
Como o SNI funciona
O cliente inclui o hostname de destino no campo extension_data da extensão server_name dentro da mensagem ClientHello. Isso ocorre antes de qualquer troca de dados criptografados e antes de o servidor apresentar seu certificado.
ClientHello
Version: TLS 1.2
Random: ...
Session ID: ...
Cipher Suites: ...
Extensions:
...
Server Name (SNI)
Server Name Type: host_name (0)
Server Name: example.com
...
O servidor ou um proxy intermediário recebe esse ClientHello e pode extrair o hostname example.com. Essa informação é então usada para determinar qual certificado TLS apresentar e como rotear ou processar a conexão subsequente.
Tratamento do SNI por proxies
Os proxies interagem com o SNI de formas diferentes conforme seu tipo, modo de operação e se realizam terminação TLS ou passthrough.
Proxies transparentes
Um proxy transparente intercepta o tráfego sem que o cliente esteja explicitamente configurado para usá-lo. Para tráfego TLS, um proxy transparente frequentemente opera na Camada 4 (TCP). Normalmente ele encaminha o fluxo TCP bruto, incluindo a mensagem ClientHello com o SNI, diretamente para o servidor de destino.
- Visibilidade do SNI: um proxy transparente pode inspecionar a mensagem
ClientHellopara extrair o hostname do SNI. Isso permite roteamento básico, registro em log ou regras de filtragem baseadas no domínio de destino, mesmo que o payload em si permaneça criptografado. - Terminação TLS: proxies transparentes normalmente não terminam o TLS para o cliente, a menos que estejam especificamente configurados para inspeção profunda de pacotes (DPI) ou operações man-in-the-middle (MITM), o que exige que o cliente confie na CA raiz do proxy. Em uma configuração transparente padrão, o proxy repassa o
ClientHelloao servidor de origem, que então realiza o handshake TLS diretamente com o cliente.
Proxies diretos (forward)
Um forward proxy atua como intermediário para clientes que solicitam recursos de servidores externos. Os clientes são explicitamente configurados para usar um forward proxy.
Método CONNECT
Para tráfego HTTPS, os clientes normalmente usam o método HTTP CONNECT para instruir o forward proxy a estabelecer um túnel TCP até o servidor de destino.
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Proxy-Connection: Keep-Alive
Depois que a requisição CONNECT é bem-sucedida (o proxy responde com HTTP/1.1 200 Connection established), o cliente inicia o handshake TLS diretamente com o servidor de destino através do túnel estabelecido.
- Visibilidade do SNI (sem interceptação): nesse modo, o forward proxy geralmente não processa o valor do SNI da mensagem
ClientHello, pois está apenas repassando o fluxo TCP criptografado bruto. A requisiçãoCONNECTfornece o hostname de destino, que o proxy usa para roteamento. - Terminação TLS: o proxy não termina o TLS; o handshake TLS ocorre fim a fim entre o cliente e o servidor de origem.
Interceptação TLS (MITM)
Alguns forward proxies são configurados para interceptação TLS (também conhecida como inspeção SSL ou proxy MITM). Isso envolve o proxy terminando a conexão TLS do cliente e estabelecendo uma nova conexão TLS com o servidor de origem.
- O cliente inicia o handshake TLS com o proxy: o cliente envia um
ClientHelloao proxy. - O proxy extrai o SNI: o proxy lê o hostname do SNI no
ClientHello. - O proxy gera um certificado: usando seu próprio certificado de CA (confiável para o cliente), o proxy gera dinamicamente um certificado de servidor para o hostname do SNI.
- O proxy conclui o handshake com o cliente: o proxy apresenta o certificado gerado ao cliente.
- O proxy estabelece uma nova conexão TLS com a origem: o proxy inicia um novo handshake TLS com o servidor de origem real, usando o hostname do SNI extraído em seu
ClientHello. - O proxy descriptografa/recriptografa o tráfego: o proxy descriptografa o tráfego do cliente, inspeciona-o e então o recriptografa antes de enviá-lo à origem, e vice-versa.
- Uso do SNI: o SNI é crucial para a interceptação TLS. O proxy usa o valor do SNI para:
- Determinar qual hostname personificar para o cliente.
- Determinar qual hostname solicitar ao servidor de origem.
- Implicações de segurança: exige que o cliente confie na CA raiz do proxy. Esse modo dá ao proxy visibilidade total do tráfego criptografado.
Proxies reversos
Um reverse proxy fica à frente de um ou mais servidores web, direcionando as requisições dos clientes ao servidor de backend apropriado. Os clientes se conectam ao reverse proxy, sem conhecer a arquitetura de backend.
- Uso do SNI: quando um cliente inicia um handshake TLS com o reverse proxy, o proxy recebe a mensagem
ClientHellocontendo o hostname do SNI. O reverse proxy usa esse valor de SNI para:- Selecionar o certificado de servidor correto a apresentar ao cliente, caso hospede múltiplos domínios.
- Rotear a requisição ao servidor de backend ou pool de aplicação apropriado.
- Aplicar políticas específicas do domínio (por exemplo, regras de WAF, cache, balanceamento de carga).
- Terminação TLS: reverse proxies quase sempre terminam as conexões TLS dos clientes. Eles descriptografam o tráfego, processam-no e depois podem recriptografá-lo para a comunicação com os servidores de backend (recriptografia, ou TLS de backend).
Exemplo: reverse proxy Nginx com SNI
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
}
}
}
Nessa configuração do Nginx, a diretiva server_name corresponde ao SNI apresentado pelo cliente. O Nginx então usa o ssl_certificate correspondente e roteia a requisição para o backend especificado em proxy_pass. O proxy_ssl_server_name on garante que o Nginx inclua o hostname do SNI ao estabelecer uma nova conexão TLS com o backend.
SNI e proxies de Camada 4 vs. Camada 7
A distinção entre proxies de Camada 4 (TCP) e Camada 7 (aplicação) também influencia o tratamento do SNI.
-
Proxies de Camada 4: operam no nível TCP. Podem inspecionar o pacote
ClientHellopara extrair o SNI sem descriptografar todo o fluxo TLS. Isso permite roteamento ou filtragem baseados em SNI antes de o handshake TLS ser concluído, sem precisar terminar o TLS. O HAProxy em modo TCP consegue fazer isso.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
Essa configuração do HAProxy usareq_ssl_snipara inspecionar o SNI doClientHelloe rotear a conexão TCP de acordo, sem terminar o TLS. -
Proxies de Camada 7: operam na camada de aplicação (por exemplo, HTTP/HTTPS). Precisam terminar o TLS para acessar cabeçalhos da camada de aplicação (como o Host HTTP, o caminho da URL etc.). Ao terminar o TLS, usam o SNI do
ClientHelloinicial para selecionar o certificado de servidor correto e depois processam a requisição HTTP descriptografada. Reverse proxies são tipicamente proxies L7. Forward proxies que fazem interceptação TLS também são L7.
Comparação: modos de tratamento de SNI por proxies
| Recurso | Proxy transparente (passthrough L4) | Forward proxy (CONNECT, sem MITM) | Forward proxy (interceptação TLS/MITM) | Reverse proxy (terminação TLS) |
|---|---|---|---|---|
| TLS do cliente termina em | Servidor de origem | Servidor de origem | Proxy | Proxy |
| TLS do proxy termina em | N/A (passthrough) | N/A (passthrough) | Servidor de origem | N/A (inicia nova se houver TLS de backend) |
| Visibilidade do SNI para o proxy | Sim (em texto claro no ClientHello) | Não (após o CONNECT) | Sim (em texto claro no ClientHello) | Sim (em texto claro no ClientHello) |
| Uso do SNI pelo proxy | Roteamento, logs, filtragem básica | Não diretamente do ClientHello | Geração de certificado, seleção de origem | Seleção de certificado, roteamento, aplicação de políticas |
| Proxy descriptografa o tráfego | Não | Não | Sim | Sim |
| Requisito de confiança do cliente | Nenhum | Nenhum | CA raiz do proxy | Certificado da origem (apresentado pelo proxy) |
Considerações de segurança e privacidade
O SNI, por definição, é transmitido em texto claro dentro da mensagem ClientHello. Isso significa que intermediários de rede, incluindo proxies e ISPs, podem observar a qual hostname um cliente está tentando se conectar, mesmo que o restante da comunicação TLS esteja criptografado.
Essa exposição em texto claro tem implicações de privacidade. Para tratar disso, o IETF desenvolveu o Encrypted SNI (ESNI), que está evoluindo para o Encrypted Client Hello (ECH). ESNI/ECH criptografa a extensão Server Name dentro da mensagem ClientHello, tornando-a opaca para observadores passivos.
- Impacto sobre proxies: ESNI/ECH muda significativamente a operação dos proxies (especialmente os de L4 ou os que fazem roteamento baseado em SNI sem terminação TLS completa). Se o SNI estiver criptografado, o proxy não pode usá-lo para decisões de roteamento em texto claro. Proxies capazes de suportar ESNI/ECH precisariam participar da troca de chaves ou recorrer a outros mecanismos (por exemplo, endereço IP, DNS) para o roteamento inicial, ou descriptografar o ECH se forem o endpoint ECH pretendido. Para proxies que terminam TLS (como reverse proxies ou forward proxies MITM), ainda seria necessário descriptografar o ECH para descobrir o hostname pretendido para seleção de certificado e roteamento.
