Comment protéger votre site public avec ESNI

Bonjour Habr, je m'appelle Ilya et je travaille dans l'équipe plateforme de la société Exness. Nous développons et mettons en œuvre des composants d'infrastructure de base utilisés par nos équipes de développement produit.

Dans cet article, je voudrais partager mon expérience de mise en œuvre de la technologie encrypted SNI (ESNI) dans l'infrastructure des sites web publics.

Comment protéger votre site public avec ESNI

L'utilisation de cette technologie permettra d'améliorer la sécurité dans le cadre de l'exploitation d'un site web public et de respecter les normes de sécurité internes en vigueur dans l'entreprise.

Tout d'abord, je tiens à souligner que la technologie n'est pas encore standardisée et est toujours en phase de brouillon ; cependant, CloudFlare et Mozilla la supportent déjà (dans draft01). Cela nous a motivés à faire une telle expérience.

Un peu de théorie

ESNI est une extension du protocole TLS 1.3 qui permet de chiffrer le SNI dans le message « Client Hello » lors de l'échange TLS. Voici à quoi ressemble le Client Hello avec le support de l'ESNI (au lieu du SNI habituel, nous voyons ESNI) :

Comment protéger votre site public avec ESNI

 Pour utiliser l'ESNI, trois éléments sont nécessaires :

  • DNS ; 
  • Support côté client ;
  • Support côté serveur.

DNS

Il est nécessaire d'ajouter deux enregistrements DNS – Aet TXT (l'enregistrement TXT contient la clé publique permettant au client de chiffrer le SNI) – voir ci-dessous. De plus, le support de DoH (DNS over HTTPS) est requis, car les clients disponibles (voir ci-dessous) n'activent pas le support de l'ESNI sans DoH. Cela est logique, car ESNI implique le chiffrement du nom de la ressource à laquelle nous accédons, donc il est inutile d'interroger le DNS par UDP. De plus, l'utilisation de DNSSEC permet de se protéger contre les attaques de « cache poisoning » dans ce scénario.

À l'heure actuelle, plusieurs fournisseurs DoH sont disponibles , parmi lesquels :OpenDNS

CloudFlare déclare enregistrement : 

Un 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" } ] }

enregistrement, la requête est formulée selon le modèle

TXT _esni.FQDN _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."
}

Ainsi, d'un point de vue DNS, nous devons utiliser DoH (idéalement avec DNSSEC) et ajouter deux enregistrements. 

Support du côté client

Si nous parlons des navigateurs, pour le moment le support est seulement implémenté dans FireFox. Ici voici des instructions sur la façon d'activer le support ESNI et DoH dans FireFox. Après avoir configuré le navigateur, nous devrions voir quelque chose comme ceci :

Comment protéger votre site public avec ESNI

Lien pour tester le navigateur.

Bien sûr, pour supporter ESNI, TLS 1.3 doit être utilisé, car ESNI est une extension de TLS 1.3.

Pour les tests de backend avec support ESNI, nous avons réalisé un client sur go, mais nous en parlerons un peu plus tard.

Support du côté serveur

Pour le moment, ESNI n'est pas supporté par les serveurs web comme nginx/apache, etc., car ils utilisent TLS via OpenSSL/BoringSSL, dans lesquels ESNI n'est pas officiellement supporté.

C'est pourquoi nous avons décidé de créer notre composant front-end (proxy inverse ESNI) qui prend en charge la terminaison TLS 1.3 avec ESNI et le proxy de trafic HTTP(S) vers l'upstream ne supportant pas ESNI. Cela permet d'appliquer la technologie dans une infrastructure déjà établie, sans modifier les composants principaux - c'est-à-dire d'utiliser les serveurs web existants qui ne supportent pas ESNI. 

Pour la clarté, voyons le schéma :

Comment protéger votre site public avec ESNI

Je note que le proxy a été conçu avec la possibilité de terminer une connexion TLS sans ESNI, pour le soutien des clients sans ESNI. De plus, le protocole de communication avec l'upstream peut être tant HTTP que HTTPS avec une version TLS inférieure à 1.3 (si l'upstream ne supporte pas 1.3). Ce schéma offre une flexibilité maximale.

L'implémentation du support ESNI sur go nous l'avons empruntée à CloudFlare. Je souligne immédiatement que l'implémentation elle-même est assez non triviale, car elle implique des modifications dans la bibliothèque standard crypto/tls et nécessite donc un « patchage » GOROOT avant la construction.

Pour générer les clés ESNI, nous avons utilisé esnitool (une autre création de CloudFlare). Ces clés sont utilisées pour le chiffrement/déchiffrement SNI.
Nous avons testé la construction en utilisant go 1.13 sur Linux (Debian, Alpine) et MacOS. 

Quelques mots sur les caractéristiques opérationnelles

Le proxy inverse ESNI fournit des métriques au format Prometheus, par exemple, telles que rps, latence montante & codes de réponse, échecs/réussites des connexions TLS & durée des connexions TLS. À première vue, cela semblait suffisant pour évaluer comment le proxy gère le trafic. 

Avant utilisation, nous avons également effectué des tests de charge. Voici les résultats :

wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Exécution d'un test de 6 minutes @ https://esni-rev-proxy.npw:443
  50 threads et 1000 connexions
  Statistiques des threads   Moy   Écart   Max   +/− Écart
    Latence     1.77s     1.21s    7.20s    65.43%
    Req/Sec    13.78      8.84   140.00     83.70%
  206357 requêtes en 6.00m, 6.08GB lus
Requêtes/sec :   573.07
Transfert/sec :     17.28MB 

Nous avons effectué des tests de charge purement qualitatifs, pour comparer les schémas utilisant le proxy inverse ESNI et sans. Nous avons « injecté » du trafic localement pour exclure les « interférences » dans les composants intermédiaires.

Ainsi, avec le support ESNI et le proxy vers l'amont en HTTP, nous avons obtenu environ ~ 550 rps d'une instance, avec une consommation CPU/RAM moyenne du proxy inverse ESNI :

  • 80% d'utilisation CPU (hôtes 4 vCPU, 4 Go de RAM, Linux)
  • 130 Mo de Mémoire RSS

Comment protéger votre site public avec ESNI

Pour comparer, le RPS pour le même amont nginx sans terminaison TLS (protocole HTTP) est d'environ ~ 1100 :

wrk -t50 -c1000 -d360s 'http://lb.npw:80' –-timeout 15s
Exécution d'un test de 6 minutes @ http://lb.npw:80
  50 threads et 1000 connexions
  Statistiques des threads   Moy   Écart   Max   +/− Écart
    Latence     1.11s     2.30s   15.00s    90.94%
    Req/Sec    23.25     13.55   282.00     79.25%
  393093 requêtes en 6.00m, 11.35GB lus
  Erreurs de socket : connexion 0, lecture 0, écriture 0, délai 9555
  Réponses non-2xx ou 3xx : 8111
Requêtes/sec :   1091.62
Transfert/sec :     32.27MB 

La présence de délais indique qu'il y a un manque de ressources (nous avons utilisé des hôtes 4 vCPU, 4 Go de RAM, Linux), et en fait, le RPS potentiel est plus élevé (nous avons obtenu des chiffres allant jusqu'à 2700 RPS sur des ressources plus puissantes).

En conclusion, je soulignerai que la technologie ESNI semble assez prometteuse. Il reste encore de nombreuses questions ouvertes, par exemple, concernant le stockage de la clé ESNI publique dans le DNS et le rotation des clés ESNI – ces questions sont activement débattues, et la dernière version du brouillon (au moment de la rédaction) de l'ESNI est déjà 7.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster