Quando um reverse proxy fica na frente de aplicações HTTPS, ele precisa decidir o que fazer com a sessão TLS que chega do cliente. Essa escolha tem consequências: ela define se o proxy consegue ver o tráfego e agir sobre ele, se os dados seguem criptografados no trecho curto até o backend e quanto trabalho criptográfico o proxy vai ter. Há exatamente três opções, e todo load balancer (o balanceador de carga) e todo (application delivery controller, o controlador de entrega de aplicações) oferece alguma combinação delas.

O que todo TLS de entrada num reverse proxy tem em comum é a direção do certificado. Como o proxy está na frente dos servidores, ele apresenta aos clientes o certificado do servidor (ou um certificado válido para o mesmo hostname). O cliente está se conectando a www.example.com e precisa ver um certificado de www.example.com; o fato de quem termina o TLS ser um load balancer, e não o servidor web de origem, fica invisível para o cliente, e é para ser assim mesmo. É o oposto de um forward proxy de saída, que forja certificados para destinos que não são dele, assunto do artigo sobre SSL forward proxy.

Origens: o handshake era caro demais para rodar em todo servidor

A terminação do TLS de entrada começou como uma decisão econômica, e não de segurança. As operações de chave pública eram tão caras que fazê-las em cada servidor de aplicação desperdiçava capacidade que poderia estar atendendo requisições; por isso, o trabalho foi para um equipamento dedicado só a isso, muitas vezes com aceleração em hardware, e os servidores atrás dele voltaram a falar em texto claro.

Esse motivo original quase desapareceu: os processadores modernos fazem o handshake (o aperto de mão do TLS) a um custo baixo, e o argumento do custo já não decide nada sozinho. O que manteve o modelo foi todo o resto em que o ponto de terminação se mostrou útil: um lugar só para guardar os certificados, um só para renová-los, um só para impor as versões de protocolo e a política de cifras, e um só capaz de ler a requisição o suficiente para roteá-la.

Então a pergunta deixou de ser se o TLS deve ser terminado e passou a ser o que acontece depois: texto claro, criptografia de novo, ou nenhuma terminação.

Offload: terminar e seguir em texto claro

No SSL offload (também chamado de terminação SSL), o proxy completa o handshake TLS com o cliente, descriptografa o tráfego e o encaminha ao backend como HTTP puro. A conexão entre o proxy e o servidor não tem criptografia.

É a opção com mais visibilidade e menos custo para o backend. Como o tráfego está em texto claro no proxy, tudo o que fica acima do TLS está disponível: o proxy pode rotear por URL, aplicar um (web application firewall), inserir cookies de persistência, acrescentar o X-Forwarded-For, fazer cache e reescrever conteúdo. A criptografia assimétrica do handshake, que é a parte cara, e qualquer aceleração em hardware ficam num lugar só, o proxy, e os servidores de backend deixam de fazer TLS. O preço é que o tráfego passa sem criptografia entre o proxy e os servidores, o que só é aceitável quando esse caminho é confiável, normalmente um segmento controlado do data center. Em ambientes com exigência de compliance de criptografia em trânsito de ponta a ponta, o offload puro em geral não é permitido.

Bridging: terminar e criptografar de novo

No SSL bridging (também chamado de SSL re-encryption ou, em algumas plataformas, de full proxy TLS), o proxy termina a sessão TLS do cliente, descriptografa, faz o seu trabalho de camada 7, abre uma segunda sessão TLS até o backend e criptografa de novo antes de encaminhar. São dois trechos criptografados, com um breve momento em texto claro dentro do proxy, que é onde a inspeção e as políticas acontecem.

O bridging mantém toda a visibilidade e o controle do offload, porque o proxy continua descriptografando, e ainda devolve a criptografia ao trecho entre o proxy e o backend. É por essa combinação que ele é a escolha comum em ambientes regulados: o WAF continua vendo as requisições, a persistência e o roteamento continuam funcionando, e mesmo assim nenhum dado da aplicação atravessa a rede em texto claro. Os dois trechos são sessões TLS independentes, então podem usar certificados, cipher suites e versões de protocolo diferentes; o lado do cliente pode exigir uma cipher suite moderna e com forward secrecy, enquanto o lado do backend usa o que os servidores internos suportarem. O preço é o maior trabalho criptográfico das três opções: o proxy faz dois handshakes por conexão e criptografa nos dois sentidos.

Passthrough: encaminhar o tráfego ainda criptografado

