Change:
(WG email coming shortly.) ESNI has different compatibility characteristics than most TLS extensions. It involves client state, and encrypting the SNI makes the ClientHello unusable for servers that do not have the key or do not implement ESNI. This breaks common rollout and rollback strategies and places strong requirements on DNS/server consistency. This makes deploying ESNI risky for servers. This change aims to reduce these deployment risks. ESNI is much more useful if widely deployed. Moreover, if ESNI is unreliable due to complex requirements on the server, clients will be disincentivized to implement it. The DNS/server consistency requirements also disincentivize rotating keys (section 7.2.5). This change introduces the notion of a "public name" which allows the client to receive authenticated signals from the server that the ESNIKeys are out of sync, so clients can safely repair key mismatches. It also aligns with existing server behavior before ESNI, so partial rollouts and rollbacks can also be handled. The fix for the latter also handles MITM scenarios, replacing the existing client recommendation: The public name notion fixes a bug in that text: an attacker could disable ESNI on all servers, given the existence of any such server.
And, as I write this, I realize I forgot to deal with Stephen's comment on the thread about the middlebox stuff! It's quite late here, so I will reword that tomorrow morning.
Currently, the connect fails when a mismatch occurs. An alternative strategy might be to return a new ESNI key that is then used for a subsequent connection.
How to understand the reliability of the public key from server?
I see that I missed something about disabling. I think that this could be a lot more explicit about the three primary cases that I talk about in the comments below.Looks mostly good, but added some nits and clarification questions.

Discussion:
3.2. <del> The protocol designed in this document is quite straightforward. First, the provider publishes a public key which is used for SNI encryption for all the domains for which it serves directly or indirectly (via Split Mode).  This document defines a publication </del> <ins> First, the provider publishes a public key and metadata which is used for SNI encryption for all the domains for which it serves directly or indirectly (via Split Mode).  This document defines a publication </ins> mechanism using DNS, but other mechanisms are also possible.  In particular, if some of the clients of a private server are applications rather than Web browsers, those applications might have <del> the public key preconfigured. </del> <ins> the public key and metadata preconfigured. </ins> When a client wants to form a TLS connection to any of the domains <del> served by an ESNI-supporting provider, it replaces the "server_name" extension in the ClientHello with an "encrypted_server_name" extension, which contains the true extension encrypted under the provider's public key.  The provider can then decrypt the extension and either terminate the connection (in Shared Mode) or forward it to the backend server (in Split Mode). </del> <ins> served by an ESNI-supporting provider, it sends an "encrypted_server_name" extension, which contains the true extension encrypted under the provider's public key.  The provider can then decrypt the extension and either terminate the connection (in Shared Mode) or forward it to the backend server (in Split Mode). </ins> 4.

structure, defined below. The version of the structure.  For this specification, that value <del> SHALL be 0xff01.  Clients MUST ignore any ESNIKeys structure with </del> <ins> SHALL be 0xff02.  Clients MUST ignore any ESNIKeys structure with </ins> a version they do not understand.  [[NOTE: This means that the RFC will presumably have a nonzero value.]]

the ESNIKeys structure.  For the purpose of computing the checksum, the value of the "checksum" field MUST be set to zero. <ins> The non-empty name of the entity trusted to update these encryption keys.  This is used to repair misconfigurations, as described in handle-server-response. </ins> The list of keys which can be used by the client to encrypt the SNI.  Every key being listed MUST belong to a different group.

For servers (in EncryptedExtensions), this extension contains the following structure: <ins> Indicates whether the server processed the client ESNI extension. (See handle-server-response and server-behavior.} </ins> The contents of ClientESNIInner.nonce.  (See client-behavior.) <ins> One or more ESNIKeys structures containing the keys that the client should use on subsequent connections to encrypt the ClientESNIInner structure. This protocol also defines the "esni_required" alert, which is sent by the client when it offered an "encrypted_server_name" extension which was not accepted by the server. Finally, requirements in client-behavior and server-behavior require implementations to track, alongside each PSK established by a previous connection, whether the connection negotiated this extension with the "esni_accept" response type.  If so, this is referred to as an "ESNI PSK".  Otherwise, it is a "non-ESNI PSK".  This may be implemented by adding a new field to client and server session states. </ins> 5.1. <ins> 5.1.1. </ins> In order to send an encrypted SNI, the client MUST first select one of the server ESNIKeyShareEntry values and generate an (EC)DHE share in the matching group.  This share will then be sent to the server in

