Skip to content

Commit 561fc6f

Browse files
committed
Reorganize
1 parent f191de7 commit 561fc6f

1 file changed

Lines changed: 93 additions & 129 deletions

File tree

draft-denis-dprive-dnscrypt.md

Lines changed: 93 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -33,45 +33,24 @@ The Domain Name System (DNS) {{!RFC1035}} is a critical component of Internet in
3333

3434
The protocol is designed to be lightweight, extensible, and simple to implement securely on top of an existing DNS client, server or proxy. It provides a standardized approach to securing DNS communications while maintaining compatibility with existing DNS infrastructure.
3535

36-
Key features of the DNSCrypt protocol include:
37-
38-
- Stateless operation: Every query can be processed independently from other queries, with no session identifiers required.
39-
- Flexible key management: Clients can replace their keys whenever they want, without extra interactions with servers.
40-
- Proxy support: DNSCrypt packets can securely be proxied without having to be decrypted, allowing client IP addresses to be hidden from resolvers ("Anonymized DNSCrypt").
41-
- Shared infrastructure: Recursive DNS servers can accept DNSCrypt queries on the same IP address and port used for regular DNS traffic.
42-
- Attack mitigation: DNSCrypt mitigates two common security vulnerabilities in regular DNS over UDP: amplification and fragmentation attacks.
43-
44-
The protocol uses modern cryptographic primitives including X25519 {{!RFC7748}} for key exchange and XChaCha20-Poly1305 {{!RFC8439}} for authenticated encryption, providing strong security guarantees while maintaining high performance.
45-
46-
This document specifies version 2 of the DNSCrypt protocol, which represents the current recommended version for implementation.
47-
48-
DNS packets do not need to be parsed or rewritten. DNSCrypt simply wraps them in a secure, encrypted container. Encrypted packets are then exchanged the same way as regular packets, using the standard DNS transport mechanisms. Queries and responses are sent over UDP, falling back to TCP for large responses only if necessary.
49-
50-
DNSCrypt is stateless. Every query can be processed independently from other queries. There are no session identifiers. In order to better defend against fingerprinting, clients can replace their keys whenever they want, without extra interactions with servers.
51-
52-
DNSCrypt packets can securely be proxied without having to be decrypted, allowing client IP addresses to be hidden from resolvers ("Anonymized DNSCrypt").
53-
54-
Recursive DNS servers can accept DNSCrypt queries on the same IP address and port used for regular DNS traffic. Similarly, DNSCrypt and DoH can also share the same IP address and TCP port.
55-
56-
Lastly, DNSCrypt mitigates two common security vulnerabilities in regular DNS over UDP: amplification and fragmentation attacks.
57-
5836
# Conventions And Definitions
5937

6038
{::boilerplate bcp14-tagged}
6139

40+
## Protocol Components
41+
6242
Definitions for client queries:
6343

6444
- `<dnscrypt-query>`: `<client-magic>` `<client-pk>` `<client-nonce>` `<encrypted-query>`
65-
- `<client-magic>`: a 8 byte identifier for the resolver certificate
66-
chosen by the client.
45+
- `<client-magic>`: a 8 byte identifier for the resolver certificate chosen by the client.
6746
- `<client-pk>`: the client's public key, whose length depends on the encryption algorithm defined in the chosen certificate.
6847
- `<client-sk>`: the client's secret key.
6948
- `<resolver-pk>`: the resolver's public key.
7049
- `<client-nonce>`: a unique query identifier for a given (`<client-sk>`, `<resolver-pk>`) tuple. The same query sent twice for the same (`<client-sk>`, `<resolver-pk>`) tuple MUST use two distinct `<client-nonce>` values. The length of `<client-nonce>` is determined by the chosen encryption algorithm.
7150
- `AE`: the authenticated encryption function.
7251
- `<encrypted-query>`: `AE(<shared-key> <client-nonce> <client-nonce-pad>, <client-query> <client-query-pad>)`
7352
- `<shared-key>`: the shared key derived from `<resolver-pk>` and `<client-sk>`, using the key exchange algorithm defined in the chosen certificate.
74-
-`<client-query>`: the unencrypted client query. The query is not modified; in particular, the query flags are not altered and the query length MUST be kept in queries prepared to be sent over TCP.
53+
- `<client-query>`: the unencrypted client query. The query is not modified; in particular, the query flags are not altered and the query length MUST be kept in queries prepared to be sent over TCP.
7554
- `<client-nonce-pad>`: `<client-nonce>` length is half the nonce length required by the encryption algorithm. In client queries, the other half, `<client-nonce-pad>` is filled with NUL bytes.
7655
- `<client-query-pad>`: the variable-length padding.
7756

@@ -90,8 +69,9 @@ Definitions for server responses:
9069
- `<resolver-response>`: the unencrypted resolver response. The response is not modified; in particular, the query flags are not altered and the response length MUST be kept in responses prepared to be sent over TCP.
9170
- `<resolver-response-pad>`: the variable-length padding.
9271

72+
# Protocol Description
9373

94-
# Protocol Overview
74+
## Overview
9575

9676
The DNSCrypt protocol operates through the following steps:
9777

@@ -102,14 +82,22 @@ The DNSCrypt protocol operates through the following steps:
10282
5. To send an encrypted response, the server adds padding to the unmodified response, encrypts the result using the client's public key and the client's nonce, and truncates the response if necessary. The resulting packet, truncated or not, is sent to the client using standard DNS mechanisms.
10383
6. The client authenticates and decrypts the response using its secret key, the server's public key, the client's nonce included in the response, and the client's original nonce. If the response was truncated, the client MAY adjust internal parameters and retry over TCP. If not, the output is a regular DNS response that can be directly forwarded to applications and stub resolvers.
10484

105-
# Key Management
85+
Key features of the DNSCrypt protocol include:
10686

107-
Both clients and resolvers generate short-term key pairs for each encryption system they support.
87+
- Stateless operation: Every query can be processed independently from other queries, with no session identifiers required.
88+
- Flexible key management: Clients can replace their keys whenever they want, without extra interactions with servers.
89+
- Proxy support: DNSCrypt packets can securely be proxied without having to be decrypted, allowing client IP addresses to be hidden from resolvers ("Anonymized DNSCrypt").
90+
- Shared infrastructure: Recursive DNS servers can accept DNSCrypt queries on the same IP address and port used for regular DNS traffic.
91+
- Attack mitigation: DNSCrypt mitigates two common security vulnerabilities in regular DNS over UDP: amplification and fragmentation attacks.
10892

109-
Clients generate unique key pairs for each resolver they communicate with, while resolvers create individual key pairs for every client they interact with. Additionally, the resolver creates a public key for each encryption system it supports.
93+
## Transport
11094

95+
The DNSCrypt protocol can use the UDP and TCP transport protocols.
96+
DNSCrypt clients and resolvers SHOULD support the protocol via UDP, and MUST support it over TCP.
97+
98+
Both TCP and UDP connections using DNSCrypt SHOULD employ port 443 by default.
11199

112-
# Session Establishment
100+
## Session Establishment
113101

114102
From the client's perspective, a DNSCrypt session is initiated when the client sends an unauthenticated DNS query to a DNSCrypt-capable resolver. This DNS query contains encoded information about the certificate versions supported by the client and a public identifier of the desired provider.
115103

@@ -123,14 +111,9 @@ The encryption algorithm, resolver public key, and client magic number from the
123111

124112
With the knowledge of the chosen certificate and corresponding secret key, along with the client's public key, the resolver is able to verify, decrypt the query, and then encrypt the response utilizing identical parameters.
125113

126-
# Transport
114+
## Query Processing
127115

