不请自来。
刚好这些天在弄相关的东西,说一下我目前了解到的东西。
首先,client hello 是否包含 server_name 完全取决于客户端(譬如你的浏览器),以目前唯一支持 ESNI 的浏览器 Firefox 来说,在高级设置中可以手动启用 ESNI ( network.security.esni.enabled ),访问 V2EX 时会自动切换到 ESNI 方式,而访问不支持 ESNI 的站点时还是会发送明文的 server_name 。目前 ESNI 仍然是草案,即便以后真的启用,为了兼容不支持 ESNI 的站点,估计也仍然会保持这种方式,毕竟不是所有站点都会支持 ESNI 。
然后,我部署了
https://github.com/dlundquist/sniproxy 这个 SNI 代理,在源码
https://github.com/dlundquist/sniproxy/blob/master/src/tls.c 第 220 行左右可以看到,SNI 代理的工作方式是需要从 tls 握手的 client hello 中提取 server_name 来作为目标判定。
如果以后 ESNI 正式启用,那么类似的 SNI 代理需要稍作修改,从 client hello 中拿到客户端发送来的公钥,然后配合自己保存的私钥解出真正的 host 来作为目标判定,这样的话就要求除了 web server 外,sniproxy 也需要访问同样的私钥。