ECH (Encrypted Client Hello): l'avenir d'ESNI dans Firefox
(https://lafibre.info/images/logo/logo_encrypted_client_hello.jpg)
Écrit par Kevin Jacobs, le 7 janvier 2021
Contexte
Il y a deux ans, nous avons annoncé la prise en charge expérimentale de l'extension ESNI (Encrypted Server Name Indication) protégeant la confidentialité dans Firefox Nightly. L'extension Server Name Indication (SNI) permet la sélection du bon certificat TLS en transmettant une copie en texte clair du nom d'hôte du serveur, dans le message "Hello" du client TLS. Cela représente une fuite de confidentialité similaire à celle du DNS, et tout comme DNS-over-HTTPS empêche les requêtes DNS d'exposer le nom d'hôte aux observateurs sur chemin, ESNI tente d'empêcher les fuites de nom d'hôte à partir de la négociation TLS elle-même.
Depuis la publication du projet de spécification d'ESNI à l'IETF, l'analyse a montré que le chiffrement uniquement de l'extension SNI fournit une protection incomplète. À titre d'exemple: lors de la reprise de session, l'extension de clé pré-partagée pourrait contenir une copie en texte clair du même nom de serveur chiffré par ESNI. L'approche ESNI nécessiterait une variante cryptée de chaque extension avec des implications potentielles sur la confidentialité, et même cela expose l'ensemble des extensions annoncées. Enfin, l'utilisation d'ESNI dans le monde réel a exposé des problèmes d'interopérabilité et de déploiement qui l'ont empêchée d'être activée à une plus grande échelle.
Arrivée du Encrypted Client Hello (ECH)
Pour remédier aux lacunes d'ESNI, les versions récentes de la spécification (https://datatracker.ietf.org/doc/draft-ietf-tls-esni/) ne chiffrent plus uniquement l'extension SNI et chiffrent à la place un message Client Hello entier (ainsi le nom passe de «ESNI» à «ECH»). Toutes les extensions ayant des implications sur la confidentialité peuvent désormais être reléguées à un «ClientHelloInner» chiffré, qui est lui-même annoncé comme une extension d'un «ClientHelloOuter» non chiffré. Si un serveur prend en charge ECH et décrypte avec succès, le client «interne» Hello est alors utilisé comme base pour la connexion TLS. Ceci est expliqué plus en détail dans l'excellent article de blog de Cloudflare sur ECH (https://blog.cloudflare.com/encrypted-client-hello/).
ECH modifie également la distribution des clés et les histoires de chiffrement: un serveur TLS prenant en charge ECH annonce désormais sa clé publique via un enregistrement DNS HTTPSSVC , alors qu'ESNI a utilisé des enregistrements TXT à cette fin. La dérivation et le chiffrement des clés sont rendus plus robustes, car ECH utilise la spécification Hybrid Public Key Encryption plutôt que de définir son propre schéma. Surtout, ECH ajoute également un mécanisme de nouvelle tentative pour augmenter la fiabilité en ce qui concerne la rotation des clés du serveur et la mise en cache DNS. Là où ESNI peut actuellement échouer après avoir reçu des clés obsolètes du DNS, ECH peut récupérer en toute sécurité, car le client reçoit les clés mises à jour directement du serveur.
Certes avec le DNS en clair celui qui observe le réseau a beaucoup d'informations, mais pas autant que le SNI.Dans les 2 cas (DNS ou SNI), c'est bien le nom de domaine complet (ex : www.lafibre.info) qui est transmis, non ?
Dans les 2 cas (DNS ou SNI), c'est bien le nom de domaine complet (ex : www.lafibre.info) qui est transmis, non ?Oui, mais le DNS est mis en cache, donc on capture une requête de temps en temps.
Hébergeur | Type de DNS | Latence (depuis Paris) | URL DNS over HTTPS (DoH) |
CloudFlare | standard | 1ms | https://cloudflare-dns.com/dns-query |
CloudFlare | DNS64 (il ne répond qu'en IPv6, logique) | 1ms | https://dns64.cloudflare-dns.com/dns-query |
Google Public DNS | standard | 1ms | https://dns.google/dns-query |
Google Public DNS | DNS64 (il ne répond qu'en IPv6, logique) | 1ms | https://dns64.dns.google/dns-query |
NextDNS | standard (incompatible IPv6) | 1ms | https://dns.nextdns.io/ cf https://my.nextdns.io/configuration/ pour la configuration |
AdGuard | standard | 84ms | https://dns.adguard.com/dns-query |
AdGuard | mode "Family protection" | 84ms | https://dns-family.adguard.com/dns-query |
CleanBrowsing | mode "Security Filter" (incompatible IPv6) | 8ms | https://doh.cleanbrowsing.org/doh/security-filter/ |
CleanBrowsing | mode "Family Filter" (incompatible IPv6) | 8ms | https://doh.cleanbrowsing.org/doh/family-filter/ |
CleanBrowsing | mode "Adult Filter" (incompatible IPv6) | 8ms | https://doh.cleanbrowsing.org/doh/adult-filter/ |
OpenDNS | standard | 9ms | https://doh.opendns.com/dns-query |
OpenDNS | mode "FamilyShield" | 9ms | https://doh.familyshield.opendns.com/dns-query |
Quad9 DNS | standard (Unsecured) | 1ms | https://dns10.quad9.net/dns-query |
Quad9 DNS | mode "Secure Recommended" | 1ms | https://dns.quad9.net/dns-query |
Quad9 DNS | mode "Secured" | 1ms | https://dns9.quad9.net/dns-query |
Quad9 DNS | mode "Secured w/ ECS (https://en.wikipedia.org/wiki/EDNS_Client_Subnet) support" | 1ms | https://dns11.quad9.net/dns-query |
Switch Public DNS | standard | 26ms | https://dns.switch.ch/dns-query |
Dans ce scénario, la plateforme NAT46 qui permet de faire le lien entre l'IPv4 de l'entreprise et l'Internet IPv6 serait chez l'opérateur. Contrairement au NAT64 utilisé sur les téléphones mobiles, où un mobile IPv6 only accède à l'Internet IPv4 pas un DNS64 qui va encoder l'IPv4 dans une IPv6, sur la NAT46, il est impossible de mettre une IPv6 dans une partie de l'IPv4 et donc la seule solution pour retrouver la cible, c'est le SNI.Le SNI ne s'applique qu'au TLS, comment cette solution de NAT46 s'appliquerait à Internet en général, et pas uniquement au web ?
Firefox supporte le ESNI, pour ça il faut :Suite au tutoriel de Vivien (Mozilla active DNS over HTTPS par défaut dans Firefox (https://lafibre.info/navigateurs/doh-usa/msg735608/#msg735608)), merci pour le tuyau. (https://lafibre.info/images/smileys/@GregLand/ay.gif)
- activer le DNS sur HTTPS (DoH) : dans les options, ou network.trr.mode=2 dans about:config (par exemple sur Android)
- activer network.security.esni.enabled dans about:config ...
Des infos intéressantes dans le mail de la ML cité par ZDNet : https://mailarchive.ietf.org/arch/msg/tls/Dae-cukKMqfzmTT4Ksh1Bzlx7ws/
1 www.cloudflare.com (alpn="h3-29,h3-28,h3-27,h2" ipv4hint="104.16.123.96, 104.16.124.96" ipv6hint="2606:4700::6810:7b60, 2606:4700::6810:7c60" )
Il manque "echconfig" à priori.1 crypto.cloudflare.com (alpn="h2" ipv4hint="162.159.135.79, 162.159.136.79" echConfig="0048FE0A0044DE00200020E7A8835B62302BB1696303E3E48942B870F80FDF853DEF0979765703E0D1596800040001000100000013636C6F7564666C6172652D65736E692E636F6D0000" ipv6hint="2606:4700:7::a29f:874f, 2606:4700:7::a29f:884f" )
Il y a "echConfig".Il y a des fonctions qui restent des années dans Chrome Canary / Firefox Nightly sans passer dans les versions bêta.
Une fois en bêta, oui, ce sera disponible rapidement dans la version stable (un retard d'une version est possible).
Malheureusement sur ios ni doh ni le reste est present sur chrome beta (105)Sur iOS c'est WebKit derrière (Apple ne permet pas les autre moteurs), donc je pense que ce sont toujours les couches réseau Apple qui sont utilisées.
Les opérateurs qui font du DPI vont avoir un problème...
ECH peut fonctionner avec HTTP/1.1 ? (oui, c'est assez tordu d'avoir un serveur qui supporte ECH mais pas HTTP/2)
Bonjour,
Actuellement j’utilise la fonctionnalité de firefox qui peut voir l'enregistrement dns httpsvc, mais ce n'est pas exhaustif.
Savez vous si on a un moyen plus simple de voir si la fonctionnalité TLS ECS est utilisée sur un site web ?
Bonne journée
sachant que a l'epoque avec ESNI ca fonctionnait et que ech semble pas actif sur rsf (https://rsf.org/cdn-cgi/trace donne cleartext sni)Il n'y a pas d'ECH pour rsf.org (cf about:networking#dnslookuptool dans Firefox, pas de "echConfig").
Autre chose m'interpelle : l'utilisation de TLS 1.2 alors que https://rsf.org gère TLS 1.3 (et les navigateurs aussi). Comment expliquer que TLS 1.2 soit utilisé ?Le Client Hello a pour version TLS 1.2, mais l'extension supported_versions indique TLS 1.2, TLS 1.3 (et GREASE pour Chrome).
Il n'y a pas d'ECH pour rsf.org (cf about:networking#dnslookuptool dans Firefox, pas de "echConfig").
Mais Chrome envoie quand même l'extension (Wireshark indique "Unknown type 65037").
Il s'agit de GREASE ECH : https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-15#name-grease-ech.
Je suppose que ça a deux rôles :
- faire comme GREASE (qui est aussi utilisé) : s'assurer que les différents serveurs et intermédiaires (proxy, ...) n'ont pas de bugs quand ils voient des extensions qu'ils ne connaissent pas
- noyer le trafic ECH dans le reste
Ici, même avec le SNI rsf.org, ça semble permettre de contourner le blocage.
Pour Firefox, il y a :
- security.tls.ech.grease_probability (pourcentage des connexions TLS qui ont GREASE ECH activé) : 0 par défaut, 50 sur Nightly
- security.tls.ech.grease_http3 (activation de GREASE ECH en HTTP/3) : false par défaut
Avec security.tls.ech.grease_probability=100, le comportement serait similaire à Chrome, ça peut permettre de contourner les blocages aussi.Le Client Hello a pour version TLS 1.2, mais l'extension supported_versions indique TLS 1.2, TLS 1.3 (et GREASE pour Chrome).
C'est normal, puisque les navigateurs supportent le deux versions, le serveur répond avec la plus récente qu'il supporte.
Wireshark renseigne probablement la colonne protocole à partir de la version vue dans l'extension supported_versions du Server Hello.
2) dans nightly les 2 options sont actives par defaut et grease probability est a 100Effectivement, ça a changé entre temps.
Mais bizarrement, ça ne fonctionne pasChrome met le SNI vers la fin des extensions, avec notamment le GREASE ECH (282 octets) avant.