unenv icon indicating copy to clipboard operation
unenv copied to clipboard

Partial `node:dns` implementation using DOH (via fetch)

Open pi0 opened this issue 1 year ago • 8 comments

Currently, we fully mock node:dns module since it depends on an OS feature however we could implement it using DNS-over-HTTPS.

async function resolveDomain(domain) {
  const dohServer = process.env.UNENV_DOH_URL || 'https://cloudflare-dns.com/dns-query';
  const url = `${dohServer}?name=${domain}&type=A`;
  try {
    const response = await fetch(url, {
      headers: {
        'Accept': 'application/dns-json'
      }
    });
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const { Answer = [] } = await response.json();
    return Answer;
  } catch (error) {
    console.error('Error resolving domain:', error);
  }
}

// Usage example
resolveDomain('example.com').then(data => console.log(data));

pi0 avatar May 23 '24 11:05 pi0

Interesting! Would there be an opt-out or way to configure? or do you think this should be an opt-in?

IgorMinar avatar May 23 '24 15:05 IgorMinar

We probably need a runtime way of configuring behavior indeed at least for DOH server. Or are you suggesting to completely opt-out of the feature? (what concerns you have?)

pi0 avatar May 23 '24 17:05 pi0

Privacy and security mainly. Some people might not be comfortable with the polyfill making outbound http calls. Maybe it's not a big deal, but it's definitely unexpected behavior from a polyfill.

IgorMinar avatar May 23 '24 17:05 IgorMinar

Fair enough we could make an error and show instructions on how to enable DNS.

BTW the native functionality also make a network request all the time (and most of the time, hosting providers are in control of DNS)

pi0 avatar May 23 '24 17:05 pi0

True. I'm not totally opposed to this, I think we should just think about the implications a bit because it's definitely unconventional.

One way to work around this possible perception of controversy is for workerd to implement this natively. I suspect that most runtimes expose a native DNS API. This implementation could still be used when targeting browsers for example.

IgorMinar avatar May 23 '24 17:05 IgorMinar

Good point and runtime-native is always the best indeed 👍🏼 Only in that case, the edge is still completely in control of the DNS resolver as is currently in control of resolving fetch URLs so a generic concern remains...

Made a poll tweet

(BTW this idea is mainly something to explore i have not seen any popular libs need node:dns)

pi0 avatar May 23 '24 18:05 pi0

I agree that if your code runs in the cloud it doesn't really matter that much if the polyfill makes a fetch request. I was mainly thinking that having your app run locally during dev time and seeing it make these fetch calls could be considered problematic by some.

IgorMinar avatar May 23 '24 21:05 IgorMinar

According to the tweeter people also tend to prefer opt-in.

I guess we can do it per-provider btw. Ie, Cloudflare runtime (i guess :D) already benefits 1.1.1.1 so we could default config in preset.

Would it worth to initiate generic discussion about possibility of exposing DNS util from worked runtime natively @IgorMinar ?

pi0 avatar May 27 '24 09:05 pi0