Compare commits
	
		
			24 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c0eb4225dc | |||
| 6ef61a8674 | |||
|  | d8ead3181d | ||
|  | bc93b942ee | ||
|  | c3934acb30 | ||
|  | bd8b57efd1 | ||
|  | 59980dfa60 | ||
|  | b5ec1f7982 | ||
|  | 3fba17eb97 | ||
|  | 028d5a4542 | ||
|  | 2705f5ef65 | ||
|  | 6cbb2d1741 | ||
|  | d5ab2d5a26 | ||
|  | c77053c39c | ||
|  | 42d3e8a072 | ||
|  | 50b335aa61 | ||
|  | a1eca4f1a5 | ||
|  | 4ffdf5b59d | ||
|  | 148bda8afc | ||
|  | ad61360a22 | ||
|  | 93e5c80ab4 | ||
|  | b3ef27791e | ||
|  | cfe5f4e818 | ||
|  | 81928adf3e | 
							
								
								
									
										4
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| v1.1.13 - Tested and working. Deployed to production with known bugs: | ||||
|     * vanity nameserver handling needs more testing | ||||
|     * delegated nameserver handling needs more testing | ||||
|     * malformed records in JSON may result in failure to respond | ||||
							
								
								
									
										41
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| Copyright 2017 AJ ONeal | ||||
| 
 | ||||
| This is open source software; you can redistribute it and/or modify it under the | ||||
| terms of either: | ||||
| 
 | ||||
|    a) the "MIT License" | ||||
|    b) the "Apache-2.0 License" | ||||
| 
 | ||||
| MIT License | ||||
| 
 | ||||
|    Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|    of this software and associated documentation files (the "Software"), to deal | ||||
|    in the Software without restriction, including without limitation the rights | ||||
|    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|    copies of the Software, and to permit persons to whom the Software is | ||||
|    furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
|    The above copyright notice and this permission notice shall be included in all | ||||
|    copies or substantial portions of the Software. | ||||
| 
 | ||||
|    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|    SOFTWARE. | ||||
| 
 | ||||