128-
The DNSCrypt protocol can use the UDP and TCP transport protocols.
129-
DNSCrypt clients and resolvers SHOULD support the protocol via UDP, and MUST support it over TCP.
130-
131-
Both TCP and UDP connections using DNSCrypt SHOULD employ port 443 by default.
132-
133-
# Padding For Client Queries Over UDP
116+
### Padding For Client Queries Over UDP
134117

135118
Before encryption takes place, queries are padded according to the ISO/IEC 7816-4 standard. Padding begins with a single byte holding the value `0x80`, succeeded by any number of `NUL` bytes.
136119

@@ -141,7 +124,7 @@ Should the client query's length fall short of `<min-query-len>` bytes, the pad
141124

142125
`<min-query-len>` is a variable length, initially set to 256 bytes, and MUST be a multiple of 64 bytes. It represents the minimum permitted length for a client query, inclusive of padding.
143126

144-
# Client Queries Over UDP
127+
### Client Queries Over UDP
145128

146129
UDP-based client queries need to follow the padding guidelines outlined in section 3.
147130

@@ -164,7 +147,7 @@ If the response has the TC flag set, the client MUST:
164147

165148
The client MAY decrease `<min-query-len>`, but the length MUST remain a multiple of 64 bytes.
166149

167-
# Padding For Client Queries Over TCP
150+
### Padding For Client Queries Over TCP
168151

169152
Queries MUST undergo padding using the ISO/IEC 7816-4 format before being encrypted. The padding starts with a byte valued `0x80` followed by a
170153
variable number of NUL bytes.
@@ -187,8 +170,7 @@ or
187170

188171
`<56-bytes-query> 0x80 (0x00 * 199)`
189172

190-
191-
# Client Queries Over TCP
173+
### Client Queries Over TCP
192174

193175
The sole differences between encrypted client queries transmitted via TCP and those sent using UDP lie in the padding length calculation and the inclusion of a length prefix, represented as two big-endian bytes.
194176

@@ -198,25 +180,7 @@ Unlike UDP queries, a query sent over TCP can be shorter than the response.
198180

199181
After having received a response from the resolver, the client and the resolver MUST close the TCP connection to ensure security and comply with this revision of the protocol, which prohibits multiple transactions over the same TCP connection.
200182

201-
# Authenticated Encryption And Key Exchange Algorithm
202-
203-
The `Box-XChaChaPoly` construction, and the way to use it described in this section, MUST be referenced in certificates as version `2` of the public-key authenticated encryption system.
204-
205-
The construction, originally implemented in the libsodium cryptographic library and exposed under the name "crypto_box_curve25519xchacha20poly1305", uses the Curve25119 elliptic curve in Montgomery form and the `hchacha20` hash function for key exchange, the `XChaCha20` stream cipher, and `Poly1305` for message authentication.
206-
207-
The public and secret keys are 32 bytes long in storage. The MAC is 16 bytes long, and is prepended to the ciphertext.
208-
209-
When using `Box-XChaChaPoly`, this construction necessitates the use of a 24 bytes nonce, that MUST NOT be reused for a given shared secret.
210-
211-
With a 24 bytes nonce, a question sent by a DNSCrypt client must be encrypted using the shared secret, and a nonce constructed as follows: 12 bytes chosen by the client followed by 12 NUL (`0x00`) bytes.
212-
213-
A response to this question MUST be encrypted using the shared secret, and a nonce constructed as follows: the bytes originally chosen by the client, followed by bytes chosen by the resolver.
214-
215-
Randomly selecting the resolver's portion of the nonce is RECOMMENDED.
216-
217-
The client's half of the nonce MAY include a timestamp in addition to a counter or to random bytes. Incorporating a timestamp allows for prompt elimination of responses to queries that were sent too long ago or are dated in the future. This practice enhances security and prevents potential replay attacks.
218-
219-
# Certificates
183+
## Certificates
220184