ESNI TXT query).  The client MUST NOT send encrypted SNI using groups or cipher suites not advertised by the server. <ins> When offering an encrypted SNI, the client MUST NOT offer to resume any non-ESNI PSKs.  It additionally MUST NOT offer to resume any sessions for TLS 1.2 or below. </ins> Let Z be the DH shared secret derived from a key share in ESNIKeys and the corresponding client share in ClientEncryptedSNI.key_share. The SNI encryption key is computed from Z as follows:

This value is placed in an "encrypted_server_name" extension. <del> The client MAY either omit the "server_name" extension or provide an innocuous dummy one (this is required for technical conformance with RFC7540; Section 9.2.) </del> <ins> The client MUST place the value of ESNIKeys.public_name in the "server_name" extension.  (This is required for technical conformance with RFC7540; Section 9.2.)  The client MUST NOT send a "cached_info" extension RFC7924 with a CachedObject entry whose CachedInformationType is "cert". 5.1.2. If the server negotiates TLS 1.3 or above and provides an "encrypted_server_name" extension in EncryptedExtensions, the client then processes the extension's "response_type" field: If the value is "esni_accept", the client MUST check that the extension's "nonce" field matches ClientESNIInner.nonce and otherwise abort the connection with an "illegal_parameter" alert. The client then proceeds with the connection as usual, verifying the certificate against the desired name. If the value is "esni_retry_request", the client proceeds with the handshake, verifying the certificate against ESNIKeys.public_name as described in verify-public-name.  If verification or the handshake fails, the client MUST return a failure to the calling application.  It MUST NOT use the retry keys. Otherwise, when the handshake completes successfully with the public name verified, the client MUST abort the connection with an "esni_required" alert.  It then processes the "retry_keys" field from the server's "encrypted_server_name" extension. If one of the values contains a version supported by the client, it can regard the ESNI keys as securely replaced by the server. It SHOULD retry the handshake with a new transport connection, using that value to encrypt the SNI.  The value may only be applied to the retry connection.  The client MUST continue to use the previously-advertised keys for subsequent connections.  This avoids introducing pinning concerns or a tracking vector, should a malicious server present client-specific retry keys to identify clients. If none of the values provided in "retry_keys" contains a supported version, the client can regard ESNI as securely disabled by the server.  As below, it SHOULD then retry the handshake with a new transport connection and ESNI disabled. If the field contains any other value, the client MUST abort the connection with an "illegal_parameter" alert. If the server negotiates an earlier version of TLS, or if it does not provide an "encrypted_server_name" extension in EncryptedExtensions, the client proceeds with the handshake, verifying the certificate against ESNIKeys.public_name as described in verify-public-name.  The client MUST NOT enable the False Start optimization RFC7918 for this handshake.  If verification or the handshake fails, the client MUST return a failure to the calling application.  It MUST NOT treat this as a secure signal to disable ESNI. Otherwise, when the handshake completes successfully with the public name verified, the client MUST abort the connection with an "esni_required" alert.  The client can then regard ESNI as securely disabled by the server.  It SHOULD retry the handshake with a new transport connection and ESNI disabled. [[TODO: Key replacement is significantly less scary than saying that ESNI-naive servers bounce ESNI off.  Is it worth defining a strict mode toggle in the ESNI keys, for a deployment to indicate it is ready for that? ]] Clients SHOULD implement a limit on retries caused by "esni_retry_request" or servers which do not acknowledge the "encrypted_server_name" extension.  If the client does not retry in either scenario, it MUST report an error to the calling application. 5.1.3. When the server cannot decrypt or does not process the "encrypted_server_name" extension, it continues with the handshake using the cleartext "server_name" extension instead (see server- behavior).  Clients that offer ESNI then verify the certificate with the public name, as follows: If the server resumed a session or negotiated a session that did not use a certificate for authentication, the client MUST abort the connection with an "illegal_parameter" alert.  This case is invalid because send-esni requires the client to only offer ESNI- established sessions, and server-behavior requires the server to decline ESNI-established sessions if it did not accept ESNI. The client MUST verify that the certificate is valid for ESNIKeys.public_name.  If invalid, it MUST abort the connection with the appropriate alert. If the server requests a client certificate, the client MUST respond with an empty Certificate message, denoting no client certificate. </ins> <del> If the server does not negotiate TLS 1.3 or above, then the client MUST abort the connection with an "unsupported_version" alert.  If the server does not provide an "encrypted_server_name" extension in EncryptedExtensions, the client MUST abort the connection with an "illegal_parameter" alert.  Moreover, it MUST check that ClientESNIInner.nonce matches the value of the "encrypted_server_name" extension provided by the server, and otherwise abort the connection with an "illegal_parameter" alert. </del> <ins> Note that verifying a connection for the public name does not verify it for the origin.  The TLS implementation MUST NOT report such connections as successful to the application.  It additionally MUST ignore all session tickets and session IDs presented by the server. These connections are only used to trigger retries, as described in handle-server-response.  This may be implemented, for instance, by reporting a failed connection with a dedicated error code. </ins> 5.2. Upon receiving an "encrypted_server_name" extension, the client- <del> facing server MUST first perform the following checks: If it is unable to negotiate TLS 1.3 or greater, it MUST abort the connection with a "handshake_failure" alert. If the ClientEncryptedSNI.record_digest value does not match the cryptographic hash of any known ESNIKeys structure, it MUST abort the connection with an "illegal_parameter" alert.  This is necessary to prevent downgrade attacks.  [[OPEN ISSUE: We looked at ignoring the extension but concluded this was better.]] </del> <ins> facing server MUST check that it is able to negotiate TLS 1.3 or greater.  If not, it MUST abort the connection with a "handshake_failure" alert. If the ClientEncryptedSNI.record_digest value does not match the cryptographic hash of any known ESNIKeys structure, it MUST ignore the extension and proceed with the connection, with the following added behavior: It MUST include the "encrypted_server_name" extension in EncryptedExtensions message with the "response_type" field set to "esni_retry_requested" and the "retry_keys" field set to one or more ESNIKeys structures with up-to-date keys.  Servers MAY supply multiple ESNIKeys values of different versions.  This allows a server to support multiple versions at once. The server MUST ignore all PSK identities in the ClientHello which correspond to ESNI PSKs.  ESNI PSKs offered by the client are associated with the ESNI name.  The server was unable to decrypt then ESNI name, so it should not resume them when using the cleartext SNI name.  This restriction allows a client to reject resumptions in verify-public-name. If the ClientEncryptedSNI.record_digest value does match the cryptographic hash of a known ESNIKeys, the server performs the following checks: </ins> If the ClientEncryptedSNI.key_share group does not match one in the ESNIKeys.keys, it MUST abort the connection with an