| Apache-2.0 License Summary | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|      http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| @ -3,11 +3,17 @@ 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 [Root project](https://rootprojects.org). | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
| 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 | ||||
| @ -16,7 +22,7 @@ Install | ||||
| ### systemd service | ||||
| 
 | ||||
| ```bash | ||||
| curl -L https://git.coolaj86.com/coolaj86/digd.js/raw/v1.1/install.sh | bash | ||||
| curl -L https://git.coolaj86.com/coolaj86/digd.js/raw/v1.2/install.sh | bash | ||||
| ``` | ||||
| 
 | ||||
| ### with git | ||||
| @ -27,14 +33,13 @@ 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' | ||||
| # Install exactly v1.2.0 | ||||
| npm install -g 'git+https://git.coolaj86.com/coolaj86/digd.js.git#v1.2.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: | ||||
| Don't have git? You can use npm's centralized repository: | ||||
| 
 | ||||
| ```bash | ||||
| npm install -g digd.js | ||||
| @ -83,6 +88,8 @@ Options | ||||
| +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. | ||||
| +notcp                      Disable TCP server (default in v1.2) | ||||
| +tcp                        Enable TCP server (default in v1.3) | ||||
| 
 | ||||
| --debug                     verbose output | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										112
									
								
								bin/digd.js
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								bin/digd.js
									
									
									
									
									
								
							| @ -5,9 +5,7 @@ | ||||
| var cli = require('cli'); | ||||
| var pkg = require('../package.json'); | ||||
| var dig = require('dig.js/dns-request'); | ||||
| var dgram = require('dgram'); | ||||
| var dnsjs = require('dns-suite'); | ||||
| var crypto = require('crypto'); | ||||
| var common = require('dig.js/common'); | ||||
| var defaultNameservers = require('dns').getServers(); | ||||
| var hexdump; | ||||
| @ -49,8 +47,32 @@ cli.main(function (args, cli) { | ||||
|       cli.norecurse = true; | ||||
|       return; | ||||
|     } | ||||
|     if (arg === '+notcp') { | ||||
|       if (cli.notcp) { | ||||
|         console.error("'+notcp' was specified more than once"); | ||||
|         process.exit(1); | ||||
|         return; | ||||
|       } | ||||
|       cli.notcp = true; | ||||
|       return; | ||||
|     } | ||||
|     if (arg === '+tcp') { | ||||
|       if (cli.tcp) { | ||||
|         console.error("'+tcp' was specified more than once"); | ||||
|         process.exit(1); | ||||
|         return; | ||||
|       } | ||||
|       cli.tcp = true; | ||||
|       return; | ||||
|     } | ||||
|   }); | ||||
| 
 | ||||
|   if (!cli.tcp) { | ||||
|     if (!cli.notcp) { | ||||
|       console.info("[WARNING] Set '+notcp' to disable tcp connections. The default behavior changes to +tcp in v1.3"); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (cli.mdns) { | ||||
|     if (!cli.type) { | ||||
|       cli.type = cli.t = 'PTR'; | ||||
| @ -73,32 +95,10 @@ cli.main(function (args, cli) { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   var handlers = {}; | ||||
|   var server = dgram.createSocket({ | ||||
|     type: cli.udp6 ? 'udp6' : 'udp4' | ||||
|   , reuseAddr: true | ||||
|   }); | ||||
|   server.bind({ | ||||
|     port: cli.port | ||||
|   , address: cli.address | ||||
|   }); | ||||
| 
 | ||||
|   handlers.onError = function (err) { | ||||
|     if ('EACCES' === err.code) { | ||||
|       console.error(""); | ||||
|       console.error("EACCES: Couldn't bind to port. You probably need to use sudo, authbind, or setcap."); | ||||
|       console.error(""); | ||||
|       process.exit(123); | ||||
|       return; | ||||
|     } | ||||
|     console.error("error:", err.stack); | ||||
|     server.close(); | ||||
|   }; | ||||
| 
 | ||||
|   handlers.onMessage = function (nb, rinfo) { | ||||
|     console.log('[DEBUG] got a message'); | ||||
| 
 | ||||
|     var queryAb = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); | ||||
|   var dnsd = {}; | ||||
|   dnsd.onMessage = function (nb, cb) { | ||||
|     var byteOffset = nb._dnsByteOffset || nb.byteOffset; | ||||
|     var queryAb = nb.buffer.slice(byteOffset, byteOffset + nb.byteLength); | ||||
|     var query; | ||||
|     var count; | ||||
| 
 | ||||
| @ -215,12 +215,11 @@ cli.main(function (args, cli) { | ||||
|         console.error("Could not write empty DNS response"); | ||||
|         console.error(e); | ||||
|         console.error(emptyResp); | ||||
|         cb(e, null, '[DEV] response sent (empty)'); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       server.send(newAb, rinfo.port, rinfo.address, function () { | ||||
|         console.log('[DEV] response sent (empty)', rinfo.port, rinfo.address); | ||||
|       }); | ||||
|       cb(null, newAb, '[DEV] response sent (empty)'); | ||||
|     } | ||||
| 
 | ||||
|     function sendResponse(newPacket) { | ||||
| @ -232,12 +231,11 @@ cli.main(function (args, cli) { | ||||
|         console.error("Could not write DNS response from local"); | ||||
|         console.error(e); | ||||
|         console.error(newPacket); | ||||
|         cb(e, null, '[DEV] response sent (local query)'); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       server.send(newAb, rinfo.port, rinfo.address, function () { | ||||
|         console.log('[DEV] response sent (local query)', rinfo.port, rinfo.address); | ||||
|       }); | ||||
|       cb(null, newAb, '[DEV] response sent (local query)'); | ||||
|     } | ||||
| 
 | ||||
|     function recurse() { | ||||
| @ -290,12 +288,11 @@ cli.main(function (args, cli) { | ||||
|             } catch(e) { | ||||
|               console.error("Could not write DNS response"); | ||||
|               console.error(newResponse); | ||||
|               cb(e, null, '[DEV] response sent'); | ||||
|               return; | ||||
|             } | ||||
| 
 | ||||
|             server.send(newAb, rinfo.port, rinfo.address, function () { | ||||
|               console.log('[DEV] response sent', rinfo.port, rinfo.address); | ||||
|             }); | ||||
|             cb(null, newAb, '[DEV] response sent'); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
| @ -335,7 +332,8 @@ cli.main(function (args, cli) { | ||||
|               console.log('request sent to', res.nameserver); | ||||
|             } | ||||
|             */ | ||||
|             console.log('[DEV] query sent (recurse)', rinfo.port, rinfo.address); | ||||
|             //console.log('[DEV] query sent (recurse)', rinfo.port, rinfo.address);
 | ||||
|             //dnsd.onSent('[DEV] query sent (recurse)');
 | ||||
|           } | ||||
|         , onTimeout: function (res) { | ||||
|             console.log(";; [" + q.name + "] connection timed out; no servers could be reached"); | ||||
| @ -373,7 +371,7 @@ cli.main(function (args, cli) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     require('../lib/dns-store').query(path.resolve(cli.input), query, function (err, resp) { | ||||
|     function respondWithResults(err, resp) { | ||||
| 
 | ||||
|       if (err) { console.log('[DEV] answer not found in local db, recursing'); console.error(err); recurse(); return; } | ||||
| 
 | ||||
| @ -383,41 +381,39 @@ cli.main(function (args, cli) { | ||||
|       if (!cli.norecurse && query.header.rd) { resp.header.ra = 1; } | ||||
| 
 | ||||
|       sendResponse(resp); | ||||
|     }); | ||||
|     } | ||||
| 
 | ||||
|     var engine; | ||||
|     try { | ||||
|       engine = require('../lib/store.json.js').create({ filepath: path.resolve(cli.input) }); | ||||
|     } catch(e) { | ||||
|       respondWithResults(e); | ||||
|       return; | ||||
|     } | ||||
|     require('../lib/digd.js').query(engine, query, respondWithResults); | ||||
|   }; | ||||
| 
 | ||||
|   handlers.onListening = function () { | ||||
|     /*jshint validthis:true*/ | ||||
|     var server = this; | ||||
|   cli.defaultNameservers = defaultNameservers; | ||||
|   require('../lib/udpd.js').create(cli, dnsd).on('listening', function () { | ||||
|     cli.chosenNameserver = cli.nameserver; | ||||
|     var index; | ||||
| 
 | ||||
|     if (!cli.chosenNameserver) { | ||||
|       index = crypto.randomBytes(2).readUInt16BE(0) % defaultNameservers.length; | ||||
|       cli.chosenNameserver = defaultNameservers[index]; | ||||
|       index = require('crypto').randomBytes(2).readUInt16BE(0) % cli.defaultNameservers.length; | ||||
|       cli.chosenNameserver = cli.defaultNameservers[index]; | ||||
|       if (cli.debug) { | ||||
|         console.log('index, defaultNameservers', index, defaultNameservers); | ||||
|         console.log('index, defaultNameservers', index, cli.defaultNameservers); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (cli.mdns || '224.0.0.251' === cli.nameserver) { | ||||
|       server.setBroadcast(true); | ||||
|       server.addMembership(cli.nameserver); | ||||
|   }); | ||||
|   if (cli.tcp /* TODO v1.3 !cli.notcp */) { | ||||
|     require('../lib/tcpd.js').create(cli, dnsd); | ||||
|   } | ||||
| 
 | ||||
|     console.log(''); | ||||
|     console.log('Bound and Listening:'); | ||||
|     console.log(server.address().address + '#' + server.address().port + ' (' + server.type + ')'); | ||||
|   }; | ||||
| 
 | ||||
|   console.log(''); | ||||
|   if (!cli.nocmd) { | ||||
|     console.log('; <<>> digd.js v' + pkg.version + ' <<>> ' + process.argv.slice(2).join(' ')); | ||||
|     console.log(';; global options: +cmd'); | ||||
|   } | ||||
| 
 | ||||
|   server.on('error', handlers.onError); | ||||
|   server.on('message', handlers.onMessage); | ||||
|   server.on('listening', handlers.onListening); | ||||
| }); | ||||
|  | ||||
							
								
								
									
										2
									
								
								dist/etc/systemd/system/digd.js.service
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/etc/systemd/system/digd.js.service
									
									
									
									
										vendored
									
									
								
							| @ -8,7 +8,7 @@ Wants=network-online.target systemd-networkd-wait-online.service | ||||
| # Restart on crash (bad signal), but not on 'clean' failure (error exit code) | ||||
| # Allow up to 3 restarts within 10 seconds | ||||
| # (it's unlikely that a user or properly-running script will do this) | ||||
| Restart=on-abnormal | ||||
| Restart=always | ||||
| StartLimitInterval=10 | ||||
| StartLimitBurst=3 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								install.sh
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								install.sh
									
									
									
									
									
								
							| @ -6,17 +6,17 @@ sudo mkdir -p /opt/digd.js /srv/digd.js | ||||
| #chown -R $(whoami):$(whoami) /opt/digd.js /srv/digd.js | ||||
| chown -R digd:digd /opt/digd.js /srv/digd.js | ||||
| 
 | ||||
| echo "v8.9.0" > /tmp/NODEJS_VER | ||||
| echo "v8.9.3" > /tmp/NODEJS_VER | ||||
| export NODE_PATH=/opt/digd.js/lib/node_modules | ||||
| export NPM_CONFIG_PREFIX=/opt/digd.js | ||||
| curl -fsSL https://bit.ly/install-min-node -o ./install-node.sh.tmp | ||||
| bash ./install-node.sh.tmp | ||||
| rm ./install-node.sh.tmp | ||||
| curl -fsSL https://git.coolaj86.com/coolaj86/node-installer.sh/raw/master/install.sh -o ./node-installer.sh.tmp | ||||
| bash ./node-installer.sh.tmp | ||||
| rm ./node-installer.sh.tmp | ||||
| /opt/digd.js/bin/node /opt/digd.js/bin/npm install -g npm@4 | ||||
| 
 | ||||
| git clone https://git.coolaj86.com/coolaj86/digd.js /opt/digd.js/lib/node_modules/digd.js | ||||
| pushd /opt/digd.js/lib/node_modules/digd.js | ||||
|   git checkout v1.1 | ||||
|   git checkout v1.2 | ||||
|   /opt/digd.js/bin/node /opt/digd.js/bin/npm install | ||||
| popd | ||||
| 
 | ||||
|  | ||||
| @ -10,23 +10,14 @@ var NOERROR = 0; | ||||
| var NXDOMAIN = 3; | ||||
| var REFUSED = 5; | ||||
| 
 | ||||
| function getRecords(db, qname, cb) { | ||||
| function getRecords(engine, qname, cb) { | ||||
|   var delMe = {}; | ||||
|   var dns = require('dns'); | ||||
|   // SECURITY XXX TODO var dig = require('dig.js/dns-request');
 | ||||
|   var count; | ||||
|   var myRecords = db.records.slice(0).filter(function (r) { | ||||
| 
 | ||||
|     if ('string' !== typeof r.name) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     // TODO use IN in masterquest (or implement OR)
 | ||||
|     // Only return single-level wildcard?
 | ||||
|     if (qname === r.name || ('*.' + qname.split('.').slice(1).join('.')) === r.name) { | ||||
|       return true; | ||||
|     } | ||||
|   }); | ||||
|   return engine.getRecords({ name: qname }, function (err, myRecords) { | ||||
|     if (err) { cb(err); return; } | ||||
| 
 | ||||
|     function checkCount() { | ||||
|       var ready; | ||||
| @ -108,12 +99,13 @@ function getRecords(db, qname, cb) { | ||||
|     if (!myRecords.length) { | ||||
|       checkCount(); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function dbToResourceRecord(r) { | ||||
|   return { | ||||
|     name: r.name | ||||
|   , typeName: r.type // NS
 | ||||
|   , typeName: r.typeName || r.type // NS
 | ||||
|   , className: 'IN' | ||||
|   , ttl: r.ttl || 300 | ||||
| 
 | ||||
| @ -147,7 +139,7 @@ function dbToResourceRecord(r) { | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function getNs(db, ds, results, cb) { | ||||
| function getNs(engine, ds, results, cb) { | ||||
|   console.log('[DEV] getNs entered with domains', ds); | ||||
| 
 | ||||
|   var d = ds.shift(); | ||||
| @ -161,7 +153,7 @@ function getNs(db, ds, results, cb) { | ||||
| 
 | ||||
|   var qn = d.id.toLowerCase(); | ||||
| 
 | ||||
|   return getRecords(db, qn, function (err, records) { | ||||
|   return getRecords(engine, qn, function (err, records) { | ||||
|     if (err) { cb(err); return; } | ||||
| 
 | ||||
|     records.forEach(function (r) { | ||||
| @ -187,16 +179,16 @@ function getNs(db, ds, results, cb) { | ||||
|     }); | ||||
| 
 | ||||
|     if (!results.authority.length) { | ||||
|       return getNs(db, ds, results, cb); | ||||
|       return getNs(engine, ds, results, cb); | ||||
|     } | ||||
| 
 | ||||
|     // d.vanityNs should only be vanity nameservers (pointing to this same server)
 | ||||
|     if (d.vanityNs || results.authority.some(function (ns) { | ||||
|       console.log('[debug] ns', ns); | ||||
|       return -1 !== db.primaryNameservers.indexOf(ns.data.toLowerCase()); | ||||
|       return -1 !== engine.primaryNameservers.indexOf(ns.data.toLowerCase()); | ||||
|     })) { | ||||
|       results.authority.length = 0; | ||||
|       results.authority.push(domainToSoa(db, d)); | ||||
|       results.authority.push(domainToSoa(engine.primaryNameservers, d)); | ||||
|       results.header.rcode = NXDOMAIN; | ||||
|     } | ||||
|     cb(null, results); | ||||
| @ -204,8 +196,8 @@ function getNs(db, ds, results, cb) { | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function domainToSoa(db, domain) { | ||||
|   var nameservers = domain.vanityNs || db.primaryNameservers; | ||||
| function domainToSoa(primaryNameservers, domain) { | ||||
|   var nameservers = domain.vanityNs || primaryNameservers; | ||||
| 
 | ||||
|   var index = Math.floor(Math.random() * nameservers.length) % nameservers.length; | ||||
|   var nameserver = nameservers[index]; | ||||
| @ -245,20 +237,20 @@ function domainToSoa(db, domain) { | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function getSoa(db, domain, results, cb, answerSoa) { | ||||
| function getSoa(primaryNameservers, domain, results, cb, answerSoa) { | ||||
|   console.log('[DEV] getSoa entered'); | ||||
| 
 | ||||
|   if (!answerSoa) { | ||||
|     results.authority.push(domainToSoa(db, domain)); | ||||
|     results.authority.push(domainToSoa(primaryNameservers, domain)); | ||||
|   } else { | ||||
|     results.answer.push(domainToSoa(db, domain)); | ||||
|     results.answer.push(domainToSoa(primaryNameservers, domain)); | ||||
|   } | ||||
| 
 | ||||
|   cb(null, results); | ||||
|   return; | ||||
| } | ||||
| 
 | ||||
| module.exports.query = function (input, query, cb) { | ||||
| module.exports.query = function (engine, query, cb) { | ||||
|   /* | ||||
|   var fs = require('fs'); | ||||
| 
 | ||||
| @ -271,11 +263,7 @@ module.exports.query = function (input, query, cb) { | ||||
|   }); | ||||
|   */ | ||||
| 
 | ||||
|   var db; | ||||
|   var qname; | ||||
|   try { | ||||
|     db = require(input); | ||||
|   } catch(e) { cb(e); return; } | ||||
| 
 | ||||
|   if (!Array.isArray(query.question) || query.question.length < 1) { | ||||
|     cb(new Error("query is missing question section")); | ||||
| @ -337,9 +325,10 @@ module.exports.query = function (input, query, cb) { | ||||
|     console.log('[DEV] answerSoa?', answerSoa); | ||||
|     console.log('[DEV] qnames'); | ||||
|     console.log(qnames); | ||||
|     var myDomains = db.domains.filter(function (d) { | ||||
|       return -1 !== qnames.indexOf(d.id.toLowerCase()); | ||||
|     }); | ||||
| 
 | ||||
|     return engine.getSoas({ names: qnames}, function (err, myDomains) { | ||||
|       console.log('[SOA] looking for', qnames, 'and proudly serving', err, myDomains); | ||||
|       if (err) { cb(err); return; } | ||||
| 
 | ||||
|       // this should result in a REFUSED status
 | ||||
|       if (!myDomains.length) { | ||||
| @ -361,10 +350,10 @@ module.exports.query = function (input, query, cb) { | ||||
|       //console.log('sorted domains', myDomains);
 | ||||
| 
 | ||||
|       if (!getNsAlso) { | ||||
|       return getSoa(db, myDomains[0], results, cb, answerSoa); | ||||
|         return getSoa(engine.primaryNameservers, myDomains[0], results, cb, answerSoa); | ||||
|       } | ||||
| 
 | ||||
|     return getNs(db, /*myDomains.slice(0)*/qnames.map(function (qn) { return { id: qn }; }), results, function (err, results) { | ||||
|       return getNs(engine, /*myDomains.slice(0)*/qnames.map(function (qn) { return { id: qn }; }), results, function (err, results) { | ||||
|         //console.log('[DEV] getNs complete');
 | ||||
| 
 | ||||
|         if (err) { cb(err, results); return; } | ||||
| @ -375,9 +364,10 @@ module.exports.query = function (input, query, cb) { | ||||
|         } | ||||
| 
 | ||||
|         // myDomains was sorted such that the longest was first
 | ||||
|       return getSoa(db, myDomains[0], results, cb); | ||||
|         return getSoa(engine.primaryNameservers, myDomains[0], results, cb); | ||||
| 
 | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   if ('SOA' === query.question[0].typeName) { | ||||
| @ -385,7 +375,7 @@ module.exports.query = function (input, query, cb) { | ||||
|   } | ||||
| 
 | ||||
|   //console.log('[DEV] QUERY NAME', qname);
 | ||||
|   return getRecords(db, qname, function (err, someRecords) { | ||||
|   return getRecords(engine, qname, function (err, someRecords) { | ||||
|     var myRecords; | ||||
|     var nsRecords = []; | ||||
| 
 | ||||
| @ -407,7 +397,10 @@ module.exports.query = function (input, query, cb) { | ||||
|       console.log("It's NS"); | ||||
| 
 | ||||
|       // If it's a vanity NS, it's not a valid NS for lookup
 | ||||
|       if (-1 === db.primaryNameservers.indexOf(r.data.toLowerCase())) { | ||||
|       // NOTE: I think that the issue here is EXTERNAL vs INTERNAL vanity NS
 | ||||
|       // We _should_ reply for EXTERNAL vanity NS... but not when it's listed on the SOA internally?
 | ||||
|       // It's surrounding the problem of what if I do sub domain delegation to the same server.
 | ||||
|       if (-1 === engine.primaryNameservers.indexOf(r.data.toLowerCase())) { | ||||
|         console.log("It's a vanity NS"); | ||||
|         return false; | ||||
|       } | ||||
| @ -422,14 +415,37 @@ module.exports.query = function (input, query, cb) { | ||||
|     }); | ||||
| 
 | ||||
|     myRecords = someRecords; | ||||
|     if (255 !== query.question[0].type && 'ANY' !== query.question[0].typeName) { | ||||
|       myRecords = myRecords.filter(function (r) { | ||||
| 
 | ||||
|         return ((r.type && r.type === query.question[0].type) | ||||
|     // If we had an ANY query then we don't need to filter out results
 | ||||
|     if (255 !== query.question[0].type && 'ANY' !== query.question[0].typeName) { | ||||
|       var hasA = false; | ||||
|       var hasCname = false; | ||||
| 
 | ||||
|       // We should only return the records that match the query,
 | ||||
|       // except in the case of A/AAAA in which case we should also collect the CNAME
 | ||||
|       myRecords = myRecords.filter(function (r) { | ||||
|         var passCnames = false; | ||||
| 
 | ||||
|         if (!hasA && ('A' === query.question[0].typeName || 'AAAA' === query.question[0].typeName)) { | ||||
|           passCnames = ('CNAME' === r.type ||'CNAME' === r.typeName); | ||||
|           hasCname = hasCname || passCnames; | ||||
|         } | ||||
| 
 | ||||
|         hasA = hasA || ('A' === r.type || 'A' === r.typeName || 'AAAA' === r.type || 'AAAA' === r.typeName); | ||||
| 
 | ||||
|         return passCnames || ((r.type && r.type === query.question[0].type) | ||||
|           || (r.type && r.type === query.question[0].typeName) | ||||
|           || (r.typeName && r.typeName === query.question[0].typeName) | ||||
|         ); | ||||
|       }); | ||||
| 
 | ||||
|       // A and AAAA will also return CNAME records
 | ||||
|       // but we filter out the CNAME records unless there are no A / AAAA records
 | ||||
|       if (hasA && hasCname && ('A' === query.question[0].typeName || 'AAAA' === query.question[0].typeName)) { | ||||
|         myRecords = myRecords.forEach(function (r) { | ||||
|           return 'CNAME' !== r.type && 'CNAME' !== r.typeName; | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (myRecords.length) { | ||||
							
								
								
									
										37
									
								
								lib/store.json.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/store.json.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports.create = function (opts) { | ||||
|   // opts = { filepath };
 | ||||
|   var engine = { db: null }; | ||||
| 
 | ||||
|   var db = require(opts.filepath); | ||||
| 
 | ||||
|   engine.primaryNameservers = db.primaryNameservers; | ||||
|   engine.getSoas = function (query, cb) { | ||||
|     var myDomains = db.domains.filter(function (d) { | ||||
|       return -1 !== query.names.indexOf(d.id.toLowerCase()); | ||||
|     }); | ||||
|     process.nextTick(function () { | ||||
|       cb(null, myDomains); | ||||
|     }); | ||||
|   }; | ||||
|   engine.getRecords = function (query, cb) { | ||||
|     var myRecords = db.records.slice(0).filter(function (r) { | ||||
| 
 | ||||
|       if ('string' !== typeof r.name) { | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       // TODO use IN in masterquest (or implement OR)
 | ||||
|       // Only return single-level wildcard?
 | ||||
|       if (query.name === r.name || ('*.' + query.name.split('.').slice(1).join('.')) === r.name) { | ||||
|         return true; | ||||
|       } | ||||
|     }); | ||||
|     process.nextTick(function () { | ||||
|       cb(null, myRecords); | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   return engine; | ||||
| }; | ||||
							
								
								
									
										70
									
								
								lib/tcpd.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								lib/tcpd.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports.create = function (cli, dnsd) { | ||||
|   function runTcp() { | ||||
|     var tcpServer = require('net').createServer({ }, function (c) { | ||||
|       c.on('error', function (err) { | ||||
|         console.warn("TCP Connection Error:"); | ||||
|         console.warn(err); | ||||
|       }); | ||||
|       c.on('data', function (nb) { | ||||
|         //console.log('TCP data.length:', nb.length);
 | ||||
|         //console.log(nb.toString('hex'));
 | ||||
| 
 | ||||
|         // DNS packets include a 2-byte length header
 | ||||
|         var count = nb.length; | ||||
|         var length = nb[0] << 8; | ||||
|         length = length | nb[1]; | ||||
|         count -= 2; | ||||
|         // TODO slice?
 | ||||
|         nb._dnsByteOffset = nb.byteOffset + 2; | ||||
| 
 | ||||
|         if (length !== count) { | ||||
|           console.error("Handling TCP packets > 512 bytes not implemented."); | ||||
|           c.end(); | ||||
|           return; | ||||
|         } | ||||
| 
 | ||||
|         // TODO pad two bytes for lengths
 | ||||
|         dnsd.onMessage(nb, function (err, newAb, dbgmsg) { | ||||
|           var lenbuf = Buffer.from([ newAb.length >> 8, newAb.length & 255 ]); | ||||
|           // TODO XXX generate legit error packet
 | ||||
|           if (err) { console.error("Error", err); c.end(); return; } | ||||
|           console.log('TCP ' + dbgmsg); | ||||
| 
 | ||||
|           c.write(lenbuf); | ||||
|           c.end(newAb); | ||||
|         }); | ||||
|       }); | ||||
|       c.on('end', function () { | ||||
|         console.log('TCP client disconnected from server'); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     tcpServer.on('error', function (err) { | ||||
|       if ('EADDRINUSE' === err.code) { | ||||
|         console.error("Port '" + cli.port + "' is already in use."); | ||||
|         tcpServer.close(); | ||||
|         process.exit(0); | ||||
|       } | ||||
|       if ('EACCES' === err.code) { | ||||
|         console.error("Could not bind on port '" + cli.port + "': EACCESS (you probably need root permissions)"); | ||||
|         tcpServer.close(); | ||||
|         process.exit(0); | ||||
|       } | ||||
|       console.error("TCP Server Error:"); | ||||
|       console.error(err); | ||||
|       tcpServer.close(function () { | ||||
|         setTimeout(runTcp, 1000); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     tcpServer.listen(cli.port, function () { | ||||
|       console.log('TCP Server bound'); | ||||
|     }); | ||||
| 
 | ||||
|     return tcpServer; | ||||
|   } | ||||
| 
 | ||||
|   return runTcp(); | ||||
| }; | ||||
							
								
								
									
										58
									
								
								lib/udpd.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								lib/udpd.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports.create = function (cli, dnsd) { | ||||
|   var server = require('dgram').createSocket({ | ||||
|     type: cli.udp6 ? 'udp6' : 'udp4' | ||||
|   , reuseAddr: true | ||||
|   }); | ||||
|   server.bind({ | ||||
|     port: cli.port | ||||
|   , address: cli.address | ||||
|   }); | ||||
| 
 | ||||
|   var handlers = {}; | ||||
|   handlers.onError = function (err) { | ||||
|     if ('EACCES' === err.code) { | ||||
|       console.error(""); | ||||
|       console.error("EACCES: Couldn't bind to port. You probably need to use sudo, authbind, or setcap."); | ||||
|       console.error(""); | ||||
|       process.exit(123); | ||||
|       return; | ||||
|     } | ||||
|     console.error("error:", err.stack); | ||||
|     server.close(); | ||||
|   }; | ||||
| 
 | ||||
|   handlers.onMessage = function (nb, rinfo) { | ||||
|     //console.log('[DEBUG] got a UDP message', nb.length);
 | ||||
|     //console.log(nb.toString('hex'));
 | ||||
| 
 | ||||
|     dnsd.onMessage(nb, function (err, newAb, dbgmsg) { | ||||
|       // TODO send legit error message
 | ||||
|       if (err) { server.send(Buffer.from([0x00])); return; } | ||||
|       server.send(newAb, rinfo.port, rinfo.address, function () { | ||||
|         console.log(dbgmsg, rinfo.port, rinfo.address); | ||||
|       }); | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|   handlers.onListening = function () { | ||||
|     /*jshint validthis:true*/ | ||||
|     var server = this; | ||||
| 
 | ||||
|     if (cli.mdns || '224.0.0.251' === cli.nameserver) { | ||||
|       server.setBroadcast(true); | ||||
|       server.addMembership(cli.nameserver); | ||||
|     } | ||||
| 
 | ||||
|     console.log(''); | ||||
|     console.log('Bound and Listening:'); | ||||
|     console.log(server.address().address + '#' + server.address().port + ' (' + server.type + ')'); | ||||
|   }; | ||||
| 
 | ||||
|   server.on('error', handlers.onError); | ||||
|   server.on('message', handlers.onMessage); | ||||
|   server.on('listening', handlers.onListening); | ||||
| 
 | ||||
|   return server; | ||||
| }; | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "digd.js", | ||||
|   "version": "1.1.9", | ||||
|   "version": "1.2.1", | ||||
|   "description": "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.", | ||||
|   "main": "bin/digd.js", | ||||
|   "homepage": "https://git.coolaj86.com/coolaj86/digd.js", | ||||
|  | ||||
| @ -1,50 +1,86 @@ | ||||
| { "primaryNameservers": [ "ns1.daplie.me", "ns2.daplie.me", "ns3.daplie.me" ] | ||||
| { "primaryNameservers": [ "ns1.daplie.com", "ns2.daplie.com", "ns3.daplie.com" ] | ||||
| , "domains": [ | ||||
|     { "id": "daplie.com", "revokedAt": 0 } | ||||
|   , { "id": "daplie.domains", "revokedAt": 0, "vanityNs": [ "ns1.daplie.domains", "ns2.daplie.domains", "ns3.daplie.domains" ] } | ||||
|   , { "id": "daplie.me", "revokedAt": 0, "vanityNs": [ "ns1.daplie.me", "ns2.daplie.me", "ns3.daplie.me" ] } | ||||
|   , { "id": "oauth3.org", "revokedAt": 0 } | ||||
|   ] | ||||
| , "records": [ | ||||
|     {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns1","data":"ns1.daplie.com"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns2","data":"ns2.daplie.com"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns3","data":"ns3.daplie.com"} | ||||
|   , {"zone":"daplie.com","name":"ns1.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"daplie.com","name":"ns2.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"daplie.com","name":"ns3.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns3","address":"159.203.25.112"} | ||||
|     {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns1","data":"ns1.daplie.com"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns2","data":"ns2.daplie.com"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns3","data":"ns3.daplie.com"} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"ns1.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"daplie.com","name":"ns2.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"daplie.com","name":"ns3.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ns3","address":"159.203.25.112"} | ||||
| 
 | ||||
|   , {"zone":"daplie.me","name":"daplie.me","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"daplie","sub":"ns1","data":"ns1.daplie.me"} | ||||
|   , {"zone":"daplie.me","name":"daplie.me","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"daplie","sub":"ns2","data":"ns2.daplie.me"} | ||||
|   , {"zone":"daplie.me","name":"daplie.me","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"daplie","sub":"ns3","data":"ns3.daplie.me"} | ||||
| 
 | ||||
|   , {"zone":"daplie.me","name":"ns1.daplie.me","type":"A","class":"IN","ttl":5,"tld":"me","sld":"daplie","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"daplie.me","name":"ns2.daplie.me","type":"A","class":"IN","ttl":5,"tld":"me","sld":"daplie","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"daplie.me","name":"ns3.daplie.me","type":"A","class":"IN","ttl":5,"tld":"me","sld":"daplie","sub":"ns3","address":"159.203.25.112"} | ||||
| 
 | ||||
|   , {"zone":"oauth3.org","name":"ns1.oauth3.org","type":"A","class":"IN","ttl":5,"tld":"org","sld":"oauth3","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"oauth3.org","name":"ns2.oauth3.org","type":"A","class":"IN","ttl":5,"tld":"org","sld":"oauth3","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"oauth3.org","name":"ns3.oauth3.org","type":"A","class":"IN","ttl":5,"tld":"org","sld":"oauth3","sub":"ns3","address":"159.203.25.112"} | ||||
| 
 | ||||
|   , {"zone":"oauth3.org","name":"oauth3.org","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"oauth3","sub":"ns1","data":"ns1.oauth3.org"} | ||||
|   , {"zone":"oauth3.org","name":"oauth3.org","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"oauth3","sub":"ns2","data":"ns2.oauth3.org"} | ||||
|   , {"zone":"oauth3.org","name":"oauth3.org","type":"NS","class":"IN","ttl":43200,"tld":"me","sld":"oauth3","sub":"ns3","data":"ns3.oauth3.org"} | ||||
| 
 | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"email.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"email","data":"mailgun.org"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"MX","class":"IN","ttl":5,"tld":"com","sld":"daplie","exchange":"mxa.mailgun.org","priority":10} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"MX","class":"IN","ttl":5,"tld":"com","sld":"daplie","exchange":"mxb.mailgun.org","priority":10} | ||||
|   , {"zone":"daplie.com","name":"preorder.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"preorder","data":"daplie.myshopify.com"} | ||||
|   , {"zone":"daplie.com","name":"k1._domainkey.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"k1._domainkey","data":"dkim.mcsv.net"} | ||||
|   , {"zone":"daplie.com","name":"rvpn.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"rvpn","address":"104.236.182.24"} | ||||
|   , {"zone":"daplie.com","name":"smtp._domainkey.daplie.com","type":"TXT","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"smtp._domainkey","data":["k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdEzzYX8U31O5p5Uvyb1B50/JPMcKnsnIQcPDWWYkBUQxMt+FyD1SRZLCaVxWybZ8eFQUwxlh0qFeLd/mIIGhCazQ74a3AH+TJhz4gOAvNQHmWvS0Sv9ZZjGuDM/RdOAFSwZET8+WUpJfDADfijihj5KqMab13NDDLOQ96wObuwQIDAQAB"]} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"TXT","class":"IN","ttl":43200,"tld":"com","sld":"daplie","data":["v=spf1 include:mailgun.org include:spf.mandrillapp.com include:_spf.google.com include:servers.mcsv.net include:mail.zendesk.com ~all"]} | ||||
|   , {"zone":"daplie.com","name":"www.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"www","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"MX","class":"IN","ttl":43200,"tld":"com","sld":"daplie","exchange":"mxa.mailgun.org","priority":10} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"MX","class":"IN","ttl":43200,"tld":"com","sld":"daplie","exchange":"mxb.mailgun.org","priority":10} | ||||
|   , {"zone":"daplie.com","name":"email.daplie.com","type":"CNAME","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"email","data":"mailgun.org"} | ||||
|   , {"zone":"daplie.com","name":"k1._domainkey.daplie.com","type":"CNAME","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"k1._domainkey","data":"dkim.mcsv.net"} | ||||
|   , {"zone":"daplie.com","name":"smtp._domainkey.daplie.com","type":"TXT","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"smtp._domainkey","data":["k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdEzzYX8U31O5p5Uvyb1B50/JPMcKnsnIQcPDWWYkBUQxMt+FyD1SRZLCaVxWybZ8eFQUwxlh0qFeLd/mIIGhCazQ74a3AH+TJhz4gOAvNQHmWvS0Sv9ZZjGuDM/RdOAFSwZET8+WUpJfDADfijihj5KqMab13NDDLOQ96wObuwQIDAQAB"]} | ||||
|   , {"zone":"daplie.com","name":"mandrill._domainkey.daplie.com","type":"TXT","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"mandrill._domainkey","data":["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrLHiExVd55zd/IQ/J/mRwSRMAocV/hMB3jXwaHH36d9NaVynQFYV8NaWi69c1veUtRzGt7yAioXqLj7Z4TeEUoOLgrKsn8YnckGs9i3B3tVFB+Ch/4mPhXWiNfNdynHWBcPcbJ8kjEQ2U8y78dHZj1YeRXXVvWob2OaKynO8/lQIDAQAB;"]} | ||||
|   , {"zone":"daplie.com","name":"iqqsuxwfyvyw.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"iqqsuxwfyvyw","data":"gv-roynzijsoqayyg.dv.googlehosted.com"} | ||||
|   , {"zone":"daplie.com","name":"mandrill._domainkey.daplie.com","type":"TXT","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"mandrill._domainkey","data":["v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrLHiExVd55zd/IQ/J/mRwSRMAocV/hMB3jXwaHH36d9NaVynQFYV8NaWi69c1veUtRzGt7yAioXqLj7Z4TeEUoOLgrKsn8YnckGs9i3B3tVFB+Ch/4mPhXWiNfNdynHWBcPcbJ8kjEQ2U8y78dHZj1YeRXXVvWob2OaKynO8/lQIDAQAB;"]} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"support.daplie.com","type":"CNAME","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"support","data":"daplie.zendesk.com"} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"proxy.tardigrade.devices.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"proxy.tardigrade.devices","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"redleader.devices.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"redleader.devices","address":"104.36.98.166"} | ||||
|   , {"zone":"daplie.com","name":"beast.devices.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"beast.devices","address":"96.19.92.42"} | ||||
|   , {"zone":"daplie.com","name":"ossus.devices.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"ossus.devices","address":"73.65.206.97"} | ||||
|   , {"zone":"daplie.com","name":"leo.devices.daplie.com","type":"A","class":"IN","ttl":3600,"tld":"com","sld":"daplie","sub":"leo.devices","address":"45.56.59.142"} | ||||
|   , {"zone":"daplie.com","name":"proxy.leo.devices.daplie.com","type":"A","class":"IN","ttl":3600,"tld":"com","sld":"daplie","sub":"proxy.leo.devices","address":"45.56.59.142"} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"git.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"git","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"tunnel.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"tunnel","address":"162.243.160.23"} | ||||
|   , {"zone":"daplie.com","name":"api.daplie.com","type":"A","class":"IN","ttl":43200,"tld":"com","sld":"daplie","sub":"api","address":"23.228.168.108"} | ||||
| 
 | ||||
|   , {"zone":"daplie.com","name":"preorder.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"preorder","data":"daplie.myshopify.com"} | ||||
|   , {"zone":"daplie.com","name":"rvpn.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"rvpn","address":"104.236.182.24"} | ||||
|   , {"zone":"daplie.com","name":"mailapp.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"mailapp","data":"mandrillapp.com"} | ||||
|   , {"zone":"daplie.com","name":"tunnel.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"tunnel","address":"162.243.160.23"} | ||||
|   , {"zone":"daplie.com","name":"localhost.alpha.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"localhost.alpha","address":"127.0.0.1"} | ||||
|   , {"zone":"daplie.com","name":"localhost.alpha.daplie.com","type":"AAAA","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"localhost.alpha","address":"::1"} | ||||
|   , {"zone":"daplie.com","name":"hero.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"hero","address":"138.197.54.15"} | ||||
|   , {"zone":"daplie.com","name":"proxy.tardigrade.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"proxy.tardigrade.devices","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"beta.git.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"beta.git","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"git.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"git","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"mattermost.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"mattermost","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"insecure-ftp.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"insecure-ftp","address":"210.5.144.209"} | ||||
|   , {"zone":"daplie.com","name":"api.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"api","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"beast.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"beast.devices","address":"96.19.92.42"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"TXT","class":"IN","ttl":5,"tld":"com","sld":"daplie","data":["v=spf1 include:mailgun.org include:spf.mandrillapp.com include:_spf.google.com include:servers.mcsv.net include:mail.zendesk.com ~all"]} | ||||
|   , {"zone":"daplie.com","name":"ossus.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ossus.devices","address":"73.65.206.97"} | ||||
|   , {"zone":"daplie.com","name":"support.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"support","data":"daplie.zendesk.com"} | ||||
|   , {"zone":"daplie.com","name":"china-ftp.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"china-ftp","address":"210.5.144.209"} | ||||
|   , {"zone":"daplie.com","name":"shop.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"shop","address":"23.227.38.32"} | ||||
|   , {"zone":"daplie.com","name":"shop.daplie.com","type":"CNAME","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"shop","data":"shops.myshopify.com"} | ||||
|   , {"zone":"daplie.com","name":"new.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"new","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"redleader.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"redleader.devices","address":"104.36.98.166"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"www.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"www","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"leo.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"leo.devices","address":"45.56.59.142"} | ||||
|   , {"zone":"daplie.com","name":"media.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"media","address":"45.56.59.142"} | ||||
|   , {"zone":"daplie.com","name":"proxy.leo.devices.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"proxy.leo.devices","address":"45.56.59.142"} | ||||
|   , {"zone":"daplie.com","name":"domains.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"domains","address":"23.228.168.108"} | ||||
|   , {"zone":"daplie.com","name":"labs.daplie.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"labs","address":"23.228.168.108"} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   , {"zone":"daplie.domains","name":"daplie.domains","type":"NS","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns1","data":"ns1.daplie.domains"} | ||||
|   , {"zone":"daplie.domains","name":"daplie.domains","type":"NS","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns2","data":"ns2.daplie.domains"} | ||||
|   , {"zone":"daplie.domains","name":"daplie.domains","type":"NS","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns3","data":"ns3.daplie.domains"} | ||||
| 
 | ||||
|   , {"zone":"daplie.domains","name":"ns1.daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"daplie.domains","name":"ns2.daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"daplie.domains","name":"ns3.daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"ns3","address":"159.203.25.112"} | ||||
| 
 | ||||
|   , {"zone":"daplie.domains","name":"leo.devices.daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"leo.devices","address":"45.56.59.142"} | ||||
|   , {"zone":"daplie.domains","name":"daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"","address":"45.56.59.142","aname":"leo.devices.daplie.domains"} | ||||
|   , {"zone":"daplie.domains","name":"daplie.domains","type":"A","class":"IN","ttl":5,"tld":"domains","sld":"daplie","sub":"www","address":"45.56.59.142","aname":"leo.devices.daplie.domains"} | ||||
|   ] | ||||
| } | ||||
|  | ||||
							
								
								
									
										23
									
								
								samples/hellabit.enom.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								samples/hellabit.enom.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| daplie domains:list # shows hellabit.com in my list of domains | ||||
| 
 | ||||
| # for hellabit.com to lookup itself (chicken and egg problem), | ||||
| # we must first set glue records | ||||
| daplie glue:set -n ns1.hellabit.com --tld com -a 138.197.72.1 | ||||
| daplie glue:set -n ns2.hellabit.com --tld com -a 162.243.136.134 | ||||
| 
 | ||||
| # now we can set hellabit.com to use nsx.hellabit.com nameservers | ||||
| daplie ns:set -n hellabit.com --tld com --nameservers ns1.hellabit.com,ns2.hellabit.com | ||||
| 
 | ||||
| # now we can't use the dns tools because digd.js does not (yet) have oauth3 compatible apis | ||||
| # these won't work | ||||
| # daplie devices:set -d sfo2.devices.hellabit.com -a 138.197.216.176 | ||||
| # daplie devices:attach -d sfo2.devices.hellabit.com -n hellabit.com | ||||
| # daplie devices:attach -d sfo2.devices.hellabit.com -n www.hellabit.com | ||||
| 
 | ||||
| # now you can test that your hard work worked | ||||
| # < ==== NOTE ==== > It may take a few minutes before this starts to work as you'd expect | ||||
| dig +trace ns1.hellabit.com | ||||
| dig +trace ns2.hellabit.com | ||||
| 
 | ||||
| dig +trace hellabit.com | ||||
| dig +trace www.hellabit.com | ||||
| @ -83,6 +83,7 @@ $digcmd @$ns -p $port NS in-delegated.example.com | ||||
| #   should return records in ANSWER section, nothing else | ||||
| $digcmd @$ns -p $port A example.com | ||||
| $digcmd @$ns -p $port AAAA example.com | ||||
| $digcmd @$ns -p $port CNAME example.com | ||||
| $digcmd @$ns -p $port MX example.com | ||||
| $digcmd @$ns -p $port SRV example.com | ||||
| $digcmd @$ns -p $port TXT example.com | ||||
| @ -101,6 +102,8 @@ $digcmd @$ns -p $port NS doesntexist.example.com | ||||
| #   should return record of correct type in ANSWER section, nothing else | ||||
| $digcmd @$ns -p $port A a.example.com | ||||
| $digcmd @$ns -p $port AAAA aaaa.example.com | ||||
| $digcmd @$ns -p $port CNAME cname.example.com | ||||
| $digcmd @$ns -p $port A cname.example.com       # Special Case, should return CNAME record | ||||
| $digcmd @$ns -p $port MX mx.example.com | ||||
| $digcmd @$ns -p $port SRV srv.example.com | ||||
| $digcmd @$ns -p $port TXT txt.example.com | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user