218 lines
6.4 KiB
Markdown
218 lines
6.4 KiB
Markdown
digd.js
|
|
=======
|
|
|
|
| [dns-suite.js](https://git.coolaj86.com/coolaj86/dns-suite.js)
|
|
| [dig.js](https://git.coolaj86.com/coolaj86/dig.js)
|
|
| **digd.js**
|
|
| Sponsored by [Daplie](https://daplie.com).
|
|
|
|
A lightweight DNS / mDNS daemon (server) for creating and capturing DNS and mDNS
|
|
query and response packets to disk as binary and/or JSON.
|
|
Options are similar to the Unix dig command.
|
|
|
|
Install
|
|
-------
|
|
|
|
### 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.0.0
|
|
npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1.0.0'
|
|
```
|
|
|
|
### 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 <path/to/dns.json>
|
|
```
|
|
|
|
**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 <path/to/file> write query and response(s) to disk with this path prefix (ex: ./samples/dns)
|
|
--input <path/to/file> input file to use for authoritative responses (ex: ./samples/db.json)
|
|
|
|
--mdns Use mDNS port (5353) and nameserver address (224.0.0.251)
|
|
|
|
-p <port> default 53 (mdns default: 5353) (listener is random for DNS and 5353 for mDNS)
|
|
--nameserver <ns> alias of @<nameserver>
|
|
--timeout <ms> alias of +time=<seconds>, but in milliseconds
|
|
|
|
@<nameserver> specify the nameserver to use for recursive DNS resolutions (defaults to system defaults)
|
|
+time=<seconds> 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.
|