folbricht / routedns

DNS stub resolver, proxy and router with support for DoT, DoH, DoQ, and DTLS
BSD 3-Clause "New" or "Revised" License
455 stars 62 forks source link

Implement support for Oblivious DNS #116

Open folbricht opened 3 years ago

folbricht commented 3 years ago

As per https://tools.ietf.org/html/draft-pauly-dprive-oblivious-doh-03 and https://blog.cloudflare.com/oblivious-dns/

cbuijs commented 3 years ago

Seems to work, didn't do extensive research/testing, and seems to be a tad slower then straight DoH to Cloudflare. Seems to retry a lot as well (not persistent?). But could be something external.

Do see differences where queries comes phone between DOH and ODOH, you can test using this: https://browserleaks.com/dns

Which would be in line of expected behaviour.

folbricht commented 3 years ago

What sort of retries are you seeing? It has to reload the target key every few minutes as they expire but that should be it.

So far I haven't found a public (non-cloudflare) proxy to test with.

cbuijs commented 3 years ago

Seems to work as expected, I recompiled everything from scratch and the retries are gone. I actually suspect something with my firewall wrong as I had some other issues as well (reboot fixed it, I think a state-table/memory problems was the cause, nothing related to RouteDNS).

mschirrmeister commented 3 years ago

I was just trying the ODoH feature as well, but ran into a problem that I get no matter what the error error="no key found for target \"odoh.cloudflare-dns.com\"" I pulled the repo, merged #118 locally and build the docker image.

My config looks like this.

# DNS-over-HTTPS via Oblivious DNS

[resolvers.cloudflare-odoh-proxy]
address = "https://odoh1.surfdomeinen.nl/dns-query"
protocol = "odoh"
target = "https://odoh.cloudflare-dns.com/dns-query"

[listeners.local-udp]
address = "0.0.0.0:53"
protocol = "udp"
resolver = "cloudflare-odoh-proxy"

[listeners.local-tcp]
address = "0.0.0.0:53"
protocol = "tcp"
resolver = "cloudflare-odoh-proxy"

I have tried other proxies as well, but error is always the same. ODoH works in general if I test for example via https://github.com/cloudflare/odoh-client-go Any hint what I am missing?

All my steps are the following.

git clone https://github.com/folbricht/routedns.git
cd routedns
git fetch origin pull/118/head:odoh
git checkout odoh
docker build -t routednsodoh .

docker run -it --name routedns \
    --rm \
    -p 5053:53/udp \
    -p 5053:53/tcp \
    -v /Users/marco/temp/odoh-client-simple.toml:/config.toml \
routednsodoh

Full error after sending a query.

ERRO[0039] failed to resolve                             addr="0.0.0.0:53" client=172.17.0.1 error="no key found for target \"odoh.cloudflare-dns.com\"" id=local-udp protocol=udp qname=ccc.de.
folbricht commented 3 years ago

@mschirrmeister The issue seems to be that https://odoh1.surfdomeinen.nl/dns-query isn't returning the key for odoh.cloudflare-dns.com. Is that your server? If that's routedns as well, it'd need an odoh listener.

Anyway, you can see the issue with this.

dig @odoh1.surfdomeinen.nl -t type65 odoh.cloudflare-dns.com

It's asking odoh1.surfdomeinen.nl to get the public key for odoh.cloudflare-dns.com and not getting a response.

Compare that to this which does get a key

dig @1.1.1.1 -t type65 odoh.cloudflare-dns.com
cbuijs commented 3 years ago

Seems to be broken for a while, see here: https://github.com/cloudflare/odoh-client-go/issues/16#issuecomment-822853041

mschirrmeister commented 3 years ago

@folbricht It is not my server. I did also try with your default config (1.1.1.1) example and had the same issue even if the dns53 or doh query against 1.1.1.1 returns the key when asking for type TYPE65.

folbricht commented 3 years ago

Oh right, the response from Cloudflare is missing the key, so it's broken upstream. Hmm, not sure I can do much. Options would be to find some other ODOH provider, or I could allow configuring the target key in the client config, not relying on getting the key via DNS.

mschirrmeister commented 3 years ago

I did not find any other odoh server/proxy so far. Instead or in addition to specifying the key, maybe you could implement to pull the config like in the issue that @cbuijs mentioned? Http request to /.well-known/odohconfigs. Don't know if that is a standard, but the Cloudlfare one and also the NL one seem to have that endpoint. The Cloudflare odoh-client also seems to have that as the only way to load the config. I saw a commit where they removed the dns based lookups.

It seems

cbuijs commented 3 years ago

The ".well-known" is pretty standard among DoH setups (not always, but a lot do), but (in my opinion) cannot rely on much. For testing and such fine. It also seems to be obsoleted/dropped if you look in the RFC/Drafts, so it probably will be unavailable at one point in time.

folbricht commented 3 years ago

I could add that, but it effectively defeats ODOH since the client would have to connect to the target directly. That allows the target to identify the target basically. It would have to be done by the proxy, but that's quite clunky. The proxy would have to receive a DNS query from the client, and convert it into an HTTPS call.

The best solution would be for cloudflare to fix the target.

mschirrmeister commented 3 years ago

Yeah makes sense. I guess in terms of identifying the target would at least know that this client is going to use the target, but will of course not be able to see actual future dns requests. But yes, lets hope Cloudflare addresses it. Also wondering they do it via the well-know uri in their current odoh-client.

folbricht commented 3 years ago

In theory, a malicious target could hand out custom keys and map queries to source IPs that way. Not likely in this case, but getting the key via DNS is really the best way.

mschirrmeister commented 3 years ago

Ok, understood. I would like to ask again for when you wrote ...response from Cloudflare is missing the key.... How is it supposed to look like exactly when you send a query for type65. When I did a query against 1.1.1.1 via plain dns or doh for odoh.cloudflare-dns.com I got an answer for type65.

folbricht commented 3 years ago

If you compare the output to the dig example in https://blog.cloudflare.com/oblivious-dns/, it's shorter now, the 4th long block is missing.

mschirrmeister commented 3 years ago

I see. I did not compare the length. Thank you very much for the explanation.

mschirrmeister commented 3 years ago

@folbricht I did reach out the Cloudflare team and I received the answer that they dropped support for TYPE65 and instead it should be fetched via the odohconfigs uri.

I guess there is a good reason for this and I assume future rfc drafts will be updated, if the design is indeed going into that direction.

cbuijs commented 2 years ago

Seems ODOH has a bit more momentum nowadays. And the usage of HTTPS key/records returned and everyone is in consensus about it's usage (RFC as well). Looks like the usage of odohconfigs disappeared/discontinued and HTTPS records are now the way to go as initially designed.

Issue: Tried to make it work merging #116 with the current version of RouteDNS and seems to be broken all over the place. Cannot get it working. Same errors as mentioned above by @mschirrmeister.

Feature-Request: How about a ODOH listener feature, so RouteDNS can be either a relay/target as well?

Some relays: https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v3/odoh-relays.md

Some targets: https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v3/odoh-servers.md

folbricht commented 2 years ago

Seems like it may be time to rebase the branch and bring it back to life. I can certainly try that. Thanks for the list of targets, that'll be useful for testing.

folbricht commented 2 years ago

The branch has been rebased on the latest master, but not actually tested it yet. I'll be travelling for a bit so can't implement the server-side of this for a little longer.