221185
To initiate a DNSCrypt session, a client transmits an ordinary unencrypted `TXT` DNS query to the resolver's IP address and DNSCrypt port. The attempt is first made using UDP; if unsuccessful due to failure, timeout, or truncation, the client then proceeds with TCP.
222186

@@ -287,6 +251,8 @@ Multiple implementations of the protocol described in this document have been de
287251

288252
# Security Considerations
289253

254+
This section discusses security considerations for the DNSCrypt protocol.
255+
290256
## Protocol Security
291257

292258
The DNSCrypt protocol provides several security benefits:
@@ -365,6 +331,73 @@ As a client is likely to reuse the same key pair many times, servers are encoura
365331

366332
This document has no IANA actions.
367333

334+
# Anonymized DNSCrypt
335+
336+
While DNSCrypt encrypts DNS traffic, DNS server operators can still observe client IP addresses. Anonymized DNSCrypt is an extension to the DNSCrypt protocol that allows queries and responses to be relayed by an intermediate server, hiding the client's IP address from the resolver.
337+
338+
## Protocol Overview
339+
340+
Anonymized DNSCrypt works by having the client send encrypted queries to a relay server, which then forwards them to the actual DNSCrypt resolver. The relay server cannot decrypt the queries or responses, and the resolver only sees the relay's IP address.
341+
342+
~~~
343+
[Client]----(encrypted query)--->[Relay]----(encrypted query)--->[Server]
344+
[Client]<--(encrypted response)--[Relay]<--(encrypted response)--[Server]
345+
~~~
346+
347+
Key properties of Anonymized DNSCrypt:
348+
349+
- The relay cannot decrypt or modify queries and responses
350+
- The resolver only sees the relay's IP address, not the client's
351+
- A DNSCrypt server can simultaneously act as a relay
352+
- The protocol works over both UDP and TCP
353+
354+
## Client Queries
355+
356+
An Anonymized DNSCrypt query is a standard DNSCrypt query prefixed with information about the target server:
357+
358+
~~~
359+
<anondnscrypt-query> ::= <anon-magic> <server-ip> <server-port> <dnscrypt-query>
360+
~~~
361+
362+
Where:
363+
- `<anon-magic>`: `0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00`
364+
- `<server-ip>`: 16 bytes encoded IPv6 address (IPv4 addresses are mapped to IPv6 using `::ffff:<ipv4 address>`)
365+
- `<server-port>`: 2 bytes in big-endian format
366+
- `<dnscrypt-query>`: standard DNSCrypt query
367+
368+
For example, a query for a server at 192.0.2.1:443 would be prefixed with:
369+
~~~
370+
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00
371+
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xff 0xff 0xc0 0x00 0x02 0x01
372+
0x01 0xbb
373+
~~~
374+
375+
## Relay Behavior
376+
377+
Relays MUST:
378+
1. Accept queries over both TCP and UDP
379+
2. Communicate with upstream servers over UDP, even if client queries were sent over TCP
380+
3. Validate incoming packets:
381+
- Check that the target IP is not in a private range
382+
- Verify the port number is in an allowed range
383+
- Ensure the DNSCrypt query doesn't start with `<anon-magic>`
384+
- Verify the query doesn't start with 7 zero bytes (to avoid confusion with QUIC)
385+
4. Forward valid queries unmodified to the server
386+
5. Verify server responses:
387+
- Check that the response is smaller than the query
388+
- Validate the response format (either starts with resolver magic or is a certificate response)
389+
- Forward valid responses unmodified to the client
390+
391+
## Operational Considerations
392+
393+
When using Anonymized DNSCrypt:
394+
1. Clients should choose relays and servers operated by different entities
395+
2. Having relays and servers on different networks is recommended
396+
3. Relay operators should:
397+
- Refuse forwarding to reserved IP ranges
398+
- Restrict allowed server ports (typically only allowing port 443)
399+
- Monitor for abuse
400+
368401
# Appendix 1: The Box-XChaChaPoly Algorithm
369402

