digd.js ======= | [dns-suite.js](https://git.coolaj86.com/coolaj86/dns-suite.js) | [dig.js](https://git.coolaj86.com/coolaj86/dig.js) | [mdig.js](https://git.coolaj86.com/coolaj86/mdig.js) | **digd.js** | Sponsored by [Daplie](https://daplie.com). A lightweight DNS / mDNS daemon (server) in node.js. Although originally created for testing dns-suite.js by creating and capturing to disk DNS and mDNS query and response packets (as binary and/or JSON), digd.js has grown into a full-blown nameserver. Options are similar to the Unix dig command. Install ------- ### systemd service ```bash curl -L https://git.coolaj86.com/coolaj86/digd.js/raw/v1.1/install.sh | bash ``` ### with git ```bash # Install the latest of v1.x npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1' ``` ```bash # Install exactly v1.1.9 npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1.1.9' ``` ### without git Don't have git? Well, you can also bow down to the gods of the centralized, monopolized, concentrated, *dictator*net (as we like to call it here at Daplie Labs), if that's how you roll: ```bash npm install -g digd.js ``` Usage ----- ```bash digd.js --input ``` **Example**: ```bash digd.js --input ./samples/db.json ``` ### Testing ```bash # unix dig dig @localhost example.com # dns-suite's dig.js dig.js @localhost example.com # unix netcat netcat -u 127.0.0.1 53 < ./samples/example.com.a.query.bin ``` Options ------- ``` --output write query and response(s) to disk with this path prefix (ex: ./samples/dns) --input input file to use for authoritative responses (ex: ./samples/db.json) --mdns Use mDNS port (5353) and nameserver address (224.0.0.251) -p default 53 (mdns default: 5353) (listener is random for DNS and 5353 for mDNS) --nameserver alias of @ --timeout alias of +time=, but in milliseconds @ specify the nameserver to use for recursive DNS resolutions (defaults to system defaults) +time= Sets the timeout for a query in seconds. +norecurse Set `ra` flag to 0. Do not perform recursion. +aaonly Set `aa` flag to 1. Do not respond with non-authoritative responses. --debug verbose output ``` JSON Database File ------------------ This DNS server is being created for use in the wild. Although there will be a true database adapter later, this JSON representation gives us an easy way to experiment with serving DNS and various record types. There are 4 types of information in the file: * Primary Nameservers `primaryNameservers` * SOA Records `domains` * devices * All other records (A, AAAA, CAA, CNAME, MX, NS, PTR, SPF, SRV, TXT) ```js module.exports = { primaryNameservers: [ 'ns1.example.com', 'ns2.example.com' ] // SOA records , domains: [ // `primary` is chosen at random from `primaryNameservers` or `vanityNs` // `serial` is generated from `updatedAt` { id: "publicsuffix.net", updatedAt: 1507594095118, ttl: 60 , admin: 'admin.publicsuffix.net', refresh: 1800, retry: 600 , expiration: 2419200, minimum: 5 } , { id: "doe.publicsuffix.net", updatedAt: 1507594095118, ttl: 60 , admin: 'admin.doe.publicsuffix.net', refresh: 1800, retry: 600 , expiration: 2419200, minimum: 5 } // default values will be used when left undefined , { id: "doefam.net", updatedAt: 1507594095118 , vanityNs: [ 'ns1.awesome.com', 'ns2.awesome.com' ] } ] , records: [ // // Plain old boring A Records // { name: "publicsuffix.net", zone: "publicsuffix.net" , tld: "net", sld: "publicsuffix", sub: "" , type: 'A', ttl: 300, address: '127.0.0.1' } { name: "www.publicsuffix.net", zone: "publicsuffix.net" , tld: "net", sld: "publicsuffix", sub: "www" , type: 'A', ttl: 300, address: '127.0.0.1' } // // Subdomain Delegation of a public suffix (treated as TLD) // { name: "jane.doe.publicsuffix.net", zone: "doe.publicsuffix.net" , tld: "publicsuffix.net", sld: "doe", sub: "john" , type: 'NS', ttl: 300, data: 'ns1.other-dns.net' } // // Example of all other record types // { name: "john.doe.publicsuffix.net" // The zone / SOA it belongs to (keep in mind that subdomains can be delegated to other users and/or nameservers) , zone: "doe.publicsuffix.net" // For indexing (note that we can treat delegated subdomains as if they were TLDs for delegation and resale) , tld: "publicsuffix.net" , sld: "doe" , sub: "john" , type: 'A' // for this example we specify a type even though we show all of the record data , class: 'IN' // (default) , ttl: 300 // A, AAAA , address: '127.0.0.1' , aname: 'some-device.example.com' // See "A Note on ANAMEs" below // CAA , flag: 0 , tag: 'issue' , value: 'letsencrypt.org' // CNAME, NS, PTR put 'name' here // TXT puts an array here , data: 'a.example.com' // MX, SRV , priority: 10 // MX , exchange: 'mxa.example.org' // SRV , weight: 20 , port: 65065 , target: 'laptop1.devices.example.com' } ] }; ``` The **Primary Nameservers** should be all of the nameservers that are in sync for these collections of records. The **SOA** records represent that a domain or subdomain has be registered to or delegated to these nameservers. The SOA records are separate from other record types because they are automatically generated as part of registering a domain or updating its records. The **other records** are in their own table for easy and fast lookup. The **devices** are an abstraction that will be used in the future for ANAMEs and Dynamic DNS. Note: Because it's possible to that delegated subdomains could have delegated subdomains that go right back to the original nameserver, **NS** records will be replaced with an SOA record if any of the NS records match any of the server's primary nameservers or if vanity nameservers are used. ### A Note on ANAMES ANAMEs serve two purposes in this system: 1. Traditional ANAME. Just a CNAME that is automatically resolved to an A record for the "bare domain" problem, and efficiency. 2. Dynamic DNS. When a record on the system is updated, any records that match it by ANAME are also updated TODO: use dns0x20 for ANAME resolutions Other Resources --------------- You may also be interested in Unbound (https://unboundtest.com), which is an entirely different project by someone else which is much more complete, written in go, and may be very useful for debugging and linting. LICENSE ======= You may, at your option, use this software under the MIT and/or Apache-2.0 licenses.