Compare commits
	
		
			17 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c0eb4225dc | |||
| 6ef61a8674 | |||
|  | d8ead3181d | ||
|  | bc93b942ee | ||
|  | c3934acb30 | ||
|  | bd8b57efd1 | ||
|  | 59980dfa60 | ||
|  | b5ec1f7982 | ||
|  | 3fba17eb97 | ||
|  | 028d5a4542 | ||
|  | 2705f5ef65 | ||
|  | 6cbb2d1741 | ||
|  | d5ab2d5a26 | ||
|  | c77053c39c | ||
|  | 42d3e8a072 | ||
|  | 4ffdf5b59d | ||
|  | 93e5c80ab4 | 
							
								
								
									
										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. | ||||
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ digd.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. | ||||
| 
 | ||||
| @ -22,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 | ||||
| @ -33,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 | ||||
| @ -89,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 | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										114
									
								
								bin/digd.js
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								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,33 +381,34 @@ 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); | ||||
|     } | ||||
| 
 | ||||
|     console.log(''); | ||||
|     console.log('Bound and Listening:'); | ||||
|     console.log(server.address().address + '#' + server.address().port + ' (' + server.type + ')'); | ||||
|   }; | ||||
|   }); | ||||
|   if (cli.tcp /* TODO v1.3 !cli.notcp */) { | ||||
|     require('../lib/tcpd.js').create(cli, dnsd); | ||||
|   } | ||||
| 
 | ||||
|   console.log(''); | ||||
|   if (!cli.nocmd) { | ||||
| @ -417,7 +416,4 @@ cli.main(function (args, cli) { | ||||
|     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 | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ 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://git.coolaj86.com/coolaj86/node-installer.sh/raw/master/install.sh -o ./node-installer.sh.tmp | ||||
| @ -16,7 +16,7 @@ rm ./node-installer.sh.tmp | ||||
| 
 | ||||
| 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,110 +10,102 @@ 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; | ||||
|     } | ||||
|   return engine.getRecords({ name: qname }, function (err, myRecords) { | ||||
|     if (err) { cb(err); return; } | ||||
| 
 | ||||
|     // 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; | ||||
|     } | ||||
|   }); | ||||
|     function checkCount() { | ||||
|       var ready; | ||||
| 
 | ||||
|   function checkCount() { | ||||
|     var ready; | ||||
|       count -= 1; | ||||
|       ready = count <= 0; | ||||
| 
 | ||||
|     count -= 1; | ||||
|     ready = count <= 0; | ||||
| 
 | ||||
|     if (!ready) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     myRecords = myRecords.filter(function (r) { | ||||
|       return !delMe[r.id]; | ||||
|     }); | ||||
| 
 | ||||
|     // There are a number of ways to interpret the wildcard rules
 | ||||
|     var hasWild = false; | ||||
|     var hasMatch = false; | ||||
|     myRecords.some(function (r) { | ||||
|       if (qname === r.name) { | ||||
|         hasMatch = true; | ||||
|         return true; | ||||
|       if (!ready) { | ||||
|         return; | ||||
|       } | ||||
|       if ('*' === r.name[0]) { | ||||
|         hasWild = true; | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     if (hasMatch) { | ||||
|       myRecords = myRecords.filter(function (r) { | ||||
|         if ('*' !== r.name[0]) { return true; } | ||||
|         return !delMe[r.id]; | ||||
|       }); | ||||
|     } | ||||
|     /* | ||||
|     // no need to filter out records if wildcard is used
 | ||||
|     else { | ||||
|       records = records.filter(function (r) { | ||||
|         if ('*' === r.name[0]) { return true; } | ||||
| 
 | ||||
|       // There are a number of ways to interpret the wildcard rules
 | ||||
|       var hasWild = false; | ||||
|       var hasMatch = false; | ||||
|       myRecords.some(function (r) { | ||||
|         if (qname === r.name) { | ||||
|           hasMatch = true; | ||||
|           return true; | ||||
|         } | ||||
|         if ('*' === r.name[0]) { | ||||
|           hasWild = true; | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|     */ | ||||
| 
 | ||||
|     cb(null, myRecords); | ||||
|   } | ||||
| 
 | ||||
|   function getRecord(r) { | ||||
|     // TODO allow multiple records to be returned(?)
 | ||||
|     return function (err, addresses) { | ||||
|       if (err || !addresses.length) { | ||||
|         r.id = r.id || Math.random(); | ||||
|         delMe[r.id] = true; | ||||
|       } else if (addresses.length > 1) { | ||||
|         r._address = addresses[Math.floor(Math.random() * addresses.length)]; | ||||
|       } else { | ||||
|         r._address = addresses[0]; | ||||
|       if (hasMatch) { | ||||
|         myRecords = myRecords.filter(function (r) { | ||||
|           if ('*' !== r.name[0]) { return true; } | ||||
|         }); | ||||
|       } | ||||
|       /* | ||||
|       // no need to filter out records if wildcard is used
 | ||||
|       else { | ||||
|         records = records.filter(function (r) { | ||||
|           if ('*' === r.name[0]) { return true; } | ||||
|         }); | ||||
|       } | ||||
|       */ | ||||
| 
 | ||||
|       cb(null, myRecords); | ||||
|     } | ||||
| 
 | ||||
|     function getRecord(r) { | ||||
|       // TODO allow multiple records to be returned(?)
 | ||||
|       return function (err, addresses) { | ||||
|         if (err || !addresses.length) { | ||||
|           r.id = r.id || Math.random(); | ||||
|           delMe[r.id] = true; | ||||
|         } else if (addresses.length > 1) { | ||||
|           r._address = addresses[Math.floor(Math.random() * addresses.length)]; | ||||
|         } else { | ||||
|           r._address = addresses[0]; | ||||
|         } | ||||
|         checkCount(); | ||||
|       }; | ||||
|     } | ||||
| 
 | ||||
|     count = myRecords.length; | ||||
|     myRecords.forEach(function (r) { | ||||
|       if (r.aname && !r.address) { | ||||
|         if ('A' === r.type) { | ||||
|           // SECURITY XXX TODO dig.resolveJson(query, opts);
 | ||||
|           dns.resolve4(r.aname, getRecord(r)); | ||||
|           return; | ||||
|         } | ||||
|         if ('AAAA' === r.type) { | ||||
|           // SECURITY XXX TODO dig.resolveJson(query, opts);
 | ||||
|           dns.resolve6(r.aname, getRecord(r)); | ||||
|           return; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       checkCount(); | ||||
|     }; | ||||
|   } | ||||
|     }); | ||||
| 
 | ||||
|   count = myRecords.length; | ||||
|   myRecords.forEach(function (r) { | ||||
|     if (r.aname && !r.address) { | ||||
|       if ('A' === r.type) { | ||||
|         // SECURITY XXX TODO dig.resolveJson(query, opts);
 | ||||
|         dns.resolve4(r.aname, getRecord(r)); | ||||
|         return; | ||||
|       } | ||||
|       if ('AAAA' === r.type) { | ||||
|         // SECURITY XXX TODO dig.resolveJson(query, opts);
 | ||||
|         dns.resolve6(r.aname, getRecord(r)); | ||||
|         return; | ||||
|       } | ||||
|     if (!myRecords.length) { | ||||
|       checkCount(); | ||||
|     } | ||||
| 
 | ||||
|     checkCount(); | ||||
|   }); | ||||
| 
 | ||||
|   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,46 +325,48 @@ 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()); | ||||
|     }); | ||||
| 
 | ||||
|     // this should result in a REFUSED status
 | ||||
|     if (!myDomains.length) { | ||||
|       // REFUSED will have no records, so we could still recursion, if enabled
 | ||||
|       results.header.rcode = REFUSED; | ||||
|       cb(null, results); | ||||
|       return; | ||||
|     } | ||||
|     return engine.getSoas({ names: qnames}, function (err, myDomains) { | ||||
|       console.log('[SOA] looking for', qnames, 'and proudly serving', err, myDomains); | ||||
|       if (err) { cb(err); return; } | ||||
| 
 | ||||
|     myDomains.sort(function (d1, d2) { | ||||
|       if (d1.id.length > d2.id.length) { | ||||
|         return -1; | ||||
|       } | ||||
|       if (d1.id.length < d2.id.length) { | ||||
|         return 1; | ||||
|       } | ||||
|       return 0; | ||||
|     }); | ||||
|     //console.log('sorted domains', myDomains);
 | ||||
| 
 | ||||
|     if (!getNsAlso) { | ||||
|       return getSoa(db, myDomains[0], results, cb, answerSoa); | ||||
|     } | ||||
| 
 | ||||
|     return getNs(db, /*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; } | ||||
| 
 | ||||
|       // has NS records (or SOA record if NS records match the server itself)
 | ||||
|       if (results.authority.length) { | ||||
|         console.log(results); cb(null, results); return; | ||||
|       // this should result in a REFUSED status
 | ||||
|       if (!myDomains.length) { | ||||
|         // REFUSED will have no records, so we could still recursion, if enabled
 | ||||
|         results.header.rcode = REFUSED; | ||||
|         cb(null, results); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       // myDomains was sorted such that the longest was first
 | ||||
|       return getSoa(db, myDomains[0], results, cb); | ||||
|       myDomains.sort(function (d1, d2) { | ||||
|         if (d1.id.length > d2.id.length) { | ||||
|           return -1; | ||||
|         } | ||||
|         if (d1.id.length < d2.id.length) { | ||||
|           return 1; | ||||
|         } | ||||
|         return 0; | ||||
|       }); | ||||
|       //console.log('sorted domains', myDomains);
 | ||||
| 
 | ||||
|       if (!getNsAlso) { | ||||
|         return getSoa(engine.primaryNameservers, myDomains[0], results, cb, answerSoa); | ||||
|       } | ||||
| 
 | ||||
|       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; } | ||||
| 
 | ||||
|         // has NS records (or SOA record if NS records match the server itself)
 | ||||
|         if (results.authority.length) { | ||||
|           console.log(results); cb(null, results); return; | ||||
|         } | ||||
| 
 | ||||
|         // myDomains was sorted such that the longest was first
 | ||||
|         return getSoa(engine.primaryNameservers, myDomains[0], results, cb); | ||||
| 
 | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -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 = []; | ||||
| 
 | ||||
| @ -410,7 +400,7 @@ module.exports.query = function (input, query, cb) { | ||||
|       // 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 === db.primaryNameservers.indexOf(r.data.toLowerCase())) { | ||||
|       if (-1 === engine.primaryNameservers.indexOf(r.data.toLowerCase())) { | ||||
|         console.log("It's a vanity NS"); | ||||
|         return false; | ||||
|       } | ||||
							
								
								
									
										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,19 +1,22 @@ | ||||
| { "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 } | ||||
|   , { "id": "daplie.me", "revokedAt": 0, "vanityNs": [ "ns1.daplie.me", "ns2.daplie.me", "ns3.daplie.me" ] } | ||||
|   , { "id": "oauth3.org", "revokedAt": 0 } | ||||
|   , { "id": "hellabit.com", "revokedAt": 0 } | ||||
|   ] | ||||
| , "records": [ | ||||
|     {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns1","data":"ns1.daplie.me"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns2","data":"ns2.daplie.me"} | ||||
|   , {"zone":"daplie.com","name":"daplie.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"daplie","sub":"ns3","data":"ns3.daplie.me"} | ||||
|     {"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":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":"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"} | ||||
| @ -23,6 +26,11 @@ | ||||
|   , {"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":"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"]} | ||||
| @ -63,20 +71,6 @@ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   , {"zone":"hellabit.com","name":"hellabit.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns1","data":"ns1.hellabit.com"} | ||||
|   , {"zone":"hellabit.com","name":"hellabit.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns2","data":"ns2.hellabit.com"} | ||||
|   , {"zone":"hellabit.com","name":"hellabit.com","type":"NS","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns3","data":"ns3.hellabit.com"} | ||||
| 
 | ||||
|   , {"zone":"hellabit.com","name":"ns1.hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns1","address":"45.55.1.122"} | ||||
|   , {"zone":"hellabit.com","name":"ns2.hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns2","address":"45.55.254.197"} | ||||
|   , {"zone":"hellabit.com","name":"ns3.hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"ns3","address":"159.203.25.112"} | ||||
| 
 | ||||
|   , {"zone":"hellabit.com","name":"leo.devices.hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"leo.devices","address":"45.56.59.142"} | ||||
|   , {"zone":"hellabit.com","name":"hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"","address":"45.56.59.142","aname":"leo.devices.hellabit.com"} | ||||
|   , {"zone":"hellabit.com","name":"hellabit.com","type":"A","class":"IN","ttl":5,"tld":"com","sld":"hellabit","sub":"www","address":"45.56.59.142","aname":"leo.devices.hellabit.com"} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   , {"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"} | ||||
|  | ||||
							
								
								
									
										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