Search code examples
node.jsdns

Use Custom DNS resolver for any request in NodeJS


I'm looking to find a way to use a custom DNS resolver for a nodejs request using node-fetch. I think there is a star of explaining here : Node override request IP resolution but I can't manage to make it work for any request. My goal is to use an alternative DNS resolver, such as cloudflare (1.1.1.1) or Google public DNS (8.8.8.8) instead the OS / ISP default DNS resolution.

import http from "http";
import https from "https";
import fetch from "node-fetch";

const staticLookup = (ip: string, v?: number) => (hostname: string, _: null, cb: Function) => {
  cb(null, ip, v || 4);
};

const staticDnsAgent = (scheme: "http" | "https", ip: string) => {
  const httpModule = scheme === "http" ? http : https;
  return new httpModule.Agent({ lookup: staticLookup(ip), rejectUnauthorized: false });
};

// Both request are not working
fetch(`https://api.github.com/search/issues?q=Hello%20World`, {
  agent: staticDnsAgent("https", "1.1.1.1")
})

fetch(`http://jsonplaceholder.typicode.com/todos`, {
  agent: staticDnsAgent("http", "8.8.8.8")
})

I'm struggling a bit to find a way to make this example work, I'm pretty sure I have to use the nodejs DNS module and set a custom server.


Solution

  • Thanks to Martheen who answered in my first post I was able to achieve the result here :

    import http from "http";
    import https from "https";
    import dns from "dns/promises";
    import fetch from "node-fetch";
    
    // Cloud flare dns
    dns.setServers([
      "1.1.1.1",
      "[2606:4700:4700::1111]",
    ]);
    
    const staticLookup = () => async (hostname: string, _: null, cb: Function) => {
      const ips = await dns.resolve(hostname);
    
      if (ips.length === 0) {
        throw new Error(`Unable to resolve ${hostname}`);
      }
    
      cb(null, ips[0], 4);
    };
    
    const staticDnsAgent = (scheme: "http" | "https") => {
      const httpModule = scheme === "http" ? http : https;
      return new httpModule.Agent({ lookup: staticLookup() });
    };
    
    fetch(`https://api.github.com/search/issues?q=Hello%20World`, {
      agent: staticDnsAgent("https")
    })
    
    fetch(`http://jsonplaceholder.typicode.com/todos`, {
      agent: staticDnsAgent("http")
    })