distributed-dig
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -153,3 +153,3 @@ // Exports a public function, resolve(), which accepts multiple domains and multiple resolvers. | ||
if (ipAddress === module.exports.isAddressUnique.addresses[i]) { | ||
debug('A match has been found. Returning False as %s is not unique', ipAddress); | ||
debug('A match has been found. Returning "False" as %s is not unique', ipAddress); | ||
// IP Address found on the list, so it's not unique; return false | ||
@@ -159,7 +159,7 @@ return(false); | ||
} | ||
debug('%s wasn\'t found on the list so adding it...'); | ||
debug('%s was not found on the list, so adding it...', ipAddress); | ||
// We've gone through the whole list without finding the IP address, so add it to the list | ||
module.exports.isAddressUnique.addresses.push(ipAddress); | ||
// Return true as the address is unique | ||
debug('Returning True'); | ||
debug('Returning "True"'); | ||
return(true); | ||
@@ -166,0 +166,0 @@ } catch (error) { |
const defaultConfig = { | ||
"options": { | ||
"request": { | ||
"port": 53, | ||
"type": "udp", | ||
"timeout": 2500, | ||
"try_edns": false, | ||
"cache": false | ||
'options': { | ||
'request': { | ||
'port': 53, | ||
'type': 'udp', | ||
'timeout': 2500, | ||
'try_edns': false, | ||
'cache': false | ||
}, | ||
"question": { | ||
"type": "A" | ||
'question': { | ||
'type': 'A' | ||
} | ||
}, | ||
"resolvers": [ | ||
'resolvers': [ | ||
{ | ||
"nameServer": "208.67.222.222", | ||
"provider": "OpenDNS (Primary)" | ||
'nameServer': '208.67.222.222', | ||
'provider': 'OpenDNS (Primary)' | ||
}, | ||
{ | ||
"nameServer": "208.67.220.220", | ||
"provider": "OpenDNS (Secondary)" | ||
'nameServer': '208.67.220.220', | ||
'provider': 'OpenDNS (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "1.1.1.1", | ||
"provider": "Cloudflare (Primary)" | ||
'nameServer': '1.1.1.1', | ||
'provider': 'Cloudflare (Primary)' | ||
}, | ||
{ | ||
"nameServer": "1.0.0.1", | ||
"provider": "Cloudflare (Secondary)" | ||
'nameServer': '1.0.0.1', | ||
'provider': 'Cloudflare (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "8.8.8.8", | ||
"provider": "Google Public DNS (Primary)" | ||
'nameServer': '8.8.8.8', | ||
'provider': 'Google Public DNS (Primary)' | ||
}, | ||
{ | ||
"nameServer": "8.8.4.4", | ||
"provider": "Google Public DNS (Secondary)" | ||
'nameServer': '8.8.4.4', | ||
'provider': 'Google Public DNS (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "199.85.126.10", | ||
"provider": "Norton ConnectSafe (Primary)" | ||
'nameServer': '199.85.126.10', | ||
'provider': 'Norton ConnectSafe (Primary)' | ||
}, | ||
{ | ||
"nameServer": "199.85.127.10", | ||
"provider": "Norton ConnectSafe (Secondary)" | ||
'nameServer': '199.85.127.10', | ||
'provider': 'Norton ConnectSafe (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "8.26.56.26", | ||
"provider": "Comodo Secure DNS (Primary)" | ||
'nameServer': '8.26.56.26', | ||
'provider': 'Comodo Secure DNS (Primary)' | ||
}, | ||
{ | ||
"nameServer": "8.20.247.20", | ||
"provider": "Comodo Secure DNS (Secondary)" | ||
'nameServer': '8.20.247.20', | ||
'provider': 'Comodo Secure DNS (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "9.9.9.9", | ||
"provider": "Quad9 (Primary)" | ||
'nameServer': '9.9.9.9', | ||
'provider': 'Quad9 (Primary)' | ||
}, | ||
{ | ||
"nameServer": "149.112.112.112", | ||
"provider": "Quad9 (Secondary)" | ||
'nameServer': '149.112.112.112', | ||
'provider': 'Quad9 (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "64.6.64.6", | ||
"provider": "Verisign DNS (Primary)" | ||
'nameServer': '64.6.64.6', | ||
'provider': 'Verisign DNS (Primary)' | ||
}, | ||
{ | ||
"nameServer": "64.6.65.6", | ||
"provider": "Verisign DNS (Secondary)" | ||
'nameServer': '64.6.65.6', | ||
'provider': 'Verisign DNS (Secondary)' | ||
}, | ||
{ | ||
"nameServer": "202.21.158.41", | ||
"provider": "Singapore" | ||
'nameServer': '202.21.158.41', | ||
'provider': 'Singapore' | ||
}, | ||
{ | ||
"nameServer": "62.219.45.200", | ||
"provider": "Israel" | ||
'nameServer': '62.219.45.200', | ||
'provider': 'Israel' | ||
}, | ||
{ | ||
"nameServer": "159.134.248.17", | ||
"provider": "Ireland" | ||
'nameServer': '159.134.248.17', | ||
'provider': 'Ireland' | ||
}, | ||
{ | ||
"nameServer": "87.213.68.130", | ||
"provider": "Netherlands" | ||
'nameServer': '87.213.68.130', | ||
'provider': 'Netherlands' | ||
}, | ||
{ | ||
"nameServer": "217.199.173.113", | ||
"provider": "United Kingdom" | ||
'nameServer': '217.199.173.113', | ||
'provider': 'United Kingdom' | ||
}, | ||
{ | ||
"nameServer": "216.98.109.133", | ||
"provider": "United States" | ||
'nameServer': '216.98.109.133', | ||
'provider': 'United States' | ||
}, | ||
{ | ||
"nameServer": "218.38.30.15", | ||
"provider": "South Korea" | ||
'nameServer': '218.38.30.15', | ||
'provider': 'South Korea' | ||
}, | ||
{ | ||
"nameServer": "103.224.162.37", | ||
"provider": "Australia" | ||
'nameServer': '103.224.162.37', | ||
'provider': 'Australia' | ||
}, | ||
{ | ||
"nameServer": "190.220.8.141", | ||
"provider": "Argentina" | ||
'nameServer': '190.220.8.141', | ||
'provider': 'Argentina' | ||
}, | ||
{ | ||
"nameServer": "201.147.98.2", | ||
"provider": "Mexico" | ||
'nameServer': '201.147.98.2', | ||
'provider': 'Mexico' | ||
} | ||
@@ -118,3 +118,2 @@ ] | ||
} | ||
} | ||
}; |
@@ -44,3 +44,3 @@ #!/usr/bin/env node | ||
try { | ||
debug('parsing %s resolvers for "nameServer" the column width', resolvers.length); | ||
debug('parsing %s resolvers for the column width of "nameServer"', resolvers.length); | ||
// Get maximum column widths | ||
@@ -64,3 +64,3 @@ var columnWidth = 0; | ||
try { | ||
debug('parsing %s resolvers for "provider" the column width', resolvers.length); | ||
debug('parsing %s resolvers for the column width of "provider"', resolvers.length); | ||
// Get maximum column width | ||
@@ -78,2 +78,3 @@ var columnWidth = 0; | ||
debug('Exception caught in getProviderColumnWidth(): %O', error); | ||
// Return a default column width of 30 | ||
return(30); | ||
@@ -84,38 +85,70 @@ } | ||
function getConfig() { | ||
debug('getConfig() Entry'); | ||
const fs = require('fs'); | ||
try { | ||
const fs = require('fs'); | ||
var cwd = process.cwd(); | ||
debug('Looking for [%s] in [%s] ...', configFileName, cwd); | ||
// Check if the config file exists in current directory | ||
if (fs.existsSync(configFileName)) { | ||
// Config file found in current directory so remember the path | ||
debug('[%s] found in [%s]', configFileName, cwd); | ||
configFilePath = cwd; | ||
// Check if the custom config file argument was used | ||
if (argv.config) { | ||
debug('"--config" argument detected'); | ||
// Check that a string was passed along with "--config" | ||
if (typeof(argv.config) === 'string') { | ||
debug('The --config parameter [%s] is of type "string"', argv.config); | ||
// Check that the file exists | ||
if (fs.existsSync(argv.config)) { | ||
debug('The specified config file exists.'); | ||
// Split the string into it file & path components | ||
configFilePath = path.dirname(argv.config); | ||
debug('Path: %s', configFilePath); | ||
configFileName = path.basename(argv.config); | ||
debug('Name: %s', configFileName); | ||
} else { | ||
// the --config parameter doesn't contain a file that exists | ||
debug('[%s] does not exist', argv.config); | ||
console.log('Error: '.red + 'The specified config file [' + argv.config.blue + '] does not exist'); | ||
return(false); | ||
} | ||
} else { | ||
// No filename was passed with --config | ||
console.log('Warning: '.yellow + 'ignoring ' + '--config'.blue + '. You must specify a valid filename'); | ||
return(false); | ||
} | ||
} else { | ||
debug('Looking for [%s] in [%s] ...', configFileName, homedir); | ||
// Use default configuration file | ||
var cwd = process.cwd(); | ||
debug('Looking for [%s] in [%s] ...', configFileName, cwd); | ||
// Check if the config file exists in current directory | ||
if (fs.existsSync(configFileName)) { | ||
// Config file found in current directory so remember the path | ||
debug('[%s] found in [%s]', configFileName, cwd); | ||
configFilePath = cwd; | ||
// Check for the config file in the "home" directory | ||
if (fs.existsSync(homedir + '//' + configFileName)) | ||
{ | ||
debug('[%s] found in [%s]', configFileName, homedir); | ||
// Config file found in homedir so remember the path | ||
configFilePath = homedir; | ||
} else { | ||
// Check for the config file in the application's root directory | ||
if (fs.existsSync(configFilePath + '//' + configFileName)) { | ||
// Config file found in application root directory | ||
debug('[%s] found in [%s]', configFileName, configFilePath); | ||
debug('Looking for [%s] in [%s] ...', configFileName, homedir); | ||
// Check for the config file in the "home" directory | ||
if (fs.existsSync(homedir + '//' + configFileName)) { | ||
debug('[%s] found in [%s]', configFileName, homedir); | ||
// Config file found in homedir so remember the path | ||
configFilePath = homedir; | ||
} else { | ||
console.log('Error:'.red + ' The config file ' + configFileName.yellow + ' could not be found in:'); | ||
console.log('current dir: '.grey + cwd); | ||
console.log('home dir: '.grey + homedir); | ||
console.log('ddig root: '.grey + configFilePath); | ||
return(false); | ||
// Check for the config file in the application's root directory | ||
if (fs.existsSync(configFilePath + '//' + configFileName)) { | ||
// Config file found in application root directory | ||
debug('[%s] found in [%s]', configFileName, configFilePath); | ||
} else { | ||
console.log('Error:'.red + ' The config file ' + configFileName.yellow + ' could not be found in:'); | ||
console.log('current dir: '.grey + cwd); | ||
console.log('home dir: '.grey + homedir); | ||
console.log('ddig root: '.grey + configFilePath); | ||
return(false); | ||
} | ||
} | ||
} | ||
} | ||
} catch (error) { | ||
debug('getConfig() caught an exception whilst determining where the configuration file is: %O', error); | ||
return(false); | ||
} | ||
// Read the configuration file | ||
// Read the configuration file | ||
try { | ||
debug('Reading config file: %s', configFilePath + '//' + configFileName); | ||
let rawJSON = fs.readFileSync(configFilePath + '//' + configFileName); | ||
@@ -129,6 +162,7 @@ let config = JSON.parse(rawJSON); | ||
//Check for CLI switches which override config file settings | ||
//Check for arguments which override config file settings | ||
// Verbose mode | ||
if (argv.verbose) { | ||
config.options.verbose = true; | ||
debug('[verbose] set to true'); | ||
} | ||
@@ -139,2 +173,3 @@ | ||
config.options.request.port = argv.port; | ||
debug('[port] set to: %s', config.options.request.port); | ||
} | ||
@@ -145,2 +180,3 @@ | ||
config.options.request.type = String.prototype.toLowerCase(argv.protocol); | ||
debug('[type (protocol)] set to: %s', config.options.request.type); | ||
} | ||
@@ -152,2 +188,3 @@ | ||
config.options.request.timeout = argv.timeout; | ||
debug('[timeout] set to: %s', config.options.request.timeout); | ||
} else { | ||
@@ -161,2 +198,3 @@ console.log('Ignoring '.grey + '--timeout'.blue + ' as its value is not a number'.grey); | ||
config.options.request.try_edns = argv.edns; | ||
debug('[try_edns] set to: %s', config.options.request.try_edns); | ||
} | ||
@@ -171,2 +209,4 @@ | ||
// **** main() **** // | ||
// Initialise configuration | ||
@@ -225,3 +265,6 @@ config = getConfig(); | ||
} | ||
} else if (argv.listDefaults) { | ||
// | ||
const defaults = require('./ddig-defaults'); | ||
defaults.printDefaultConfig(); | ||
} else { | ||
@@ -244,6 +287,6 @@ try { | ||
} else { | ||
debug('"%s" is not a valid hostname. Excluding it from the domains[] array'); | ||
if (process.argv[i].substring(0, 2) !== '--') { | ||
// Excluding CLI switches beginning with '--' from warnings | ||
console.log('Warning: '.yellow + 'ignoring ' + process.argv[i].blue + ' as it\'s not a valid domain name'); | ||
debug('"%s" is not a valid hostname. Excluding it from the domains[] array', process.argv[i]); | ||
// Check for arguments that are missing the double dash prefix | ||
if ((process.argv[i].substring(0, 1) === '-') && (process.argv[i].substring(0, 2) !== '--')) { | ||
console.log('Warning: '.yellow + 'ignoring ' + process.argv[i].blue + ' as it\'s not a valid argument'); | ||
} | ||
@@ -250,0 +293,0 @@ } |
10
help.js
@@ -11,3 +11,3 @@ module.exports = { | ||
//display help screen | ||
// Display help screen | ||
console.log('%s [a.k.a %s]'.cyan, package.name, Object.keys(package.bin)[0]); | ||
@@ -31,4 +31,6 @@ console.log('Read the docs: '.green + package.homepage); | ||
console.log(' ' + '--edns <true|false> ' + 'Enable or disable EDNS(0) [false]'.grey); | ||
console.log(' ' + '--config <filename> ' + 'Specify an alternative configuration file'.grey); | ||
console.log(' ' + '--list-resolvers ' + 'List resolvers configured in config file'.grey); | ||
console.log(' ' + '--list-options ' + 'List DNS request options configured in config file'.grey); | ||
console.log(' ' + '--list-defaults ' + 'Print json of default config file settings'.grey); | ||
console.log(' ' + '--verbose ' + 'Outputs more information'.grey); | ||
@@ -40,6 +42,6 @@ console.log(' ' + '--no-color ' + 'Switches off colour output'.grey); | ||
console.log('EXAMPLES:'.grey); | ||
console.log(' ddig www.asos.com'); | ||
console.log(' ddig www.asos.com --verbose'); | ||
console.log(' ddig www.asos.com secure.asos.com --timeout 5000'); | ||
console.log(' ddig www.example.com'); | ||
console.log(' ddig www.example.com --verbose'); | ||
console.log(' ddig example.com www.example.com --timeout 5000'); | ||
} | ||
}; |
{ | ||
"name": "distributed-dig", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "A utility which makes DNS lookup requests across multiple DNS resolvers and collates the results.", | ||
@@ -48,2 +48,3 @@ "main": "distributed-dig.js", | ||
"prettyjson": "^1.2.1", | ||
"valid-filename": "^3.1.0", | ||
"yargs": "^14.0.0" | ||
@@ -50,0 +51,0 @@ }, |
105
README.md
@@ -16,8 +16,12 @@ # distributed-dig | ||
--- | ||
## Overview | ||
Issues multiple DNS lookup requests across a multitude of DNS resolvers. | ||
A utility which makes DNS lookup requests across multiple DNS resolvers and collates the results. | ||
Useful for checking if a DNS record has been fully propagated, or for querying the origins behind an [AWS Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-types.html) / [Azure Traffic Manager](https://azure.microsoft.com/en-gb/services/traffic-manager/) record (*or any other DNS-based load balancing solution*). | ||
--- | ||
## Installation | ||
@@ -31,2 +35,4 @@ | ||
--- | ||
## Usage | ||
@@ -38,2 +44,4 @@ | ||
--- | ||
## Options | ||
@@ -44,20 +52,16 @@ | ||
```text | ||
--port <number> Specify the DNS port [53] | ||
--protocol <upd|tcp> Specify the DNS protocol [udp] | ||
--timeout <number> Specify the DNS timeout in milliseconds [2500] | ||
--edns <true|false> Enable or disable EDNS(0) [false] | ||
--list-resolvers List resolvers configured in config file | ||
--list-options List DNS request options configured in config file | ||
--verbose Outputs more information | ||
--no-color Switches off colour output | ||
--version Display version number | ||
--help Display this help | ||
--port <number> Specify the DNS port [53] | ||
--protocol <upd|tcp> Specify the DNS protocol [udp] | ||
--timeout <number> Specify the DNS timeout in milliseconds [2500] | ||
--edns <true|false> Enable or disable EDNS(0) [false] | ||
--config <filename> Specify an alternative configuration file | ||
--list-resolvers List resolvers configured in config file | ||
--list-options List DNS request options configured in config file | ||
--list-defaults Print json of default config file settings | ||
--verbose Outputs more information | ||
--no-color Switches off colour output | ||
--version Display version number | ||
--help Display this help | ||
``` | ||
### help | ||
Displays the help screen: | ||
![`ddig --help`](https://marksmurphy.github.io/img/ddig.help.gif) | ||
### port | ||
@@ -81,3 +85,3 @@ | ||
Enables [EDNS(0)](https://en.wikipedia.org/wiki/Extension_mechanisms_for_DNS) | ||
Default: `false` (_disabled_) | ||
Default: `false` (*disabled*) | ||
@@ -89,2 +93,12 @@ With EDNS(0) enabled, if an upstream resolver doesn't support it then the standard DNS will be used as a fallback. | ||
### config | ||
Specifies an alternative configuration file. | ||
To create a custom config you can: | ||
1. pipe **--list-defaults** to a new file: `ddig --list-defaults > custom.json` | ||
2. Edit `custom.json` | ||
3. Use the new configuration file: `ddig --config [path]custom.json example.com` | ||
### list-resolvers | ||
@@ -102,5 +116,9 @@ | ||
### list-defaults | ||
Prints out a sample default config file in raw json. Pipe it to a file for an initial customised configuration file. | ||
### verbose | ||
Switches on verbose mode which outputs additional fields: | ||
Switches on verbose mode which outputs the following additional fields: | ||
@@ -117,8 +135,16 @@ * Full recursive answer (i.e. nested `cname` records) | ||
If your terminal has problems rendering the colour output then you can switch it off by using `--no-color` | ||
If your terminal has problems rendering the colour output then you can switch it off by using `--no-color`. | ||
### version | ||
Prints out distributed-dig's version number. | ||
Prints out `distributed-dig`'s version number. | ||
### help | ||
Displays the help screen: | ||
![`ddig --help`](https://marksmurphy.github.io/img/ddig.help.gif) | ||
--- | ||
## Examples | ||
@@ -156,2 +182,4 @@ | ||
--- | ||
## Features | ||
@@ -171,2 +199,4 @@ | ||
--- | ||
## Configuration File | ||
@@ -222,2 +252,4 @@ | ||
--- | ||
## Debugging | ||
@@ -245,2 +277,33 @@ | ||
--- | ||
## Changelog | ||
### [1.1.1] - September 21<sup>st</sup> 2019 | ||
#### Changed | ||
* Fixed a problem when specifying a full path with the `--config` option. | ||
* Fixed erroneous warnings when using `--config`. | ||
### [1.1.0] - September 20<sup>th</sup> 2019 | ||
#### Added | ||
* New `--config` option to specify an alternative configuration file. | ||
* New `--list-defaults` option which prints a default config json file to the console; useful as an initial custom configuration file. | ||
#### Changed | ||
* Improved input validation for `--timeout` & `--protocol`. | ||
* Improved the `Warning` logic for ignored domains to remove erroneous warnings with valid switches and options. | ||
### [1.0.4] - September 17<sup>th</sup> 2019 | ||
* Fixed file system path separator problem when attempting to locate a config file on Linux systems. | ||
### [1.0.0] - September 17<sup>th</sup> 2019 | ||
* Initial Release. | ||
## FAQ | ||
@@ -247,0 +310,0 @@ |
# To Do | ||
* Add the option `--config` to specify alternative config file via command line. | ||
* Use `findup-sync` to find config file if not in current directory. | ||
* Use `findup-sync` to find config file if not in current directory. | ||
* Add a `--file` option to take domain names from a flat text file. | ||
* Add the option `--unique` to display only the first occurrence of each unique IP address. | ||
* Add a **SoundEx** pattern match against invalid domains and CLI switches to allow *Did you mean ...* alongside the *Warning: Ignoring ...*. | ||
* Add `--certs` switch which instructs `ddig-core.js.resolve()` to extract an x.505 cert from each endpoint, using [get-ssl-certificate](https://www.npmjs.com/package/get-ssl-certificate) and add the details to the `lookupResult` response object. | ||
* Add `--certs` switch which instructs `ddig-core.js.resolve()` to extract an x.505 cert from each endpoint, using either: | ||
* [get-ssl-certificate](https://www.npmjs.com/package/get-ssl-certificate) and add the details to the `lookupResult` response object. | ||
@@ -20,2 +21,3 @@ ```javascript | ||
* [ssldecoder](https://www.npmjs.com/package/ssldecoder) | ||
* Allow for `--certs` *and* `--verbose` to display more x.509 properties. |
43920
10
771
302
10
+ Addedvalid-filename@^3.1.0
+ Addedfilename-reserved-regex@2.0.0(transitive)
+ Addedvalid-filename@3.1.0(transitive)