Como proteger seu site público com ESNI

Olá Habr, meu nome é Ilya e trabalho na equipe de plataforma da Exness. Desenvolvemos e implementamos componentes de infraestrutura essenciais usados ​​por nossas equipes de desenvolvimento de produtos.

Neste artigo, gostaria de compartilhar minha experiência na implementação da tecnologia SNI criptografada (ESNI) na infraestrutura de sites públicos.

Como proteger seu site público com ESNI

A utilização desta tecnologia melhorará o nível de segurança ao trabalhar com um site público e estará em conformidade com as normas de segurança internas adotadas pela empresa.

Primeiramente, gostaria de salientar que a tecnologia não é padronizada e ainda está em fase de projeto; no entanto, a CloudFlare e a Mozilla já a suportam (em rascunho01Foi isso que nos motivou a realizar tal experimento.

Um pouco de teoria

ESNI – é uma extensão do protocolo TLS 1.3 que permite a criptografia do SNI na mensagem de handshake TLS "Client Hello". Veja como é um Client Hello com suporte a ESNI (em vez do SNI usual, vemos o ESNI):

Como proteger seu site público com ESNI

 Para utilizar o ESNI, são necessários três componentes:

  • DNS; 
  • Suporte ao cliente;
  • Suporte do lado do servidor.

DNS

Você precisa adicionar dois registros DNS – AE SMS (O registro TXT contém a chave pública com a qual o cliente pode criptografar o SNI) – veja abaixo. Além disso, deve haver suporte. DoH (DNS sobre HTTPS), visto que os clientes disponíveis (ver abaixo) não habilitam o suporte a ESNI sem DoH. Isso é lógico, já que o ESNI exige a criptografia do nome do recurso que estamos acessando, o que significa que não faz sentido acessar o DNS sobre UDP. Além disso, usando DNSSEC Permite proteger contra ataques de envenenamento de cache neste cenário.

Disponível no momento vários fornecedores do Departamento de Saúde, entre eles:

CloudFlare declara (Verificar meu navegador → SNI criptografado → Saiba mais) que seus servidores já suportam ESNI, o que significa que os servidores da CloudFlare têm pelo menos dois registros DNS — A e TXT. No exemplo abaixo, estamos consultando o DNS do Google (via HTTPS): 

А registro:

curl 'https://dns.google.com/resolve?name=www.cloudflare.com&type=A' 
-s -H 'accept: application/dns+json'
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": true,
  "CD": false,
  "Question": [
    {
      "name": "www.cloudflare.com.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "www.cloudflare.com.",
      "type": 1,
      "TTL": 257,
      "data": "104.17.210.9"
    },
    {
      "name": "www.cloudflare.com.",
      "type": 1,
      "TTL": 257,
      "data": "104.17.209.9"
    }
  ]
}

SMS O registro e a solicitação são gerados de acordo com um modelo. _esni.FQDN:

curl 'https://dns.google.com/resolve?name=_esni.www.cloudflare.com&type=TXT' 
-s -H 'accept: application/dns+json'
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": true,
  "CD": false,
  "Question": [
    {
    "name": "_esni.www.cloudflare.com.",
    "type": 16
    }
  ],
  "Answer": [
    {
    "name": "_esni.www.cloudflare.com.",
    "type": 16,
    "TTL": 1799,
    "data": ""/wEUgUKlACQAHQAg9SiAYQ9aUseUZr47HYHvF5jkt3aZ5802eAMJPhRz1QgAAhMBAQQAAAAAXtUmAAAAAABe3Q8AAAA=""
    }
  ],
  "Comment": "Response from 2400:cb00:2049:1::a29f:209."
}

Portanto, do ponto de vista do DNS, devemos usar DoH (de preferência com DNSSEC) e adicionar dois registros. 

Suporte ao cliente

Se falarmos de navegadores, então, neste momento... O suporte está implementado apenas no Firefox.. é Aqui estão as instruções sobre como habilitar o suporte a ESNI e DoH no Firefox. Depois que o navegador estiver configurado, você deverá ver algo como isto:

Como proteger seu site público com ESNI

Link Para verificar o navegador.

Obviamente, o TLS 1.3 deve ser usado para dar suporte ao ESNI, já que o ESNI é uma extensão do TLS 1.3.

Para fins de teste do backend com suporte a ESNI, implementamos um cliente em go, Mas mais sobre isso mais tarde.

Suporte do lado do servidor

Atualmente, o ESNI não é suportado por servidores web como nginx/apache, etc., uma vez que eles funcionam com TLS via OpenSSL/BoringSSL, que não oferecem suporte oficial ao ESNI.

Portanto, decidimos criar nosso próprio componente de front-end (proxy reverso ESNI) que suportasse a terminação TLS 1.3 com ESNI e encaminhasse o tráfego HTTP(S) para servidores upstream que não suportam ESNI. Isso nos permite usar a tecnologia em uma infraestrutura existente sem alterar os componentes principais — ou seja, usando servidores web existentes que não suportam ESNI. 

Para maior clareza, segue um diagrama:

Como proteger seu site público com ESNI

Vale ressaltar que o proxy foi projetado com a capacidade de encerrar conexões TLS sem ESNI, para dar suporte a clientes que não utilizam ESNI. Além disso, o protocolo de comunicação upstream pode ser HTTP ou HTTPS com uma versão TLS inferior a 1.3 (caso o upstream não suporte a 1.3). Esse design proporciona máxima flexibilidade.

Implementação do suporte ESNI em go nós pegamos emprestado de CloudFlareJá adianto que a implementação em si não é trivial, pois envolve alterações na biblioteca padrão. cripto / tls e, portanto, requer "correção". GOROOT antes da montagem.

Para gerar chaves ESNI, usamos esnitool (também uma criação da CloudFlare). Essas chaves são usadas para criptografar/descriptografar SNI.
Мы протестировали сборку с использованием go 1.13 на Linux (Debian, Alpine) и MacOS. 

Algumas palavras sobre as funcionalidades operacionais.

O proxy reverso ESNI fornece métricas no formato Prometheus, como RPS (requisições por segundo), latência de upstream e códigos de resposta, handshakes TLS com falha/sucesso e duração do handshake TLS. À primeira vista, isso parecia suficiente para avaliar como o proxy lida com o tráfego. 

Também realizamos testes de carga antes do uso. Os resultados estão abaixo:

wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Running 6m test @ https://esni-rev-proxy.npw:443
  50 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.77s     1.21s    7.20s    65.43%
    Req/Sec    13.78      8.84   140.00     83.70%
  206357 requests in 6.00m, 6.08GB read
Requests/sec:    573.07
Transfer/sec:     17.28MB 

Realizamos testes de carga puramente qualitativos para comparar a configuração com e sem o proxy reverso ESNI. Injetamos tráfego localmente para eliminar interferências de componentes intermediários.

Assim, com suporte a ESNI e proxy reverso com HTTP, obtivemos cerca de 550 requisições por segundo (rps) de uma instância, com o consumo médio de CPU/RAM do proxy reverso ESNI:

  • 80% CPU Usage (4 vCPU, 4 GB RAM хосты, Linux)
  • 130 MB de memória RSS

Como proteger seu site público com ESNI

Para efeito de comparação, o RPS para o mesmo servidor nginx upstream sem terminação TLS (protocolo HTTP) é de aproximadamente 1100:

wrk -t50 -c1000 -d360s 'http://lb.npw:80' –-timeout 15s
Running 6m test @ http://lb.npw:80
  50 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.11s     2.30s   15.00s    90.94%
    Req/Sec    23.25     13.55   282.00     79.25%
  393093 requests in 6.00m, 11.35GB read
  Socket errors: connect 0, read 0, write 0, timeout 9555
  Non-2xx or 3xx responses: 8111
Requests/sec:   1091.62
Transfer/sec:     32.27MB 

Наличие таймаутов говорит о том, что есть нехватка ресурсов (мы использовали 4 vCPU, 4 GB RAM хосты, Linux), и по факту потенциальный RPS выше (мы получали цифры до  2700 RPS на более мощных ресурсах).

Em conclusão, gostaria de observar que A tecnologia ESNI parece bastante promissora. Ainda existem muitas questões em aberto, como o armazenamento da chave pública ESNI no DNS e a rotação das chaves ESNI — esses assuntos estão sendo ativamente debatidos, e a versão preliminar mais recente (na data desta publicação) do ESNI já está disponível. 7.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção DDoS, servidores VPS VDS 🔥 Compre hospedagem de sites confiável com proteção contra DDoS, servidores VPS/VDS | ProHoster