such that its length equals the size of the largest possible Certificate (message) covered by the same ESNI key.  Moreover, the server MUST include the "encrypted_server_name" extension in <del> EncryptedExtensions, and the value of this extension MUST match PaddedServerNameList.nonce. </del> <ins> EncryptedExtensions with the "response_type" field set to "esni_accept" and the "nonce" field set to the decrypted PaddedServerNameList.nonce value from the client "encrypted_server_name" extension. If the server sends a NewSessionTicket message, the corresponding ESNI PSK MUST be ignored by all other servers in the deployment when not negotiating ESNI, including servers which do not implement this specification.  This may be implemented by adding a new field to the server session state which earlier implementations cannot parse. This restriction provides robustness for rollbacks (see misconfiguration). </ins> 5.4.

to the backend server.  Thus, backend servers function the same as servers operating in Shared Mode. <ins> As in Shared Mode, if the backend server sends a NewSessionTicket message, the corresponding ESNI PSK MUST be ignored by other servers in the deployment when not negotiating ESNI, including servers which do not implement this specification. </ins> 6. <del> In general, this mechanism is designed only to be used with servers which have opted in, thus minimizing compatibility issues.  However, there are two scenarios where that does not apply, as detailed below. </del> <ins> Unlike most TLS extensions, placing the SNI value in an ESNI extension is not interoperable with existing servers, which expect the value in the existing cleartext extension.  Thus server operators SHOULD ensure servers understand a given set of ESNI keys before advertising them.  Additionally, servers SHOULD retain support for any previously-advertised keys for the duration of their validity. However, in more complex deployment scenarios, this may be difficult to fully guarantee.  Thus this protocol was designed to be robust in case of inconsistencies between systems that advertise ESNI keys and servers, at the cost of extra round-trips due to a retry.  Two specific scenarios are detailed below. </ins> 6.1. <del> If DNS is misconfigured so that a client receives ESNI keys for a server which is not prepared to receive ESNI, then the server will ignore the "encrypted_server_name" extension, as required by RFC8446; Section 4.1.2.  If the servers does not require SNI, it will complete the handshake with its default certificate.  Most likely, this will cause a certificate name mismatch and thus handshake failure. Clients SHOULD NOT fall back to cleartext SNI, because that allows a network attacker to disclose the SNI.  They MAY attempt to use another server from the DNS results, if one is provided. </del> <ins> It is possible for ESNI advertisements and servers to become inconsistent.  This may occur, for instance, from DNS misconfiguration, caching issues, or an incomplete rollout in a multi-server deployment.  This may also occur if a server loses its ESNI keys, or if a deployment of ESNI must be rolled back on the server. The retry mechanism repairs most such inconsistencies.  If server and advertised keys mismatch, the server will respond with esni_retry_requested.  If the server does not understand the "encrypted_server_name" extension at all, it will ignore it as required by RFC8446; Section 4.1.2.  Provided the server can present a certificate valid for the public name, the client can safely retry with updated settings, as described in handle-server-response. Unless ESNI is disabled as a result of successfully establishing a connection to the public name, the client MUST NOT fall back to cleartext SNI, as this allows a network attacker to disclose the SNI. It MAY attempt to use another server from the DNS results, if one is provided. </ins> 6.2. A more serious problem is MITM proxies which do not support this extension.  RFC8446; Section 9.3 requires that such proxies remove <del> any extensions they do not understand.  This will have one of two results when connecting to the client-facing server: The handshake will fail if the client-facing server requires SNI. The handshake will succeed with the client-facing server's default certificate. A Web client client can securely detect case (2) because it will result in a connection which has an invalid identity (most likely) but which is signed by a certificate which does not chain to a publicly known trust anchor.  The client can detect this case and disable ESNI while in that network configuration. In order to enable this mechanism, client-facing servers SHOULD NOT require SNI, but rather respond with some default certificate. A non-conformant MITM proxy will forward the ESNI extension, substituting its own KeyShare value, with the result that the client- facing server will not be able to decrypt the SNI.  This causes a hard failure.  Detecting this case is difficult, but clients might opt to attempt captive portal detection to see if they are in the presence of a MITM proxy, and if so disable ESNI.  Hopefully, the TLS 1.3 deployment experience has cleaned out most such proxies. </del> <ins> any extensions they do not understand.  The handshake will then present a certificate based on the public name, without echoing the "encrypted_server_name" extension to the client. Depending on whether the client is configured to accept the proxy's certificate as authoritative for the public name, this may trigger the retry logic described in handle-server-response or result in a connection failure.  A proxy which is not authoritative for the public name cannot forge a signal to disable ESNI. A non-conformant MITM proxy which instead forwards the ESNI extension, substituting its own KeyShare value, will result in the client-facing server recognizing the key, but failing to decrypt the SNI.  This causes a hard failure.  Clients SHOULD NOT attempt to repair the connection in this case. </ins> 7.

operating in Split Mode is not possible.  See cleartext-dns for more details regarding cleartext DNS. <ins> Validating the ESNIKeys structure additionally validates the public name.  This validates any retry signals from the server because the client validates the server certificate against the public name before retrying. </ins> 7.2.8. This design has no impact on application layer protocol negotiation.

8.1. <del> IANA is requested to Create an entry, encrypted_server_name(0xffce), </del> <ins> IANA is requested to create an entry, encrypted_server_name(0xffce), </ins> in the existing registry for ExtensionType (defined in RFC8446), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". 8.2. <ins> IANA is requested to create an entry, esni_required(121) in the existing registry for Alerts (defined in RFC8446), with the "DTLS-OK" column being set to "Y". 8.3. </ins> IANA is requested to create an entry in the DNS Underscore Global Scoped Entry Registry (defined in I-D.ietf-dnsop-attrleaf) with the "RR Type" column value being set to "TXT", the "_NODE NAME" column