Skip to content

Commit 99e6e5f

Browse files
committed
Simplify
1 parent 78576c5 commit 99e6e5f

1 file changed

Lines changed: 95 additions & 21 deletions

File tree

‎draft-denis-dprive-dnscrypt.md‎

Lines changed: 95 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ The DNSCrypt protocol is designed to encrypt and authenticate DNS traffic betwee
3737

3838
# Introduction
3939

40-
The Domain Name System (DNS) {{!RFC1035}} is a critical component of Internet infrastructure, but its original design did not include security features to protect the confidentiality and integrity of queries and responses. This fundamental security gap exposes DNS traffic to eavesdropping, tampering, and various attacks that can compromise user privacy and network security.
41-
42-
To address these vulnerabilities, this document defines the DNSCrypt protocol, which encrypts and authenticates DNS queries and responses, providing strong confidentiality, integrity, and resistance to attacks affecting the original DNS protocol. The protocol is designed to be lightweight, extensible, and simple to implement securely on top of existing DNS infrastructure, offering a practical solution for securing DNS communications without requiring significant changes to current systems.
40+
DNSCrypt encrypts and authenticates DNS traffic between clients and resolvers.
41+
It uses signed resolver certificates, unauthenticated certificate retrieval,
42+
authenticated encryption for queries and responses, and optional relaying
43+
through Anonymized DNSCrypt.
4344

4445
# Conventions And Definitions
4546

@@ -179,18 +180,18 @@ The protocol operates as follows:
179180

180181
1. The DNSCrypt client sends a DNS query to a DNSCrypt server to retrieve the server's certificates.
181182
2. The client generates the client key-exchange value required by the selected certificate.
182-
3. The client encrypts unmodified DNS queries using the selected certificate, padding them as necessary, and concatenates them to `<client-magic>`, `<client-pk>`, and `<client-nonce>`. The resulting output is transmitted to the server via standard DNS transport mechanisms {{!RFC1035}}.
183+
3. The client encrypts unmodified DNS queries using the selected certificate, padding them as necessary, and concatenates them to `<client-magic>`, `<client-pk>`, and `<client-nonce>`. The resulting output is transmitted to the server over UDP or TCP.
183184
4. Encrypted queries are decrypted by the server using the query's `<client-pk>` field and the resolver secret key corresponding to the selected certificate. The output is a regular DNS packet that doesn't require any special processing.
184-
5. To send an encrypted response, the server adds padding to the unmodified response, encrypts the result using the shared key and a nonce made of the client's nonce followed by the resolver's nonce, and truncates the response if necessary. The resulting packet, truncated or not, is sent to the client using standard DNS mechanisms.
185+
5. To send an encrypted response, the server adds padding to the unmodified response, encrypts the result using the shared key and a nonce made of the client's nonce followed by the resolver's nonce, and truncates the response if necessary. The resulting packet, truncated or not, is sent to the client over the same transport.
185186
6. The client authenticates and decrypts the response using the shared key and the nonce included in the response. If the response was truncated, the client MAY adjust internal parameters and retry over TCP {{!RFC7766}}. If not, the output is a regular DNS response that can be directly forwarded to applications and stub resolvers.
186187

187188
Key features of the DNSCrypt protocol include:
188189

189-
- Stateless operation: Every query can be processed independently from other queries, with no session identifiers required.
190-
- Flexible key management: Clients can replace their keys whenever they want, without extra interactions with servers.
191-
- Proxy support: DNSCrypt packets can securely be proxied without having to be decrypted, allowing client IP addresses to be hidden from resolvers ("Anonymized DNSCrypt").
192-
- Shared infrastructure: Recursive DNS servers can accept DNSCrypt queries on the same IP address and port used for regular DNS traffic.
193-
- Attack mitigation: DNSCrypt mitigates two common security vulnerabilities in regular DNS over UDP: amplification {{!RFC5358}} and fragmentation attacks.
190+
- Stateless operation: every query can be processed independently, with no session identifiers required.
191+
- Fresh client key-exchange values: clients can generate new key-exchange values as often as allowed by the selected encryption system, without extra interactions with resolvers.
192+
- Proxy support: DNSCrypt packets can be relayed without being decrypted, allowing client IP addresses to be hidden from resolvers with Anonymized DNSCrypt.
193+
- Shared infrastructure: recursive DNS servers can accept DNSCrypt queries on the same IP address and port used for ordinary DNS traffic.
194+
- Attack mitigation: DNSCrypt limits UDP response size, supports padding, and uses TCP retry to reduce amplification and fragmentation risk {{!RFC5358}}.
194195

