Skip to content

Commit

Permalink
Working
Browse files Browse the repository at this point in the history
  • Loading branch information
brannondorsey committed Mar 31, 2018
1 parent f4f7a5b commit 8012ca3
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 39 deletions.
52 changes: 38 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const log = require('loglevel')
const c = require('chalk')
const { ArgumentParser } = require('argparse')

const Client = require('./src/Client.js')
const DomainRebind = require('./src/DomainRebind.js')
const server = dns.createServer()

function main() {
Expand All @@ -14,39 +14,48 @@ function main() {
log.setDefaultLevel('info')
log.setLevel('debug')

const clients = {}
const domains = {}
const orderedDomains = new Set()

server.on('request', (request, response) => {

request.question.forEach(question => {

const domain = question.name
log.debug(question)

if (!clients.hasOwnProperty[domain]) {
clients[domain] = new Client(domain)
if (!domains.hasOwnProperty(domain)) {
domains[domain] = new DomainRebind(domain)
orderedDomains.add(domain)
if (orderedDomains.size > args['max_client_records']) {
// remove the oldest client from the set and dict
const oldest = orderedDomains.values().next().value
orderedDomains.delete(oldest)
delete domains[oldest]
}
}

const address = clients[domain].next()
const address = domains[domain].next()

let answer = {
name: domain,
address: address || args['default_answer'],
ttl: 1,
ttl: 1
}

// only handle A and CNAME for now
// only handle A for now
switch(question.type) {

case dns.consts.NAME_TO_QTYPE.A:
response.answer.push(dns.A(answer))
break

default:
console.log('in here')
}
})

if (response.answer.length > 0) {
response.answer.forEach(ans => {
log.info(c.blue('[+]') + ` A ${c.cyan(ans.address)} ${ans.name}`)
})
}

response.send()
})

Expand All @@ -55,12 +64,13 @@ function main() {
})

server.on('error', (err, buff, req, res) => {
console.log(err.stack)
log.error(c.red('[!]') + ' native-dns server error:')
log.error(err.stack)
})

server.on('socketError', (err, socket) => {
if (err.code == 'EACCES') {
let m = c.red(`[!]`)
let m = c.red('[!]')
m += ` Fatal error binding to port ${args.port}, address in use.`
log.error(m)
}
Expand Down Expand Up @@ -94,6 +104,20 @@ function parseArgs() {
}
)

let message = 'The number of domain name records to store in RAM at once. '
message += 'Once the number of unique domain names queried surpasses this number '
message += 'domains will be removed from memory in the order they were '
message += 'requested. Domains that have been removed in this way will '
message += 'have their program state reset the next time they are queried '
message += '(default: 10000000).'
parser.addArgument(
[ '-b', '--max-ram-domains' ],
{
help: message,
defaultValue: 10000000
}
)

return parser.parseArgs()
}

Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@
"chalk": "^2.3.2",
"loglevel": "^1.6.1",
"native-dns": "^0.7.0"
},
"devDependencies": {
"uuid": "^3.2.1"
}
}
12 changes: 5 additions & 7 deletions src/Client.js → src/DomainRebind.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
const ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

class DomainRebind {

class Client {

// ntimes
// forever
// repeat
constructor(domain) {
this.domain = domain
this.program = this.parseProgram(this.domain)
Expand Down Expand Up @@ -35,10 +31,12 @@ class Client {
return instruction.ip
}

// ntimes
// forever
// repeat
parseProgram(domain) {

const labels = domain.toLowerCase().split('.')

const instructions = []

if (labels.length < 1) return []
Expand Down Expand Up @@ -91,4 +89,4 @@ class Client {
}
}

module.exports = Client
module.exports = DomainRebind
88 changes: 70 additions & 18 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,72 @@
const dns = require('dns')
const dnsliar = require('./index')
const Client = require('./src/Client')

const domains = [
'rebind.network',
'A.192.168.1.1.rebind.network',
'A.192.168.1.1.1time.rebind.network',
'A.192.168.1.1.5times.10.0.0.1.1time.rebind.network'
]
const dns = require('dns')
const assert = require('assert')
const uuidv4 = require('uuid/v4')

const { spawn } = require('child_process');
const dnsliar = spawn('node', ['index.js', '--help', 15354])

let running = false
dnsliar.stdout.on('data', (data) => {
console.log(`stdout: ${data}`)
if (!running) {
resolveRequests(requests)
running = true
}
})

domains.forEach(domain => {
let client = new Client(domain)
while (true) {
let ip = client.next()
console.log(domain)
console.log(ip)
if (!ip) break
}
dnsliar.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
})

dnsliar.on('close', (code) => {
console.log(`child process exited with code ${code}`)
})

const uuid = uuidv4()

const requests = [
// domain name, expected result
[`rebind.network`, '127.0.0.1'],
[`A.192.168.1.1.${uuid}.rebind.network`, '127.0.0.1'],

[`A.192.168.1.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.1time.${uuid}.rebind.network`, '127.0.0.1'],

[`A.192.168.1.1.forever.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.forever.${uuid}.rebind.network`, '192.168.1.1'],

[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '10.0.0.1'],
[`A.192.168.1.1.5times.10.0.0.1.1time.${uuid}.rebind.network`, '127.0.0.1'],

[`A.192.168.1.1.1time.192.168.1.2.1times.repeat.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.1time.192.168.1.2.1times.repeat.${uuid}.rebind.network`, '192.168.1.2'],
[`A.192.168.1.1.1time.192.168.1.2.1times.repeat.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.1time.192.168.1.2.1times.repeat.${uuid}.rebind.network`, '192.168.1.2'],

[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.1'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.2'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.2'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.3'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.3'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.3'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.3'],
[`A.192.168.1.1.1time.192.168.1.2.2times.192.168.1.3.forever.${uuid}.rebind.network`, '192.168.1.3']
]

dns.setServers(['127.0.0.1:15354'])

function resolveRequests(requests, index=0) {
if (index < requests.length) {
dns.resolve(requests[index][0], 'A', (err, result) => {
if (err) throw err
console.log(`${result.toString().padEnd(15)} ${requests[index][0]}`)
assert.equal(result, requests[index][1])
resolveRequests(requests, index + 1)
})
}
}

0 comments on commit 8012ca3

Please sign in to comment.