cacheable-lookup icon indicating copy to clipboard operation
cacheable-lookup copied to clipboard

DNS over HTTPS support

Open szmarczak opened this issue 2 years ago • 16 comments

szmarczak avatar Aug 19 '21 09:08 szmarczak

One question, would we be using cloudflare or google DoH APIs for this (Ex.: https://cloudflare-dns.com/dns-query). Interested to contribute here

lokesh411 avatar May 02 '22 08:05 lokesh411

I think the CloudFlare one is a good start to implement, then we can do something like this:

const cacheable = new CacheableLookup();

cacheable.servers = [
	  '8.8.8.8', // DNS over UDP/TCP
	  'https://1.1.1.1/dns-query', // DNS over HTTPS
];

There's a spec at https://datatracker.ietf.org/doc/html/rfc8484


I'd do this by storing HTTP/2 sessions in an object (key would be a string starting with https://). We can detect cacheable.servers changes in

https://github.com/szmarczak/cacheable-lookup/blob/45b18daf9f0c8406691fad81188e956641e2309d/source/index.js#L134-L138

so when it's updated, we close sessions that are no longer required and open new ones if there shall be. Then when a user makes a DNS request

https://github.com/szmarczak/cacheable-lookup/blob/45b18daf9f0c8406691fad81188e956641e2309d/source/index.js#L240

we simply go through the list and send a HTTP/2 request to the DoH server and handle that. Note that dns.Resolver doesn't accept DoH servers so we need to filter the list before calling resolver.setServers.


It's possible that there may be multiple DoH servers. This can be quite a hassle, so no need to do this all in one PR.

szmarczak avatar May 02 '22 08:05 szmarczak

Thanks, would go through the specification once, DoH queries should be round robin if multiple DoH servers are given right?

lokesh411 avatar May 02 '22 10:05 lokesh411

No, those should be fallback servers. As per Node.js docs:

Fallback DNS servers will only be used if the earlier ones time out or result in some other error.

szmarczak avatar May 02 '22 18:05 szmarczak

Got it, thanks

lokesh411 avatar May 04 '22 19:05 lokesh411

I created doh-resolver to use DNS-over-HTTPS as resolver with cacheable-lookup:

const CacheableLookup = require('cacheable-lookup')
const DoHResolver = require('doh-resolver')
const https = require('https')

const resolver = new DoHResolver({ servers: ['1.1.1.1', '8.8.8.8'] })

const cacheable = new CacheableLookup({ resolver })

https.get('https://example.com', { lookup: cacheable.lookup }, response => {
  // Handle the response here
})

Kikobeats avatar Jul 01 '22 09:07 Kikobeats

Awesome! It's quite heavy though, can you reduce the size?

szmarczak avatar Jul 01 '22 16:07 szmarczak

yea, I'm working on it; the main dependency is dns2 that is exporting a lot of things I really don't need

Kikobeats avatar Jul 01 '22 19:07 Kikobeats

Are you sure?

image

szmarczak avatar Jul 04 '22 18:07 szmarczak

gotcha; shipped [email protected] that removes the logger dependency

CleanShot 2022-07-05 at 10 54 47@2x

Kikobeats avatar Jul 05 '22 08:07 Kikobeats

Awesome! Would you be up to sending a PR mentioning this in the docs?

szmarczak avatar Jul 06 '22 20:07 szmarczak

PR #77 fixes this! 🎉

See 🍊 Tangerine and https://github.com/forwardemail/tangerine/issues/1.

titanism avatar Feb 25 '23 19:02 titanism

Reported as spam to GitHub

titanism avatar Jan 01 '24 01:01 titanism

Reported for spam

titanism avatar Jan 01 '24 20:01 titanism

BTW this is how I use cacheable-lookup with tangerine for getting DNS-over-HTTPs:

new CacheableLookup({
  resolver: new Tangerine(
    {
      cache: false,
    },
    require('got').extend({
      responseType: 'buffer',
      decompress: false,
      retry: 0
    })
  )
})

If this looks good to @titanism I can create a PR to add it into the README 🙂

Kikobeats avatar Jan 10 '24 13:01 Kikobeats

You're welcome to add whatever you like! This nicely shows how it supports things other than undici.

titanism avatar Jan 10 '24 19:01 titanism