195196
## Transport
196197

@@ -199,8 +200,6 @@ DNSCrypt clients and resolvers SHOULD support the protocol via UDP, and MUST sup
199200

200201
Both TCP and UDP connections using DNSCrypt SHOULD employ port 443 by default.
201202

202-
The choice of port 443 helps DNSCrypt traffic blend with HTTPS traffic, providing some protection against traffic analysis.
203-
204203
## DNS Wire Conventions Used Here
205204

206205
Except where a cryptographic primitive explicitly says otherwise, all multi-byte
@@ -218,7 +217,7 @@ A DNS message starts with the 12-byte DNS header:
218217

219218
The DNS flags field uses the ordinary DNS bit assignments. The bits used by
220219
this document are QR (`0x8000`), AA (`0x0400`), TC (`0x0200`), RD (`0x0100`),
221-
and RA (`0x0080`).
220+
RA (`0x0080`), and CD (`0x0010`).
222221

223222
A DNS name in a query is encoded as a sequence of labels. Each label is one
224223
length octet, followed by that many bytes. The name ends with a zero length
@@ -245,6 +244,41 @@ character-string is a one-byte length followed by up to 255 bytes. A DNSCrypt
245244
certificate carried in a `TXT` record is reconstructed by concatenating those
246245
character-string payloads in order, excluding the one-byte length fields.
247246

247+
A successful certificate response echoes the single question and contains zero
248+
or more `TXT` answer records, one certificate per answer record. A response that
249+
does not contain the complete certificate set because of a UDP size limit sets
250+
the DNS `TC` flag. A successful certificate response uses these DNS header
251+
fields:
252+
253+
| Header field | Value |
254+
| ------------ | ----------------------------------------------- |
255+
| ID | copied from the query |
256+
| Flags | QR set, TC set only when truncated, RCODE = 0 |
257+
| QDCOUNT | 1 |
258+
| ANCOUNT | number of certificate `TXT` answers included |
259+
| NSCOUNT | 0 |
260+
| ARCOUNT | 0 |
261+
262+
Resolvers MAY set ordinary DNS flags such as `AA` or `RA`, and MAY copy `RD`
263+
or `CD` from the query. Clients MUST ignore those flags for certificate
264+
validation. A client uses `TC` only to decide whether to retry the certificate
265+
query over TCP or with a larger padded UDP query.
266+
267+
Each certificate answer is a `TXT` RR:
268+
269+
| RR field | Value |
270+
| -------- | ----------------------------------------------- |
271+
| NAME | `0xc0 0x0c`, or the uncompressed question name |
272+
| TYPE | `TXT` (`0x00 0x10`) |
273+
| CLASS | `IN` (`0x00 0x01`) |
274+
| TTL | 4-byte DNS TTL; not the certificate validity |
275+
| RDLENGTH | length in bytes of the TXT RDATA |
276+
| RDATA | certificate split into TXT character-strings |
277+
278+
The response does not echo the query's EDNS(0) `OPT` pseudo-RR. Certificate
279+
validity is determined only by `<ts-start>` and `<ts-end>` inside the signed
280+
certificate, not by the DNS TTL.
281+
248282
When a UDP certificate query uses EDNS(0) padding, the additional record is an
249283
`OPT` pseudo-RR. It has root owner name (`0x00`), type `OPT` (`0x00 0x29`), a
250284
two-byte UDP payload size, four bytes of extended RCODE/version/flags, and an
@@ -290,7 +324,7 @@ source port.
290324
After receiving a query, a resolver MAY ignore it or send an encrypted DNSCrypt
291325
response.
292326

