Tangerine
Node.js DNS over HTTPS - :tangerine: Tangerine is the best drop-in replacement for dns.promises.Resolver using DNS over HTTPS ("DoH") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support). Made for @forwardemail.
Install / Use
/learn @forwardemail/TangerineREADME
Table of Contents
- Install
- Foreword
- Features
- Usage and Examples
- API
new Tangerine(options[, request])tangerine.cancel()tangerine.getServers()tangerine.lookup(hostname[, options])tangerine.lookupService(address, port[, abortController, purgeCache])tangerine.resolve(hostname[, rrtype, options, abortController])tangerine.resolve4(hostname[, options, abortController])tangerine.resolve6(hostname[, options, abortController])tangerine.resolveAny(hostname[, options, abortController])tangerine.resolveCaa(hostname[, options, abortController]))tangerine.resolveCname(hostname[, options, abortController]))tangerine.resolveMx(hostname[, options, abortController]))tangerine.resolveNaptr(hostname[, options, abortController]))tangerine.resolveNs(hostname[, options, abortController]))tangerine.resolvePtr(hostname[, options, abortController]))tangerine.resolveSoa(hostname[, options, abortController]))tangerine.resolveSrv(hostname[, options, abortController]))tangerine.resolveTxt(hostname[, options, abortController]))tangerine.resolveCert(hostname[, options, abortController]))tangerine.resolveTlsa(hostname[, options, abortController]))tangerine.reverse(ip[, abortController, purgeCache])tangerine.setDefaultResultOrder(order)tangerine.setServers(servers)tangerine.spoofPacket(hostname, rrtype, answers[, json, expires = 30000])
- Options
- Cache
- Compatibility
- Debugging
- Benchmarks
- Contributors
- License
Install
npm install tangerine undici
-import dns from 'dns';
+import Tangerine from 'tangerine';
- const resolver = new dns.promises.Resolver();
+const resolver = new Tangerine();
Foreword
What is this project about
Our team at Forward Email (100% open-source and privacy-focused email service) needed a better solution for DNS.
After years of using the Node.js internal DNS module, we ran into these recurring patterns:
- Cloudflare and Google now have DNS over HTTPS servers ("DoH") available – and browsers such as Mozilla Firefox now have it enabled by default.
- DNS cache consistency across multiple servers cannot be easily accomplished using packages such as
unbound,dnsmasq, andbind– and configuring/etc/resolv.confacross multiple Ubuntu versions is not enjoyable (even with Ansible). Maintaining logic at the application layer is much easier from a development, deployment, and maintenance perspective. - Privacy, security, and caching approaches needed to be constantly scaled, re-written, and re-configured.
- Our development teams would encounter unexpected 75 second delays while making DNS requests (if they were connected to a VPN and forgot they were behind blackholed DNS servers – and attempting to use patterns such as
dns.setServers(['1.1.1.1'])). The default timeout if you are behind a blackholed DNS server in Node.js is 75 seconds (due toc-aresunder the hood with5,10,20, and40second retry backoff timeout strategy). - There are zero existing DNS over HTTPS ("DoH") Node.js npm packages that:
- Utilize modern open-source software under the MIT license and are currently maintained.
- Once popular packages such as native-dns and dnscached are archived or deprecated.
- Other packages only provide
lookupfunctions, have a limited sub-set of methods such as @zeit/dns-cached-resolver, or are unmaintained.
- Act as a 1:1 drop-in replacement for
dns.promises.Resolverwith DNS over HTTPS ("DoH"). - Support caching for multiple backends (with TTL and purge support), retries, smart server rotation, and AbortController usage.
- Provide out of the box support for both ECMAScript modules (ESM) and CommonJS (CJS) (see discussions for and against).
- Utilize modern open-source software under the MIT license and are currently maintained.
- The native Node.js
dnsmodule does not support caching out of the box – which is a highly requested feature (but belongs in userland). - Writing tests against DNS-related infrastructure requires either hacky DNS mocking or a DNS server (manipulating cache is much easier).
- <u>The Node.js community is lacking a high-quality and dummy-proof userland DNS package with sensible defaults.</u>
Why integrate DNS over HTTPS
With DNS over HTTPS (DoH), DNS queries and responses are encrypted and sent via the HTTP or HTTP/2 protocols. DoH ensures that attackers cannot forge or alter DNS traffic. DoH uses port 443, which is the standard HTTPS traffic port, to wrap the DNS query in an HTTPS request. DNS queries and responses are camouflaged within other HTTPS traffic, since it all comes and goes from the same port. – Cloudflare
DNS over HTTPS (DoH) is a protocol for performing remote Domain Name System (DNS) resolution via the HTTPS protocol. A goal of the method is to increase user privacy and security by preventing eavesdropping and manipulation of DNS data by [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-midd