No SSL passthrough, o proxy não termina o TLS. Ele encaminha o fluxo TCP criptografado direto para um backend, que completa o handshake TLS com o cliente, de ponta a ponta. O proxy nunca tem a chave privada e nunca vê texto claro.

O passthrough é, na verdade, um comportamento de camada 4 que só tem TLS no nome, e herda as características do proxy TCP: é rápido, não depende do protocolo e não enxerga o conteúdo. O proxy não pode aplicar um WAF, não pode rotear por URL e não pode inserir cookies, porque não consegue ler a requisição. O que ele ainda consegue fazer é rotear pelo Server Name Indication, porque o vai em texto claro no ClientHello, antes de a criptografia começar; um proxy em passthrough espia esse hostname para escolher o pool de backend certo, sem descriptografar mais nada. O passthrough é a escolha certa quando a criptografia de ponta a ponta até o backend é obrigatória e o proxy não precisa inspecionar nada, ou quando o próprio backend precisa terminar o TLS (por exemplo, para fazer a sua própria autenticação por certificado de cliente).

Como escolher entre as três, sem rodeios

O offload é a escolha certa quando a rede entre o proxy e os servidores é de fato sua e as regras de compliance permitem. O trecho em texto claro é curto, e a simplicidade de operação é real.

O bridging é a escolha certa quando não é o caso, e custa o dobro em criptografia, mais uma segunda decisão de confiança: o proxy precisa validar o certificado do servidor, do lado upstream, e, se não validar, a criptografia é só enfeite. É a mesma armadilha da interceptação de saída: criptografar de novo até um servidor que você não autenticou não prova nada.

O passthrough é a escolha certa quando a chave não pode sair da aplicação, ou quando o cliente se autentica com certificado. O preço é tudo o que o proxy poderia ter feito: nada de roteamento por conteúdo, nada de inserção de header (cabeçalho), nada de observabilidade por requisição, e health checks (as verificações de saúde) reduzidos a saber se a porta responde.

O que quebra na prática

O endereço do cliente some. O servidor vê o proxy. Para recuperar o endereço, é preciso um header inserido pelo proxy, e a aplicação tem de ser configurada para confiar nesse header vindo exatamente desse proxy e de mais ninguém: um header que qualquer cliente também pode enviar não serve de prova.

Os certificados vencem numa data que alguém poderia ter lido com um ano de antecedência. Centralizar os certificados facilita a renovação e faz com que um esquecimento afete tudo de uma vez.

A política se afasta da realidade. O proxy negocia uma cipher suite moderna com o cliente e algo bem mais antigo com o backend, e o relatório de postura só mede o lado da frente.

Os health checks mentem no passthrough. Uma porta que aceita conexão não é uma aplicação capaz de responder, e é assim que um ambiente serve erros com todos os monitores verdes.

O cenário, por categoria

  • Reverse proxies e servidores web: NGINX, HAProxy, Envoy, Apache, Caddy; todos terminam TLS e todos conseguem fazer bridging ou passthrough.
  • Application delivery controllers: F5, Citrix, A10, em que a terminação fica no mesmo lugar que a persistência, o health monitoring e a política de tráfego.
  • Load balancers de nuvem e CDNs, em que o certificado muitas vezes fica no repositório do provedor e a chave privada nunca existe em nada que você administre.
  • Service meshes, que invertem o modelo: TLS mútuo em toda parte entre as workloads, com o sidecar fazendo ao mesmo tempo o papel de ponto de terminação e de ponto de origem do TLS.

O que o SNI e o TLS mútuo mudam

Dois recursos atravessam os três modos. O SNI importa porque um único IP e porta de proxy costuma atender muitos hostnames; o campo SNI permite que o proxy (ou o backend, no passthrough) escolha o certificado e a configuração certos para o nome pedido. É o tratamento correto do SNI que faz a hospedagem virtual (virtual hosting) sobre TLS funcionar.

O TLS mútuo (autenticação por certificado de cliente) é onde a escolha do modo pesa de verdade. Se o backend espera um certificado de cliente, o offload e o bridging quebram a cadeia, porque quem termina a sessão TLS do cliente é o proxy, e por isso o certificado do cliente nunca chega ao backend. O proxy pode validar ele mesmo o certificado do cliente e passar a identidade verificada ao backend num header, ou, se o backend realmente precisa ver o certificado original, algumas plataformas reapresentam uma cópia restrita dele no trecho até o backend. Se nenhuma das duas saídas for aceitável, o passthrough é o único modo que preserva um handshake de TLS mútuo legítimo, de ponta a ponta. Muitas vezes, é justamente a decisão sobre como tratar o TLS mútuo que força a escolha entre os três modos.