Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Configuration of server sources
Instead of manually adding servers to the
static section, these can be read from lists. Human-readable lists, with nice descriptions, and the corresponding stamps.
Here is an example of such a list: https://download.dnscrypt.info/dnscrypt-resolvers/v2/public-resolvers.md
Which is even more readable once rendered as Markdown: https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md
This particular list is also visible as a nice web component here: https://dnscrypt.info/public-servers
What is the point of these lists?
First, you don't have to manually enter names and stamps any more. In fact, the
[static] section is generally useless unless you run your own servers.
dnscrypt-proxy can download lists, verify them, and automatically download updates. All the resolvers defined in a list can then be used just by adding their name to the
For example, the
public-resolvers list above is loaded by the example configuration file. So you can use any resolver names it contains without having to provide any other information. This, for example, should work out of the box:
server_names = ['scaleway-fr', 'cloudflare']
Just as a static configuration would, creating and maintaining these lists still requires work. But instead of requiring everyone to do the exact same work, this can be done at a single place, and then shared online.
Anyone can create a list, sign it, and publish it on any website for everybody else to use. This defines a "source": a mechanism to subscribe to lists, automatically download them and keep them always up to date.
Do you wish you had a list that only includes resolves in some specific countries? Create such a list, possibly by copy/pasting resolvers from another list, sign it, and share it online.
Are you running several public resolvers? Put their information in a list, and people will have a simple way to use your resolvers, and have a configuration that includes all the changes you are going to make to them over time.
Configuring the sources to use
The example configuration file includes a
[sources] [sources.'public-resolvers'] urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md'] cache_file = 'public-resolvers.md' minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' refresh_delay = 72 prefix = ''
This declares a source named
public-resolvers, for a list that can be downloaded from two URLs. If one of these URLs doesn't work, the other one will be tried. There can be any number of URLs mirroring the same content. A single one is also totally fine.
cache_file is the file name the content will be saved as. It needs to be unique for each source.
minisign_key is a public key, used to verify that the content is legitimate. Lists can thus be served from any location, even from an untrusted ISP:
dnscrypt-proxy will immediately detect and reject something that has been tampered with.
In order to do so, a second file is automatically downloaded; its name is identical to the one containing the list, with a
.minisig suffix, and this is a signature that only whoever maintains the list can create.
refresh_delay is optional and controls how frequently the proxy will check if an update is available. Be nice with web server operators and don't set something crazy here.
72 (hours) is fine.
What happens if two lists define different servers with the same name? The last definition will "win", but this may not be what you want, especially if these lists are completely unrelated, and the name reuse was not intentional.
In order to prevent this, a prefix can be prepended to all the names of a list.
For example, if
prefix is set to
main and that list includes a resolver called
example, the name
main-example should be used as the
resolver_names value instead of
As implied by the previous statement, multiple lists can be used simultaneously. They just need to have different names (
prefix properties are optional.
Manually downloading the files is not recommended, but if you have a good reason to do so, just remove the
urls property. Downloaded files will still be cache files, and will expire after
refresh_delay hours. If this is not what you want, either make sure to download updates regularily, or bump
A list can include servers of very different properties. Some of these servers may only be accessible using IPv6. Some may not store any logs, some may. Some do DNSSEC validation, some don't.
Even if a list contains many resolvers, you have the ability to use only the ones matching your requirements. In order to do so, the following properties can be adjusted:
# Use servers reachable over IPv4 ipv4_servers = true # Use servers reachable over IPv6 -- Do not enable if you don't have IPv6 conne$ ipv6_servers = false # Use servers implementing the DNSCrypt protocol dnscrypt_servers = true # Use servers implementing the DNS-over-HTTP/2 protocol doh_servers = true # Server must support DNS security extensions (DNSSEC) require_dnssec = false # Server must not log user queries (declarative) require_nolog = true # Server must not enforce its own blacklist (for parental control, ads blocking...) require_nofilter = true
If you require servers to support DNSSEC and no logs, but use a list that doesn't have any matching these criteria, the proxy will not be able to start, since no resolvers are valid for your selection.
This applies to the case where
server_names is empty, which means "use all the resolvers, from all lists, matching the criteria".
If you explicitly list the resolvers you want to use in
server_names, your choice will be respected no matter how the filters are configured.
For example, with the following configuration:
server_names =  require_dnssec = true
cisco will not be used even if found in the sources, because it doesn't support DNSSEC.
But adding explicit names instead of letting the proxy find the fastest among all choices automatically:
server_names = ['cisco', 'cisco-ipv6']
will use the listed set of resolvers, no matter what the filters are.
Where to find more sources?
This very documentation has a set of sources you can use: public server sources.
Feel free to update this page with your own lists if you like.
Creating your own source
The format of a list is pretty straightforward. It includes a title for the list (as a markdown title, with a single leading
# character), followed by a short description of what the list is all about.
Including ways to contact the maintainer is a good idea.
Then, each resolver starts with a name (a markdown subtitle, starting with two leading
# characters), followed by a free-form description.
Really, you can include whatever you want here. But one thing the description must include is the stamp. It will be automatically parsed by the proxy to associate it to the server name.
If you use the dnscrypt server Docker image, the stamp will be displayed after installation.
If you use some other server software, you can use the DNS stamp calculator to compute it. This works both for DNSCrypt and DNS-over-HTTP/2.
Finally, the resulting list need to be signed with Minisign, which is way easier to use than PGP, and produces very short keys and signatures.
For security purposes,
dnscrypt-proxy will not accept lists that are not signed.