293-
The client MUST authenticate and, if authentication succeeds, decrypt the response with the help of the resolver's public key, the shared secret, and the response nonce. The client MUST verify that the `<client-nonce>` prefix of the response nonce matches a currently outstanding query. In case the response fails verification, or the `<client-nonce>` does not match a currently outstanding query, it MUST be disregarded by the client.
327+
The client MUST authenticate and, if authentication succeeds, decrypt the response using the derived shared key and the response nonce. The client MUST verify that the `<client-nonce>` prefix of the response nonce matches a currently outstanding query. In case the response fails verification, or the `<client-nonce>` does not match a currently outstanding query, it MUST be disregarded by the client.
294328

295329
If the response has the TC flag set, the client MUST:
296330

@@ -403,7 +437,7 @@ The following diagram shows the structure of a DNSCrypt certificate:
403437
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
404438
~~~
405439

406-
To initiate a DNSCrypt session, a client transmits an ordinary unencrypted `TXT` DNS query to the resolver's IP address and DNSCrypt port. A client MAY use UDP or TCP according to local policy. A common strategy is to try UDP first and retry over TCP after failure, timeout, or truncation.
440+
To initiate a DNSCrypt session, a client transmits an ordinary unencrypted `TXT` DNS query to the resolver's IP address and DNSCrypt port. A client MAY use UDP or TCP according to local policy. A common strategy is to try UDP first and retry over TCP after failure, timeout, or truncation. Over TCP, the certificate query and response are DNS messages framed with the two-byte big-endian DNS-over-TCP length prefix {{!RFC7766}}; the prefix is not part of the DNS message.
407441

408442
Resolvers are not required to serve certificates both on UDP and TCP.
409443

@@ -706,7 +740,7 @@ Relays MUST:
706740
- Check that the target IP is not in a private, loopback, link-local, multicast, unspecified, or otherwise locally routed range
707741
- Verify the port number is in an allowed range
708742
- Ensure the inner `<dnscrypt-query>` doesn't start with `<anon-magic>`
709-
- Reject the inner `<dnscrypt-query>` if its first 8 bytes are `0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01`, to avoid protocol confusion with QUIC {{!RFC9000}}; relays MAY reject broader reserved prefixes by local policy
743+
- Reject the inner `<dnscrypt-query>` if its first 8 bytes are `0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01`, to avoid protocol confusion with QUIC {{!RFC9000}}
710744
4. Forward the inner `<dnscrypt-query>` unmodified to the target server over UDP, without the Anonymized DNSCrypt prefix
711745
5. Verify server responses:
712746

@@ -717,7 +751,49 @@ Relays MUST:
717751

718752
Address validation is performed after decoding `<server-ip>`. If the decoded address is an IPv4-mapped IPv6 address, the relay applies the IPv4 policy to the embedded IPv4 address. Relay operators SHOULD maintain an explicit allowlist or denylist of target ranges. At minimum, relays MUST reject targets that are not globally routable, including unspecified, loopback, link-local, multicast, private-use, unique-local, documentation, benchmarking, and other special-use addresses.
719753

