distributed-dig
Advanced tools
Comparing version 1.0.4 to 1.1.0
@@ -16,17 +16,2 @@ #!/usr/bin/env node | ||
// Default DNS TCP options | ||
// eslint-disable-next-line no-unused-vars | ||
const defaultOptions = { | ||
'request': { | ||
'port': 53, | ||
'type': 'udp', | ||
'timeout': 2500, | ||
'try_edns': false, | ||
'cache': false | ||
}, | ||
'question': { | ||
'type': 'A' | ||
} | ||
}; | ||
// Holds the config json | ||
@@ -99,9 +84,9 @@ var config = {}; | ||
const fs = require('fs'); | ||
debug('Looking for [%s] in [%s] ...', configFileName, process.cwd()); | ||
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, process.cwd()); | ||
configFilePath = process.cwd(); | ||
debug('[%s] found in [%s]', configFileName, cwd); | ||
configFilePath = cwd; | ||
@@ -125,5 +110,5 @@ } else { | ||
console.log('Error:'.red + ' The config file ' + configFileName.yellow + ' could not be found in:'); | ||
console.log(process.cwd()); | ||
console.log(homedir); | ||
console.log(configFilePath); | ||
console.log('current dir: '.grey + cwd); | ||
console.log('home dir: '.grey + homedir); | ||
console.log('ddig root: '.grey + configFilePath); | ||
return(false); | ||
@@ -156,3 +141,3 @@ } | ||
if (argv.protocol) { | ||
config.options.request.type = argv.protocol; | ||
config.options.request.type = String.prototype.toLowerCase(argv.protocol); | ||
} | ||
@@ -162,3 +147,7 @@ | ||
if (argv.timeout) { | ||
config.options.request.timeout = argv.timeout; | ||
if(typeof argv.timeout === 'number'){ | ||
config.options.request.timeout = argv.timeout; | ||
} else { | ||
console.log('Ignoring '.grey + '--timeout'.blue + ' as its value is not a number'.grey); | ||
} | ||
} | ||
@@ -181,150 +170,153 @@ | ||
// Check for 'help' command line parameters, or no parameters at all | ||
if ((process.argv.length === 2) || (argv.help)) { | ||
// Show help screen | ||
const help = require('./help'); | ||
help.helpScreen(); | ||
} else if (argv.listResolvers) { | ||
// Get list of resolvers | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
if (config.options.verbose) { | ||
// Raw JSON output | ||
const prettyjson = require('prettyjson'); | ||
console.log('Resolvers'.yellow); | ||
console.log(prettyjson.render(config.resolvers)); | ||
if (config) { | ||
// Check for 'help' command line parameters, or no parameters at all | ||
if ((process.argv.length === 2) || (argv.help)) { | ||
// Show help screen | ||
const help = require('./help'); | ||
help.helpScreen(); | ||
} else if (argv.listResolvers) { | ||
// Get list of resolvers | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
if (config.options.verbose) { | ||
// Raw JSON output | ||
const prettyjson = require('prettyjson'); | ||
console.log('Resolvers'.yellow); | ||
console.log(prettyjson.render(config.resolvers)); | ||
} else { | ||
const columnify = require('columnify'); | ||
const columns = columnify(config.resolvers, { | ||
config: { | ||
'nameServer': { | ||
headingTransform: function() { | ||
return 'Resolver IP Address'.underline; | ||
} | ||
}, | ||
'provider': { | ||
headingTransform: function() { | ||
return 'DNS Provider'.underline; | ||
} | ||
} | ||
} | ||
}); | ||
console.log(columns); | ||
} | ||
} else if (argv.listOptions) { | ||
// Get the options | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
if (config.options.verbose) { | ||
// Raw JSON output | ||
const prettyjson = require('prettyjson'); | ||
console.log('Options'.yellow); | ||
console.log(prettyjson.render(config.options)); | ||
} else { | ||
const columnify = require('columnify'); | ||
console.log('{request}'.yellow); | ||
var columns = columnify(config.options.request, {columns: ['Option', 'Value']}); | ||
console.log(columns); | ||
console.log('{question}'.yellow); | ||
columns = columnify(config.options.question, {columns: ['Option', 'Value']}); | ||
console.log(columns); | ||
} | ||
} else { | ||
const columnify = require('columnify'); | ||
const columns = columnify(config.resolvers, { | ||
config: { | ||
'nameServer': { | ||
headingTransform: function() { | ||
return 'Resolver IP Address'.underline; | ||
try { | ||
// Loop through command line parameters to extract domains. Expecting 'distributed-dig.js domain [domain [domain] ... ]' | ||
var i = 2; | ||
const isValidDomain = require('is-valid-domain'); | ||
for (i = 2; i < process.argv.length; i++) { | ||
debug('Extracted "%s" from the command line', process.argv[i]); | ||
// Check that's a valid domain | ||
if (isValidDomain(process.argv[i])){ | ||
// Add domain into the array | ||
domains.push(process.argv[i]); | ||
// Set domain column width | ||
if (process.argv[i].length > domainColumnWidth) { | ||
domainColumnWidth = process.argv[i].length; | ||
} | ||
}, | ||
'provider': { | ||
headingTransform: function() { | ||
return 'DNS Provider'.underline; | ||
} 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'); | ||
} | ||
} | ||
} | ||
}); | ||
console.log(columns); | ||
} | ||
} else if (argv.listOptions) { | ||
// Get the options | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
if (config.options.verbose) { | ||
// Raw JSON output | ||
const prettyjson = require('prettyjson'); | ||
console.log('Options'.yellow); | ||
console.log(prettyjson.render(config.options)); | ||
} else { | ||
const columnify = require('columnify'); | ||
console.log('{request}'.yellow); | ||
var columns = columnify(config.options.request, {columns: ['Option', 'Value']}); | ||
console.log(columns); | ||
console.log('{question}'.yellow); | ||
columns = columnify(config.options.question, {columns: ['Option', 'Value']}); | ||
console.log(columns); | ||
} | ||
debug('%s domains: %O', domains.length, domains); | ||
} else { | ||
try { | ||
// Loop through command line parameters to extract domains. Expecting 'distributed-dig.js domain [domain [domain] ... ]' | ||
var i = 2; | ||
const isValidDomain = require('is-valid-domain'); | ||
for (i = 2; i < process.argv.length; i++) { | ||
debug('Extracted "%s" from the command line', process.argv[i]); | ||
// Check that's a valid domain | ||
if (isValidDomain(process.argv[i])){ | ||
// Add domain into the array | ||
domains.push(process.argv[i]); | ||
// Set domain column width | ||
if (process.argv[i].length > domainColumnWidth) { | ||
domainColumnWidth = process.argv[i].length; | ||
// If we've got some domains to lookup, display some useful extra information | ||
if (domains.length > 0) { | ||
// Display which configuration file is being used | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
// If we're going to be outputting verbose columns, check the terminal width is sufficient | ||
if ((config.options.verbose) && (process.stdout.columns < 130)) { | ||
console.log('When using the --verbose switch you might want to consider increasing your console width to at least 130 (it\'s currently %s)'.cyan, process.stdout.columns); | ||
} | ||
} 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 domains: %O', domains.length, domains); | ||
// If we've got some domains to lookup, display some useful extra information | ||
if (domains.length > 0) { | ||
// Display which configuration file is being used | ||
console.log('Using configuration file: '.grey + configFileName.yellow + ' ['.grey + configFilePath.grey + ']'.grey ); | ||
// If we're going to be outputting verbose columns, check the terminal width is sufficient | ||
if ((config.options.verbose) && (process.stdout.columns < 130)) { | ||
console.log('When using the --verbose switch you might want to consider increasing your console width to at least 130 (it\'s currently %s)'.cyan, process.stdout.columns); | ||
} | ||
} | ||
// Iterate through the list of domains | ||
domains.forEach((domain) => { | ||
// Iterate through each resolver | ||
config.resolvers.forEach((resolver) => { | ||
// Perform a lookup for the current domain via the current resolver | ||
ddig.resolve(domain, resolver, config.options, (response) => { | ||
debug('Looking up %s against %s (%s) returned: %O', domain, resolver.nameServer, resolver.provider, response); | ||
var result = {}; | ||
if (response.success) { | ||
// The lookup succeeded. Extract the properties needed from the response | ||
result = [{ | ||
'unique': '', | ||
'domain': response.domain, | ||
'IPAddress': response.ipAddress.green, | ||
'provider': response.provider.grey, | ||
}]; | ||
if (ddig.isAddressUnique(response.ipAddress)) { | ||
// If this is first time we've seen this IP address mark the 'unique' column | ||
result[0].unique = '•'; | ||
} | ||
// Iterate through the list of domains | ||
domains.forEach((domain) => { | ||
// Iterate through each resolver | ||
config.resolvers.forEach((resolver) => { | ||
// Perform a lookup for the current domain via the current resolver | ||
ddig.resolve(domain, resolver, config.options, (response) => { | ||
debug('Looking up %s against %s (%s) returned: %O', domain, resolver.nameServer, resolver.provider, response); | ||
var result = {}; | ||
if (response.success) { | ||
// The lookup succeeded. Extract the properties needed from the response | ||
result = [{ | ||
'unique': '', | ||
'domain': response.domain, | ||
'IPAddress': response.ipAddress.green, | ||
'provider': response.provider.grey, | ||
}]; | ||
if (ddig.isAddressUnique(response.ipAddress)) { | ||
// If this is first time we've seen this IP address mark the 'unique' column | ||
result[0].unique = '•'; | ||
// Add additional 'success' columns if `verbose` is switched on | ||
if (config.options.verbose) { | ||
//result[0].nameServer = response.nameServer.grey; | ||
result[0].provider += EOL + response.nameServer.grey; | ||
result[0].duration = response.duration + 'ms'; | ||
result[0].recursion = response.recursion; | ||
} | ||
} else { | ||
// The lookup failed | ||
result = [{ | ||
'unique': '', | ||
'domain': response.domain, | ||
'IPAddress': response.msg.red, | ||
'provider': response.provider.grey | ||
}]; | ||
// Add additional 'failed' columns if `verbose` is switched on | ||
if (config.options.verbose) { | ||
//result[0].nameServer = response.nameServer.grey; | ||
result[0].provider += EOL + response.nameServer.grey; | ||
result[0].duration = response.duration + 'ms'; | ||
} | ||
} | ||
// Add additional 'success' columns if `verbose` is switched on | ||
if (config.options.verbose) { | ||
//result[0].nameServer = response.nameServer.grey; | ||
result[0].provider += EOL + response.nameServer.grey; | ||
result[0].duration = response.duration + 'ms'; | ||
result[0].recursion = response.recursion; | ||
} | ||
} else { | ||
// The lookup failed | ||
result = [{ | ||
'unique': '', | ||
'domain': response.domain, | ||
'IPAddress': response.msg.red, | ||
'provider': response.provider.grey | ||
}]; | ||
// Add additional 'failed' columns if `verbose` is switched on | ||
if (config.options.verbose) { | ||
//result[0].nameServer = response.nameServer.grey; | ||
result[0].provider += EOL + response.nameServer.grey; | ||
result[0].duration = response.duration + 'ms'; | ||
} | ||
} | ||
// Display the result | ||
let columns = columnify(result, { | ||
showHeaders: false, | ||
preserveNewLines: true, | ||
config: { | ||
unique: {minWidth:1, maxWidth: 1}, | ||
domain: {minWidth: domainColumnWidth}, | ||
IPAddress: {minWidth: 15}, | ||
provider: {minWidth: providerColumnWidth}, | ||
nameServer: {minWidth: nameServerColumnWidth}, | ||
duration: {minWidth: 7} | ||
} | ||
// Display the result | ||
let columns = columnify(result, { | ||
showHeaders: false, | ||
preserveNewLines: true, | ||
config: { | ||
unique: {minWidth:1, maxWidth: 1}, | ||
domain: {minWidth: domainColumnWidth}, | ||
IPAddress: {minWidth: 15}, | ||
provider: {minWidth: providerColumnWidth}, | ||
nameServer: {minWidth: nameServerColumnWidth}, | ||
duration: {minWidth: 7} | ||
} | ||
}); | ||
console.log(columns); | ||
}); | ||
console.log(columns); | ||
}); | ||
}); | ||
}); | ||
} catch(err) { | ||
console.error('An error occurred: %O'.red, err); | ||
} catch(err) { | ||
console.error('An error occurred: %O'.red, err); | ||
} | ||
} | ||
} |
{ | ||
"name": "distributed-dig", | ||
"version": "1.0.4", | ||
"description": "Issues DNS lookup requests across multiple DNS servers and collates the results.", | ||
"version": "1.1.0", | ||
"description": "A utility which makes DNS lookup requests across multiple DNS resolvers and collates the results.", | ||
"main": "distributed-dig.js", | ||
@@ -30,3 +30,4 @@ "scripts": { | ||
"address", | ||
"edns" | ||
"edns", | ||
"ddig" | ||
], | ||
@@ -33,0 +34,0 @@ "author": "Mark Murphy", |
@@ -77,3 +77,3 @@ # distributed-dig | ||
Enables [EDNS(0)](https://en.wikipedia.org/wiki/Extension_mechanisms_for_DNS) | ||
Default: `false` (_disabled)) | ||
Default: `false` (_disabled_) | ||
@@ -127,2 +127,4 @@ With EDNS(0) enabled, if an upstream resolver doesn't support it then the standard DNS will be used as a fallback. | ||
![ddig www.asos.com](https://marksmurphy.github.io/img/ddig.example.01.png) | ||
### Lookup a single domain with verbose enabled | ||
@@ -136,5 +138,7 @@ | ||
![ddig www.asos.com --verbose](https://marksmurphy.github.io/img/ddig.example.02.png) | ||
### Lookup multiple domains with an increased timeout | ||
* List the IP addresses returned for `www.asos.com`, `my.asos.com` & `secure.asos.com` from each of the configured resolver with a 5 second timeout: | ||
* List the IP addresses returned for both `www.asos.com` & `secure.asos.com` from each of the configured resolver with a 5 second timeout: | ||
@@ -145,2 +149,4 @@ ```text | ||
![ddig www.asos.com my.asos.com secure.asos.com](https://marksmurphy.github.io/img/ddig.example.03.png) | ||
## Features | ||
@@ -147,0 +153,0 @@ |
39438
9
720
239