Hacker News new | comments | show | ask | jobs | submit login

There are 3 major protocols available for DNS privacy:

* DNSCrypt

* DNS over TLS

* DNS over HTTPS

DNSCrypt is the one with better client support and a long list of providers available. If you pick DNS over TLS or DNS over HTTPS you will be restricted to 3 or 4 major players (google, quad9, cloudflare and cleanbrowsing). If you trust them, you are good.

For example, this is the list of providers with DNSCrypt support: https://download.dnscrypt.info/dnscrypt-resolvers/v2/public-...

For DNS over (HTTPS|TLS), there is very little client tools available for troubleshooting. The best one I found was these 2 in PHP:

https://github.com/dcid/dns-over-tls-php-client https://github.com/dcid/doh-php-client

DNSCrypt is also the fastest and most secure.

It doesn't require sessions (uses UDP by default, like regular DNS, but prevents amplification), enforces safe cryptography and pinned certificates, is trivial to implement, doesn't need OpenSSL, implements padding without inventing yet another DNS extension, and can use unique keys for each question (so that DNS providers can't fingerprint clients, unlike other options due to TCP sessions and TLS tickets).

If it's the fastest and most secure, why are people throwing their weight behind DNS-over-HTTPS? There must be a reason for it.

Because it's much more complicated to implement, where-as DNS-over-TLS and DNS-over-HTTPS are far simpler to integrate into existing software and operations.


Both HTTPS and TLS implementations require custom software in order to work, as no OS supports this natively (yet).

It boils down to install a stub that your local resolver will use instead of the upstream directly.

Well, basically because there are TLS libraries available in nearly every language. DNSCrypt is a custom protocol.

For example here is my implementation over rustls in TRust-DNS: https://github.com/bluejekyll/trust-dns/blob/master/rustls/s...

Basically that’s a thin wrapper over the TLS library, and I was able to do three different libraries. DNSCrypt on the other hand was a much larger project, and I gave up on implementing it when I saw the DNS-over-TLS RFC complete.

Quite the opposite, actually. A DNSCrypt client can be implemented in a couple lines of Python: https://github.com/tresni/dnspython-dnscrypt/blob/master/dns...

It probably took about 15 minutes to write these. Writing a fully functional client in Go, which is the core of dnscrypt-proxy 2, took about the same time: https://github.com/jedisct1/dnscrypt-proxy/commit/b076e01f7a...

Correctly implementing DNS-over-TLS is way more complicated.

It has to use TCP. So in order to avoid it being vulnerable to the most trivial slowloris attack, you need to implement a connection pool, reuse old connections, timers to enforce timeouts.

If you want half-decent performance, you need to make sure that multiple, out-of-order queries and responses can be sent over the same connection. This requires tracking query identifiers, making sure that there are no ID collisions in inflight queries, and if you are just building a proxy, you can’t expect any upstream server to support this.

TLS session tickets allow DNS operators to track devices no matter what their IP are. TCP sessions allow DNS operators to fingerprint devices sharing the same external IP. From a privacy perspective, this is effectively a regression over plain DNS. So for people who care about this, you need to add the ability to disable these. Performance will be terrible, but that’s what you get for using a transport protocol that was never designed for DNS. This can be partially mitigated with DoH using forthcoming HTTP/2 extensions. But for raw TLS that doesn’t allow much except send() and receive() packets, there’s no hope without reinventing HTTP.

Encrypted DNS requires padding. The way to do padding in DNS-over-TLS is to add extra records to DNS packets. So you need to parse and modify DNS packets. Which is slow and painful to write, if only because of name compression. Instead of that lousy hack, DNS-over-HTTP/2 can simply use existing HTTP/2 mechanisms: HTTP/2 frames already support padding. DNSCrypt doesn’t require packets to be parsed or modified either; padding bytes are simply appended to raw DNS packets before encryption, and are trivial to remove after decryption.

As we recently saw, DNS-over-TLS is virtually useless against attacks such as BGP hijacks, unless certificates are pinned. So, you need to implement pinning. Figuring out how to do it using the OpenSSL API is going to keep you busy for quite some time. DNSCrypt only requires one function call to verify a signature. DNS-over-HTTP/2 can leverage what browsers and modern HTTP library already do.

So, implementing DNS-over-TLS is hard. It’s not just about sticking stunnel in front of a stub resolver. Even just the TLS part is hard to implement securely. Validating TLS certificates in non-browser software remains the most dangerous code in the world: https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-...

But it’s also pointless. Other protocols are easier to implement and more efficient.

And from a server perspective, proposing DNS-over-TLS means that there is yet another thing to do certificate management for. Key management is hard. It’s the root cause of virtually all DNSSEC outages, and why people gave up with DNSSEC or didn’t even try. Software supposed to automate this exist, but the reality remains the same.

In contrast, key management has been solved in the HTTP world. Through built-in support in web servers, ACME clients, CDNs and proxies. People already run web sites. Let them leverage what they already have and that works well instead of forcing them to go back to square one and figure out how to do key management for DNS. Ditto for authentication and logging. Which is why DNS-over-HTTP/2 makes way more sense than DNS-over-TLS DNS-over-TLS also requires a dedicated port. Which is even not reachable from many restricted network environments such as the WiFi network I am currently on. This kinda defeats the whole point of the protocol. DNS-over-HTTP/2 uses the one port that is less likely to be blocked, and is fully compatible with proxies including transparent ones from mobile carriers. DNSCrypt also uses port 443 by default, can use TCP only if required, but it doesn’t even need a dedicated port either; DNSCrypt and regular DNS can share the same port, as done by Cisco servers.

So, DNS-over-TLS is hard to implement. Hard to deploy. Difficult to connect to. Slow. Won’t get any better without reinventing HTTP. Feels like it was invented 20 years ago, but it doesn’t really make sense any more today.

I disagree. In my TLS implementation, I support multiplexing, timeouts, and generally everything you said is hard, over standard TLS impls.

I found this much more straightforward to implement than DNSCrypt. See my response to the sibling comment for a link to the code.

AFAIK it isn't possible to combine it with Pi-Hole though.


Do the dnscrypt providers actually work, though? I tried setting it up from my machine, and it seemed like many of them were gone. I eventually managed to find a working provider in Iceland, but being that I'm in a country on the opposite side of the planet, the increased latency made the internet markedly more sluggish.

Unless you are still running version 1, dnscrypt-proxy will automatically pick the fastest, working servers for you.

Neat, thanks. I'll try and get it going again this weekend.

The location doesn't matter much. Most of them are anycast, loading from all over the world.

Might you or anyone else have suggestions/feedback of which providers supporting DNSCrypt you have good luck with?

Are OS implementations planning to switch to DNS over TLS or DNS over HTTPS anytime soon?

Because if not, any requests made by non-browsers are still susceptible and will only give users a false sense of security.

Because it's better than doing nothing in the short term, and OSes can switch over as time moves on. Browsers have a much faster cadence and automatic updates (mostly).

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact