]>
Private Discovery with TLS-ESNI
Private Octopus Inc.Friday Harbor98250WAU.S.A.huitema@huitema.nethttp://privateoctopus.com/University of Luxembourg6, avenue de la FonteEsch-sur-Alzette4364Luxembourgdaniel.kaiser@uni.luhttps://secan-lab.uni.lu/
DNS-SD (DNS Service Discovery) normally discloses information about both the devices offering services and the devices requesting services.
This information includes host names, network parameters, and possibly a further description of the corresponding service instance.
Especially when mobile devices engage in DNS Service Discovery over Multicast DNS at a public hotspot,
a serious privacy problem arises.
We propose to solve this problem by developing a private discovery profile for UDP based transports using TLS,
such as DTLS and QUIC. The profile is based on using the Encrypted SNI extension. We also define a standalone
private discovery service, that can be combined with arbitrary applications in the same way as DNS-SD.
DNS-SD over mDNS enables configurationless
service discovery in local networks.
It is very convenient for users, but it requires the public exposure
of the offering and requesting identities along with information about the offered and
requested services.
Parts of the published information can seriously breach the user's privacy.
These privacy issues and potential solutions are discussed in
and .
When analyzing these scenarios in , we find that
the DNS-SD messages leak identifying information such as the instance name,
the host name or service properties.
In this document, we propose a discovery solution that can replace DNS-SD in simple deployment
scenarios, with the following characteristics:
We only target discovery of peers on the same local network, using multicast. We
make no attempt at compatibility with the server based solutions such as DNSSD
over Unicast DNS .
We do not attempt to keep the same formats as mDNS .
We assume a solution that can be integrated in an application, without dependency
on system support.
The proposed solution aligns with TLS 1.3 , and
specifically with transports of TLS over UDP, such as DTLS
or QUIC .
The solution uses SNI encryption .
The solution assumes that entities who want to be privately discovered maintain
an asymmetric discovery key pair. The public component of that discovery key pair
and the service name of the entity are provisioned to authorized discovery
clients. In this document, we will refer to this public component as the
"Discovery Key" of the server. When needed, we will refer to the private
component of the key pair as the "Discovery Private Key".
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in .
In the proposed solution, the first packet of a TLS-based UDP transport is
broadcast or multicast over the local network. This packet carries the TLS 1.3
ClientHello message, including an Encrypted SNI (ESNI) extension. The ESNI
is encrypted with the Discovery Key of the requested service.
Services that are ready to be discovered listen on the broadcast or
multicast address and check whether the received packets contain a TLS 1.3
ClientHello Message and an ESNI extension. If the extension can be
decrypted with the Private Discovery Key of the local service, they
set up a connection.
This mechanism only works with TLS based protocols operating over UDP, such
as DTLS or QUIC.
Private discovery relies on the privacy of the server Discovery Key, which
is used to encrypt the target server name carried in the ESNI extension.
Clients can only discover a server if they know the server's Discovery Key.
Servers receiving a properly encrypted discovery request do not know
the identity of the client issuing the request, but they know that the
client belongs to a group authorized to perform the discovery.
In the ESNI based specification, the server's Discovery Key plays the
same role as the ESNI Encryption Key of the client facing server, but
a major difference is that the Discovery Key is kept private.
According to standard ESNI, the client facing server publishes an ESNI encryption
key in the DNS. In contrast, the Discovery Key MUST NOT be publicly
available in the DNS.
The discovery key is passed to the peer in exactly the same format as ESNI:
struct {
uint8 checksum[4];
KeyShareEntry keys<4..2^16-1>;
CipherSuite cipher_suites<2..2^16-2>;
uint16 padded_length;
uint64 not_before;
uint64 not_after;
Extension extensions<0..2^16-1>;
} ESNIKeys;
This document does not discuss how the Discovery Key is provisioned to
authorized discovery clients.
The ESNI extension design assumes that several services are available through
a single client facing server. These different services have different SNI
values and length. ESNI pads these SNI to a padded length specified for the
client facing server, ensuring that third parties cannot infer the
identity of the service from the length of the extension. In our
design, requests for multiple services are sent over multicast. If different
services used different padding length, third parties could infer the
service identity from the ESNI length. To prevent this information
leakage, services participating in private discovery MUST set the padded
length to exactly 128 bytes.
The ESNI extension is defined in as:
struct {
CipherSuite suite;
KeyShareEntry key_share;
opaque record_digest<0..2^16-1>;
opaque encrypted_sni<0..2^16-1>;
} ClientEncryptedSNI;
In standard ESNI usage, the "record_digest" identifies the ESNI Encryption Key.
Clients using private discovery MUST leave the "record_digest" empty, and
encode it as a zero-length binary string. The ESNI Encryption Key will be
the Discovery Key of the target server.
The KeyShareEntry is set in accordance with the ESNI specification. It is combined
with the server Discovery Key to encrypt the SNI. According to the ESNI
specification, the encrypted structure contains:
struct {
ServerNameList sni;
opaque zeros[ESNIKeys.padded_length - length(sni)];
} PaddedServerNameList;
struct {
uint8 nonce[16];
PaddedServerNameList realSNI;
} ClientESNIInner;
Servers that receive the extension as part of private discovery attempt to decrypt the
value using their Private Discovery Key. If the decryption succeeds, and if
the decrypted SNI corresponds to the expected value, the server will accept
the discovery request.
The message flows of DTLS 1.3 all start
with the client sending a TLS ClientHello message. The following figure
presents a simple DTLS flow using the ESNI extension for private discovery:
Client Server
ClientHello +----------+
+ key_share* | Flight 1 |
+ ESNI --------> +----------+
ServerHello
+ key_share* +----------+
{EncryptedExtensions} | Flight 2 |
{ESNI} +----------+
{Certificate*}
<-------- {Finished}
[Application Data*]
+----------+
| Flight 3 |
{Finished} --------> +----------+
[Application Data]
+----------+
<-------- [Ack] | Flight 4 |
[Application Data*] +----------+
[Application Data] <-------> [Application Data]
The first flight consists of a single UDP packet. In classic DTLS, this would be
sent to the IP address and UDP port chosen for the application. Instead, the client using
private discovery MUST sent this to the "private discovery" multicast address
defined in and to
the UDP port chosen for the application.
The multicast message sent by the client will be received by many servers.
The servers using private discovery MUST verify that the ESNI extension is
present. If it is present, each server attempts to decrypt the ESNI extension
using the local private discovery key, as specified in .
If the verification succeeds, the server proceeds with the connection, and
sends the second flight of DTLS packets to the IP address and UDP port
from which it received the client's first flight.
The client receiving the second flight of messages processes them as specified in
DTLS 1.3 . The client MUST verify that the ESNI
extension is present, and matches the expected value as specified in
. If the ESNI extension is absent or does not
pass verification, the entire flight MUST be ignored. If the verification
succeeds, the client remembers the IP address and UDP port of the server,
and uses it for the reminder of the session.
A successful ESNI exchange demonstrates to the server that the client has knowledge of
the server discovery key, and to the client that the server is in
possession of the corresponding private discovery key. This is meant to restrict
access to a subset of the client and server population, but does not replace the
need for server authentication and optional client authentication as
specified in TLS 1.3.
The QUIC Transport uses TLS to negotiate encryption keys. The use of TLS in QUIC is
specified in , and can be summarized as follow:
The QUIC connection starts with the client sending an Initial message, carrying
a TLS ClientHello and its extensions.
The server replies with its own Initial message, carrying the server hello and
establishing the "handshake" keys used to protect the reminder of the TLS 1.3
exchange.
Server and client exchange encrypted Handshake messages to verify that the
session is properly established and to negotiate the encryption keys of the
application data.
Server and Client exchange encrypted application messages until they decide to
close the connection.
All messages are sent over UDP.
When using Private Discovery, the client adds an ESNI extension to the ClientHello
sent in the Initial message. The ESNI extension is formatted a specified
in . In classic QUIC, the Initial message would be
sent in a UDP packet to the IP address and UDP port of the server. Instead, the client using
private discovery MUST sent this to the "private discovery" multicast address
defined in and to
the UDP port chosen for the application.
The multicast message sent by the client will be received by many servers.
The servers using private discovery MUST verify that the ESNI extension is
present. If it is present, each server attempts to decrypt the ESNI extension
using the local private discovery key, as specified in .
If the verification succeeds, the server proceeds with the connection, and
sends the next QUIC packets to the IP address and UDP port
from which it received the client's first flight.
The client receiving the second flight of messages processes them as specified in
DTLS 1.3 . The client MUST verify that the ESNI
extension is present, and matches the expected value as specified in
. If the ESNI extension is absent or does not
pass verification, the entire QUIC connection MUST be ignored. If the verification
succeeds, the client remembers the IP address and UDP port of the server,
and uses it for the reminder of the QUIC connection.
The mechanisms discussed in assume that an application
based on DTLS or QUIC is modified to enable private local discovery. This does not
cover all services. Further services can be supported by a two-phase process
in which each application is paired with an implementation of the private
discovery service.
The private discovery service is an implementation of DNS over QUIC, as
specified in , modified to
also implement the Private Discovery over Quic defined in
. The DNS implementation is solely
for the purpose of providing a service equivalent to DNS-SD.
The Private Discovery DNS Service is run by the service that wants
to be discovered. The name of the discovery service is the name of the service
that needs to be discovered. Clients are provisioned with the associated
Discovery Key. Clients discover the Private Discovery DNS Service, and can then
use it to obtain the DNS records associated with the application service:
SRV, TXT, A or AAAA records.
The proposed design relies on active discovery of servers by the clients. When a client
arrives on a new network and wishes to establish a connection to a server, it sends
a multicast message that tries to reach that server. This designs has two
potential issues:
If the server is not present when a client tries to contact it, the client may
have to repeat the connection attempts over time.
If multiple clients connect to the same server, each client sends a multicast
message, which can translate in heavy multicast load in some configurations.
The importance of these two issues is debatable. Many applications have a
peer-to-peer nature, in which peers can be either clients or servers. When two
peers are not present at the same time, the first peer to arrive will fail to
establish a connection, but the second peer will succeed, without having to rely
on time based repetitions.
Similarly, if we move from device oriented discovery to application oriented
discovery, the number of client per server is likely to be very small, so
that there will be little difference between "multicast per client" and
"multicast per server".
However, there may be configurations where a "server arrival announce" message would
result in fast discovery and fewer multicast messages.
The server arrival announce message is a UDP packet sent to the Discovery
Multicast Address reserved in and port %lt;TBD>.
The format of the message will be defined in a next draft version, meeting
the following requirements:
Multiplexing: should be easily demuxed from DTLS or QUIC traffic.
ESNI: should contain an ESNI extension, secured with the server's
discovery key.
Replay: should contain a timestamp and the global scope IPv6 address
of the server.
The use of TLS 1.3 and the ESNI extension provides robust defenses against attacks.
In particular, Private Discovery benefits from the defenses against
dictionary attacks and replay attacks built in the ESNI design. Protections
against a residual DOS attack is discussed in .
The privacy of the discovery relies on keeping the discovery key of
the service secret. The consequences and partial mitigation of leaking the
discovery key are discussed in .
Compromising of the server's private discovery key will allow an
attacker to break the privacy of the discovery, as discussed in .
Attackers may try to disrupt a private discovery handshake by sending a spoofed
Server Hello (DTLS) or a spoofed Server Initial packet (QUIC). The client will
reject these attempts after noticing that the encrypted extensions do not include
a proper ESNI extension, containing the expected copy of the ESNI nonce.
Attackers will not succeed spoofing the server, but they could succeed in denying
the connection if the fake response arrives before the response from the actual
server, and if the implementation just gave up the attempt after failing to validate
the first response that it received.
To defend against this attack,
implementations SHOULD keep listening for responses and
attempting validation until they receive at least one valid response from the
expected server.
The Discovery Key is known by all the authorized clients. If one of these clients
is compromised, the privacy of the server will be compromised: attackers
will be able to spoof the authorized client and discover whether the server
is present on a local network. However, the leak can only be exploited in
an active attack: the attacker must actively set up a connection with the
target server.
The attack is mitigated when the server migrates to a different discovery
key and restricts the availability of that key to non-compromised clients.
Exploiting a compromised discovery key normally requires that the attacker
is present on the same link as the target. Attackers might try to work
around that limitation by sending unicast packet targeted at plausible
server locations. Servers participating in private discovery MUST NOT
accept discovery requests arriving from off-link sources.
The private component of the asymmetric key pair used for discovery MUST
be kept secret by the server. If it is compromised, attackers can
process discovery requests and verify that they can be decrypted with
the server's private discovery key. They could also process logs
of old discovery attempts.
The design provides two mitigations against the consequences of this
failure:
The discovery requests do not uniquely identify the client, and the attacker
will only know that an attempt came from one of the authorized clients.
The actual communications are protected by TLS, and inherit the
forward secrecy properties of TLS 1.3.
[[TODO: consider specifying a way to rotate the discovery key, so as to
mitigate the lack of forward secrecy. Maybe add that to ESNI. ]]
Suppose that an attacker has identified a client, and is capable of
recording the multicast messages from that client. The attacker can
then replay the message, triggering a response from the target server
if present on the network.
The attacker will not be able to actually establish a connection with
the server -- the TSL and ESNI designs protect against that. But it
will be able to find out that the same server that responded to the
client before responds now, which is a way to track the server.
The attacker can mount two variations of the attack: replay over time,
and replay at different locations. In the current design, the main
protection against that attack is the implementation of a "discovery
window", so that servers only listen to multicast requests when they
are "ready to be discovered".
[[TODO: consider adding a time stamp in an extension to ESNI.]]
[[TODO: consider adding the IPv6 address of the sender in an extension to ESNI.]]
[[TODO: special consideration for server arrival announce.]]
IANA is required to allocate the
IPv6 multicast address FF02::<TBD> for use
as "Private Discovery Multicast Address" described in this document.
**RFC Editor's Note:** Please remove this section prior to
publication of a final version of this document.
Early experiments MAY use the address FF02::60DB:F6C5.
This address is marked in the IANA
registry as unassigned.
[[TODO]]
&rfc2119;
&rfc6763;
&rfc8446;
&I-D.ietf-tls-dtls13;
&I-D.ietf-tls-esni;
&I-D.ietf-quic-transport;
&I-D.ietf-quic-tls;
&I-D.huitema-quic-dnsoquic;
&rfc6762;
&I-D.ietf-dnssd-prireq;
Adding Privacy to Multicast DNS Service DiscoveryEfficient Privacy Preserving Multicast DNS Service Discovery