DNS over HTTPS

The code below example of DNS client uses the http2 module to connect to the DNS server 1.1.1.1 (CloudFlare) for the hostname google.com.

The response from the server is a JSON object, which is parsed and logged to the console. The addresses contained in the "Answer" section of the response are logged as the result.

const http2 = require('http2');
const fs = require('fs');
const crypto = require('crypto');
const { URL } = require('url');

const dnsServer = '1.1.1.1';
const hostname = 'google.com';
const type = 'A';
const caBundle = fs.readFileSync('path/to/ca-bundle.pem');

const dnsUrl = new URL(`https://${dnsServer}/dns-query?name=${hostname}&type=${type}`);
const nonce = crypto.randomBytes(16).toString('hex');

const options = {
  host: dnsUrl.host,
  path: dnsUrl.pathname + dnsUrl.search + `&nonce=${nonce}`,
  ca: caBundle,
  rejectUnauthorized: true,
};

const client = http2.connect(`https://${dnsUrl.host}`, options);

client.on('error', (err) => console.error(err));

const req = client.request({
  ':path': options.path,
  'accept': 'application/dns-json',
});

let rawData = '';
req.on('data', (chunk) => { rawData += chunk; });
req.on('end', () => {
  try {
    const response = JSON.parse(rawData);
    const answer = response.Answer;
    const addresses = answer.map((a) => a.data);
    console.log(`Addresses for ${hostname}: ${addresses}`);
  } catch (e) {
    console.error(e.message);
  }
  client.close();
});
req.end();

Note: the CA bundle for certificate verification, and the nonce for security.

Read more

I hope this post was helpful to you.

Leave a reaction if you liked this post!