DNS forwarder

A DNS forwarder, also known as a DNS relay, is a server that receives DNS queries from clients and then forwards them to other DNS servers for resolution. Here's an example of how you could implement a simple DNS forwarder in Node.js:

const { Resolver } = require('node:dns');
const dgram = require('dgram');
const server = require('dns-packet');
const { Buffer } = require('node:buffer');

const socket = dgram.createSocket('udp4');
socket.bind(53, '127.0.0.1');

const resolver = new Resolver();
resolver.setServers(['8.8.8.8']);

socket.on('message', (msg, rinfo) => {
  const request = server.decode(msg);

  resolver.resolve4(request.questions[0].name, (err, addresses) => {
    if (err) {
      console.error(err);
      return;
    }

    const response = server.encode({
      id: request.id,
      type: 'response',
      flags: server.RECURSION_DESIRED,
      questions: request.questions,
      answers: addresses.map((a) => ({
        name: request.questions[0].name,
        type: 'A',
        ttl: 600,
        data: a,
      })),
    });

    socket.send(response, rinfo.port, rinfo.address, (err) => {
      if (err) {
        console.error(err);
      }
      else {
        console.log(response.toString(), addresses);
      }
    });
  });
});

Test using Dig command on Linux:

Screenshot_2023-02-14_11-13-32.png

This implementation creates a UDP server that listens on port 53 (the standard port for DNS) and waits for incoming DNS queries. When it receives a query, it uses the resolve4 function to resolve the query, and then sends the resolved address back to the client.

Note that this is a very simple implementation and doesn't have many features that a real-world DNS forwarder might have, such as:

  • caching.
  • error handling.
  • configurable forwarders.

Read more

I hope this post was helpful to you.

Leave a reaction if you liked this post!