720-
These relay requirements ensure that anonymization does not compromise the security properties of the underlying DNSCrypt protocol. Proper deployment requires additional operational considerations.
754+
If relay validation fails, the relay MUST NOT forward the inner packet. For a
755+
UDP client, the relay sends no response. For a TCP client, the relay closes the
756+
connection without sending a length-prefixed response. The same behavior applies
757+
to upstream responses that fail validation or exceed the response-size rule.
758+
759+
The mandatory QUIC-confusion check above is intentionally the exact 8-byte
760+
value. The broader rule that `<client-magic>` MUST NOT start with seven zero
761+
bytes is enforced when resolvers issue certificates. A relay cannot classify
762+
every inner packet by the first eight bytes alone, because the inner packet can
763+
also be an unencrypted certificate query. Relay operators MAY reject broader
764+
reserved prefixes by local policy after first recognizing valid certificate
765+
queries.
766+
767+
A relay recognizes an inner certificate query by parsing it as a DNS message
768+
with `QR = 0`, `QDCOUNT = 1`, question type `TXT`, question class `IN`, and a
769+
question name that starts with `2.dnscrypt-cert.`. Relays are not required to
770+
support non-standard provider names through Anonymized DNSCrypt; clients using
771+
such names can retrieve certificates directly from the resolver.
772+
773+
An encrypted upstream response is valid for relaying if all of these are true:
774+
775+
- The response came from the target IP address and port selected by the prefix.
776+
- The response is no larger than the inner query forwarded upstream.
777+
- The response starts with `<resolver-magic>`.
778+
779+
No stronger encrypted-response matching is required at the relay. The relay
780+
does not decrypt the packet, does not know the selected certificate, and cannot
781+
in general know the offset of `<client-nonce>` because the `<client-pk>` length
782+
depends on the encryption system and resumed PQ queries use a different shape.
783+
The client performs nonce matching after decryption.
784+
785+
A certificate upstream response is valid for relaying if all of these are true:
786+
787+
- The response came from the target IP address and port selected by the prefix.
788+
- The response is no larger than the inner certificate query forwarded upstream.
789+
- The response is a DNS response (`QR = 1`) and has the same transaction ID as
790+
the relayed certificate query.
791+
- The response contains exactly one question whose name, type, and class match
792+
the relayed certificate query.
793+
- The matching question name starts with `2.dnscrypt-cert.`.
794+
795+
The relay does not need to validate certificate signatures or parse every TXT
796+
answer. The client verifies certificates after receiving the relayed response.
721797

722798
## Operational Considerations
723799

@@ -730,11 +806,9 @@ When using Anonymized DNSCrypt:
730806
- Restrict allowed server ports (typically only allowing port 443)
731807
- Monitor for abuse
732808

733-
These operational guidelines help ensure that Anonymized DNSCrypt deployments provide the intended privacy benefits while maintaining security and preventing abuse.
734-
735809
# Post-Quantum Key Exchange (PQDNSCrypt)
736810

737-
The key exchange described so far relies on X25519 {{!RFC7748}}, which a sufficiently capable quantum computer would be able to break. An attacker who records DNSCrypt traffic today could therefore decrypt it once such a computer exists. This section defines the PQ extension, which performs the key exchange with a hybrid post-quantum mechanism while leaving the rest of the protocol unchanged: the certificate system, the packet framing, the authenticated encryption, the nonces, the padding philosophy, and Anonymized DNSCrypt all carry over. A DNSCrypt deployment that uses this extension is referred to as PQDNSCrypt.
811+
The classical `Box-XChaChaPoly` encryption system relies on X25519 {{!RFC7748}}, which a sufficiently capable quantum computer would be able to break. An attacker who records classical DNSCrypt traffic today could therefore decrypt it once such a computer exists. This section defines the PQ extension, which performs the key exchange with a hybrid post-quantum mechanism while leaving the rest of the protocol unchanged: the certificate system, the packet framing, the authenticated encryption, the nonces, the padding philosophy, and Anonymized DNSCrypt all carry over. A DNSCrypt deployment that uses this extension is referred to as PQDNSCrypt.
738812

739813
PQ is introduced as a new encryption system version (`<es-version>` `0x00 0x03`) inside the existing version 2 certificate format. It is not a new major protocol version, and it does not change the certificate lookup name. A resolver MAY advertise a PQ certificate alongside a classical certificate under the same provider name, and a client that does not implement PQ ignores the `<es-version>` value it does not recognize, exactly as already required.
740814

@@ -1185,7 +1259,7 @@ The successful response carrying the 124-byte certificate above is 182 bytes. Th
11851259

11861260
~~~
11871261
certificate response with one TXT answer (182 bytes):
1188-
abcd8481000100010000000001320d646e7363727970742d6365727407657861
1262+
abcd8180000100010000000001320d646e7363727970742d6365727407657861
11891263
6d706c6503636f6d0000100001c00c0010000100015180007d7c444e53430002
11901264
00003a570ea17f47b80217977fbb455840bfd50ab32f5fbf2aabc173a6a49b7a
11911265
49ca55362a6c5dec47657cf515e9f99382a316dfecd964b94d1c4659cac45961

0 commit comments

Comments
 (0)