370403
The `Box-XChaChaPoly` algorithm combines the `X25519` {{!RFC7748}} key exchange mechanism with a variant of the ChaCha20-Poly1305 construction specified in {{!RFC8439}}.
@@ -466,72 +499,3 @@ The Box-XChaChaPoly algorithm combines the key exchange mechanism X25519 defined
466499
- `<sk>`: sender's secret key
467500
- `<sk'>`: `HChaCha20(X25519(<pk>, <sk>))`
468501
- `Box-XChaChaPoly(pk, sk, m)`: `XChaCha20_DJB-Poly1305(<sk'>, <m>)`
469-
470-
# Anonymized DNSCrypt
471-
472-
While DNSCrypt encrypts DNS traffic, DNS server operators can still observe client IP addresses. Anonymized DNSCrypt is an extension to the DNSCrypt protocol that allows queries and responses to be relayed by an intermediate server, hiding the client's IP address from the resolver.
473-
474-
## Protocol Overview
475-
476-
Anonymized DNSCrypt works by having the client send encrypted queries to a relay server, which then forwards them to the actual DNSCrypt resolver. The relay server cannot decrypt the queries or responses, and the resolver only sees the relay's IP address.
477-
478-
```
479-
[Client]----(encrypted query)--->[Relay]----(encrypted query)--->[Server]
480-
[Client]<--(encrypted response)--[Relay]<--(encrypted response)--[Server]
481-
```
482-
483-
Key properties of Anonymized DNSCrypt:
484-
485-
- The relay cannot decrypt or modify queries and responses
486-
- The resolver only sees the relay's IP address, not the client's
487-
- A DNSCrypt server can simultaneously act as a relay
488-
- The protocol works over both UDP and TCP
489-
490-
## Client Queries
491-
492-
An Anonymized DNSCrypt query is a standard DNSCrypt query prefixed with information about the target server:
493-
494-
```
495-
<anondnscrypt-query> ::= <anon-magic> <server-ip> <server-port> <dnscrypt-query>
496-
```
497-
498-
Where:
499-
- `<anon-magic>`: `0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00`
500-
- `<server-ip>`: 16 bytes encoded IPv6 address (IPv4 addresses are mapped to IPv6 using `::ffff:<ipv4 address>`)
501-
- `<server-port>`: 2 bytes in big-endian format
502-
- `<dnscrypt-query>`: standard DNSCrypt query
503-
504-
For example, a query for a server at 192.0.2.1:443 would be prefixed with:
505-
```
506-
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00
507-
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xff 0xff 0xc0 0x00 0x02 0x01
508-
0x01 0xbb
509-
```
510-
511-
## Relay Behavior
512-
513-
Relays MUST:
514-
1. Accept queries over both TCP and UDP
515-
2. Communicate with upstream servers over UDP, even if client queries were sent over TCP
516-
3. Validate incoming packets:
517-
- Check that the target IP is not in a private range
518-
- Verify the port number is in an allowed range
519-
- Ensure the DNSCrypt query doesn't start with `<anon-magic>`
520-
- Verify the query doesn't start with 7 zero bytes (to avoid confusion with QUIC)
521-
4. Forward valid queries unmodified to the server
522-
5. Verify server responses:
523-
- Check that the response is smaller than the query
524-
- Validate the response format (either starts with resolver magic or is a certificate response)
525-
- Forward valid responses unmodified to the client
526-
527-
## Operational Considerations
528-
529-
When using Anonymized DNSCrypt:
530-
1. Clients should choose relays and servers operated by different entities
531-
2. Having relays and servers on different networks is recommended
532-
3. Relay operators should:
533-
- Refuse forwarding to reserved IP ranges
534-
- Restrict allowed server ports (typically only allowing port 443)
535-
- Monitor for abuse
536-
537-
--- back

0 commit comments

Comments
 (0)