Health Check DNS Load Balanced Web Servers

by Eric Fortis

Uxtly is load balanced with DNS using an `A’ record per server.

dig A uxtly.com

uxtly.com. 300 IN  A  192.0.2.155
uxtly.com. 300 IN  A  192.0.2.165

How to check a specific server?

Resolve the domain to a specific IP. Here are two ways of doing it, both timeout in two seconds .

curl

curl -so /dev/null --max-time 2 --head \
  --write-out "%{http_code}" \
  --resolve uxtly.com:443:192.0.2.155 \
  https://uxtly.com

Or, with Node.js

import https from 'https';

checkStatus('https://uxtly.com', '192.0.2.155')
  .then(console.log)
  .catch(console.error);

function checkStatus(url, ip) {
  return new Promise((resolve, reject) => {
    const IPv4 = 4;
    const req = https.request(url,
      {
        method: 'HEAD',
        timeout: 2000,
        lookup(_, options, resolveDNS) {
           if (options.all)
             resolveDNS(null, [{ address: ip, family: IPv4 }]) // Node 20
           else
             resolveDNS(null, ip, IPv4) // Node 16
         }
      },
      response => { resolve(response.statusCode) }
    );
    req.on('error', reject);
    req.on('timeout', () => req.destroy());
    req.end();
  });
}

Open Source

This health-check.mjs shows how to send an email on failure.

Other use

Bypassing a reverse proxy

For example, if Cloudflare® is proxying a server, you can see the original response sent by the origin server (you’ll need to tweak the method and response output).

Avoided alternatives

/etc/hosts or DNS zone file

Avoid changing the /etc/hosts file because it’s system-wide, requires elevated privileges, and limits health checks to be sequential. Also, it depends on nsswitch.conf.

The same goes for changing a zone file of a caching DNS resolver like unbound.

Private Tunnels

Connecting via VPN or SSH wouldn’t be end-to-end health checks.

IP Address in the certificate’s SAN

Issuing certificates with an IP address in addition to the domain name it’s a needless expense if it’s only for health checking.

Skipping the hostname and certificate verification

For example, curl --insecure -L https://192.0.2.155

Sponsored by: