-
Notifications
You must be signed in to change notification settings - Fork 1k
Local DoH
In addition to responding to standard DNS queries, dnscrypt-proxy
can also act as a DoH server, and respond to local queries sent over that protocol.
In particular, this means that Firefox can be configured to use it, so that it will accept to enable ECH (previously known as ESNI) without bypassing your DNS proxy.
In order to enable this, the first thing you need is a self-signed certificate. Since this is just for local usage, you can use that example one or create your own with:
openssl req -x509 -nodes -newkey rsa:2048 -days 5000 -sha256 -keyout \
localhost.pem -out localhost.pem
Generating the TLS key requires answering a couple questions (e.g. Country Name
, Organization Name
, Email Address
and so on). However, answers fields can be empty or left to the default values.
Next, edit dnscrypt-proxy.toml
configuration file, search for the local_doh
section and uncomment the following lines:
[local_doh]
listen_addresses = ['127.0.0.1:3000']
path = "/dns-query"
cert_file = "localhost.pem"
cert_key_file = "localhost.pem"
The path to the localhost.pem
file, should be set in the cert_file
and cert_key_file
options. Make sure that the file can be read by the user the dnscrypt-proxy
service will be running as.
Now, dnscrypt-proxy
should be restarted. With the above settings, the URL of the local DoH server would be https://127.0.0.1:3000/dns-query
. Here is a small exception of the system logs/status:
[NOTICE] Now listening to https://127.0.0.1:3000/dns-query [DoH]
[INFO] [cloudflare] TLS version: 304 - Protocol: h2 - Cipher suite: 4865
[NOTICE] [cloudflare] OK (DoH) - rtt: 54ms
[NOTICE] Server with the lowest initial latency: cloudflare (rtt: 54ms)
[NOTICE] dnscrypt-proxy is ready - live servers: 1
Firefox allows you to bypass complain on self-signed certificates using the method described above. However, other browsers (Chrome/Chromium, Edge, Safari, etc…) prevent you from using DoH with invalid certificate.
Generally, you can make yourself a local certificate authority (CA) and validate your self-signed certificate, but this job maybe tedious and varied from systems to systems. Thanks to mkcert
, you can facilitate this process and generate a valid certificate for usage with other browser.
- Install
mkcert
from here - Make yourself a local CA by running:
mkcert -install
- Make validated certificate for "localhost", "127.0.0.1, and "::1" by running:
mkcert localhost 127.0.0.1 ::1
- Edit you
dnscrypt-proxy.toml
to use the generated certificate and key
It is possible, but not recommended, to configure local_doh
to listen to outside queries, for example:
[local_doh]
listen_addresses = ['123.456.789.1:3000']
path = "/dns-query"
cert_file = "fullchain.pem"
cert_key_file = "privkey.pem"
cert_file
and cert_key_file
can be generated using Let's Encrypt.
Firefox and Cloudflare used to be running an experiment called ESNI. ESNI was the name of an obsolete version of ECH (Encrypted ClientHello), a TLS extension to hide the server name in TLS (including HTTPS) connections.
They are both experimenting with ECH, the new revision of the protocol. Firefox ECH support was implemented in Firefox 85 in exchange for ESNI, which is no longer supported.
While this may eventually be a significant privacy improvement, ECH currently has some caveats to be aware of:
- It is a work-in-progress design and has not yet seen significant (or really any) security analysis.
- It hasn't been deployed anywhere, besides experiments in Firefox and on Cloudflare servers. Even when using Firefox, ECH will never be used except when connecting to some websites from Cloudflare customers.
- Enabling ECH will trigger an extra DNS query for every single new hostname, even for hosts that don't support ECH. Every time a query for a host that doesn't support is made, an error will be returned (
NXDOMAIN
). - Enabling ECH in Firefox breaks some websites ("Secure connection failed -
SSL_ERROR_NO_CYPHER_OVERLAP
" or "SSL_ERROR_MISSING_ESNI_EXTENSION"). - Keep in mind that ECH is still unfinished. What is available is only a technology preview.
Firefox has a setting to enable ECH, but for some unexplained reasons, the web browser ignores it unless it was also configured to bypass your DNS settings.
However, dnscrypt-proxy
's local DoH server can be configured in Firefox, so that the ECH/ESNI setting will not be ignored.
After having set up the local DoH
feature as documented above, open the DoH server full URL (ex: https://127.0.0.1:3000/dns-query
) as a regular website with Firefox.
The first time, the web browser will notice that the certificate is self-signed and complain about it. This is expected. Click "Advanced" and "I accept the risks". This is okay, you are only going to connect to your own machine.
Without the above step, TLS hanshakes will fail and dnscrypt-proxy
will record entries such as:
dnscrypt-proxy[13628]: http: TLS handshake error from 127.0.0.1:38984: remote error: tls: bad certificate
Next, type about:config
in the URL bar, search for trr
and make the following changes:
- Set
network.trr.custom_uri
andnetwork.trr.uri
tohttps://127.0.0.1:3000/dns-query
- Set
network.trr.mode
to2
or3
info - Set
network.dns.echconfig.enabled
totrue
- Set
network.dns.use_https_rr_as_altsvc
totrue
- Set
network.security.esni.enabled
totrue
(deprecated) - Restart Firefox
You can finally check if the Firefox+Cloudflare ESNI experiment is enabled here (don't pay attention to the "Secure DNS" column, the green mark will only be shown when using Cloudflare). But this test doesn't yet work for ECH.
Note that the actual resolvers don't have to be Cloudflare's, and don't have to use the DoH protocol either. ESNI is perfectly compatible with DNSCrypt and Anonymized DNSCrypt.
In order to revert the changes, set network.trr.mode
to 0
. Other parameters will then be ignored, so they can be left as-is.
Enabling ECH
doesn't actually do anything unless the website you are connecting to was explicitly configured to support it. This requires TLS 1.3.
As of today, this is not supported anywhere, except on websites cached by Cloudflare and participating to the experiment.
In somecases if you want to run dnscrypt-proxy as a non-root user you'll get the error "[FATAL] listen udp 0.0.0.0:53: bind: permission denied"
to solve this problem you can run the following command and allow dnscrypt to have access to a low level port :
sudo setcap cap_net_bind_service=+ep $(which dnscrypt-proxy)
- Home
- Installation
- Configuration
- Checking that your DNS traffic is encrypted
- Automatic Updates
- Server sources
- Combining blocklists
- Public Blocklist and other configuration files
- Building from source
- Run your own DNSCrypt server in under 10 minutes
- DNS stamps specifications
- Windows Tips
- dnscrypt-proxy in the media
- Planned Features