Skip to content
Frank Denis edited this page Oct 8, 2018 · 29 revisions

DNS Stamps

Server stamps encode all the parameters required to connect to a secure DNS server as a single string. Think about stamps as QR code, but for DNS.

Online DNS stamp calculator

Stamps can be quickly viewed/modified/created using this VueJS component.

An online demo is accessible here: https://stamps.dnscrypt.info

An example list of public secure DNS resolvers, with their DNS stamps.

DNSCrypt stamps

Format:

"sdns://" || base64url(0x01 || props || len(addr) || addr ||
                       len(pk) || pk || len(providerName) || providerName)

|| is the concatenation operator.

0x01 is the protocol identifier for DNSCrypt.

props is a small-endian 64 bit value that represents informal properties about the resolver. It is a logical OR combination of the following values:

  • 1: the server supports DNSSEC
  • 2: the server doesn't keep logs
  • 4: the server doesn't intentionally block domains

For example, a server that supports DNSSEC, stores logs, but doesn't block anything on its own should set props as the following 8 bytes sequence: { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }.

len(x) is a byte representation of the length of x, in bytes. Strings do not have to be zero-terminated.

addr is the IP address, as a string, with a port number if the server is not accessible over the standard port for the protocol (443). IPv6 strings must be included in square brackets: [fe80::6d6d:f72c:3ad:60b8].

pk is the provider's public key, as a 32-byte vector.

providerName is the provider name.

The stamp is encoded using the URL-safe variant of base64.

DNS-over-HTTP/2 stamps

Format:

"sdns://" || base64url(0x02 || props || len(addr) || addr ||
                       vlen(hash0) || hash0 || len(hostname) || hostname ||
                       len(path) || path)

addr is the IP address of the server. It can be an empty string, or just a port number. In that case, the host name will be resolved to an IP address using another resolver.

vlen(x) is equal to len(x) if x is the last element of a set, and 0x80 | len(x) if there are more elements in the set.

hash0 is the SHA256 digest of one of the TBS certificate found in the validation chain, typically the certificate used to sign the resolver's certificate.

Multiple hashes will be encoded as vlen(hash0) || hash0 || ... || vlen(hashN) || hashN, which is equivalent to (0x80 | len(hash0)) || hash0 || ... || len(hashN) || hashN.

hostname is the server host name which will also be used as a SNI name.

path is the absolute URI path, such as /.well-known/dns-query.

DNS-over-TLS stamps

Format:

"sdns://" || base64url(0x03 || props || len(addr) || addr ||
                       vlen(hash0) || hash0 || len(hostname) || hostname)

addr is the IP address of the server. It can be an empty string, or just a port number. In that case, the host name will be resolved to an IP address using another resolver. IPv6 strings must be included in square brackets: [fe80::6d6d:f72c:3ad:60b8].

vlen(x) is equal to len(x) if x is the last element of a set, and 0x80 | len(x) if there are more elements in the set.

hash0 is the SHA256 digest of one of the TBS certificate found in the validation chain, typically the certificate used to sign the resolver's certificate.

Multiple hashes will be encoded as vlen(hash0) || hash0 || ... || vlen(hashN) || hashN, which is equivalent to (0x80 | len(hash0)) || hash0 || ... || len(hashN) || hashN.

hostname is the server host name which will also be used as a SNI name.

Plain DNS stamps

Format:

"sdns://" || base64url(0x00 || props || len(addr) || addr)

addr is the IP address of the server. IPv6 strings must be included in square brackets: [fe80::6d6d:f72c:3ad:60b8].

Clone this wiki locally