class PassiveDNS::Provider::DNSDB

Queries FarSight's passive DNS database

Attributes

debug[RW]

:debug enables verbose logging to standard output

Public Class Methods

config_section_name() click to toggle source

Sets the configuration section name to “dnsdb”

# File lib/passivedns/client/provider/dnsdb.rb, line 17
def self.config_section_name
  "dnsdb"
end
name() click to toggle source

Sets the modules self-reported name to “DNSDB”

# File lib/passivedns/client/provider/dnsdb.rb, line 13
def self.name
  "DNSDB"
end
new(options={}) click to toggle source

Options

  • :debug Sets the debug flag for the module

  • “APIKEY” REQUIRED: The API key associated with DNSDB

  • “URL” Alternate url for testing. Defaults to “api.dnsdb.info/lookup

Example Instantiation

options = {
  :debug => true,
  "APIKEY" => "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "URL" => "https://api.dnsdb.info/lookup"
}

PassiveDNS::Provider::DNSDB.new(options)
# File lib/passivedns/client/provider/dnsdb.rb, line 42
def initialize(options={})
  @debug = options[:debug] || false
  @timeout = options[:timeout] || 20
  @key = options["APIKEY"] || raise("APIKEY option required for #{self.class}")
  @base = options["URL"] || "https://api.dnsdb.info/lookup"
end
option_letter() click to toggle source

Sets the command line database argument to “d”

# File lib/passivedns/client/provider/dnsdb.rb, line 21
def self.option_letter
  "d"
end

Public Instance Methods

lookup(label, limit=nil) click to toggle source

Takes a label (either a domain or an IP address) and returns an array of PassiveDNS::PDNSResult instances with the answers to the query

# File lib/passivedns/client/provider/dnsdb.rb, line 51
def lookup(label, limit=nil)
  $stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
  Timeout::timeout(@timeout) {
    url = nil
    if label =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$/
      label = label.gsub(/\//,',')
      url = "#{@base}/rdata/ip/#{label}"
    else
      url = "#{@base}/rrset/name/#{label}"
    end
    url = URI.parse url
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = (url.scheme == 'https')
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    http.verify_depth = 5
    path = url.path
    if limit
      path << "?limit=#{limit}"
    end
    request = Net::HTTP::Get.new(path)
    request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
    request.add_field("X-API-Key", @key)
    request.add_field("Accept", "application/json")
    t1 = Time.now
    response = http.request(request)
    t2 = Time.now
    $stderr.puts response.body if @debug
    parse_json(response.body,t2-t1)
  }
rescue Timeout::Error
  $stderr.puts "#{self.class.name} lookup timed out: #{label}"
end

Private Instance Methods

parse_json(page,response_time) click to toggle source

parses the response of DNSDB's JSON reply to generate an array of PDNSResult

# File lib/passivedns/client/provider/dnsdb.rb, line 87
def parse_json(page,response_time)
  res = []
  raise "Error: unable to parse request" if page =~ /Error: unable to parse request/
  rows = page.split(/\n/)
  rows.each do |row|
    record = JSON.parse(row)
    answers = record['rdata']
    answers = [record['rdata']] if record['rdata'].class == String
    query = record['rrname'].gsub!(/\.$/,'')
    rrtype = record['rrtype']
    firstseen = Time.at(record['time_first'].to_i)
    lastseen = Time.at(record['time_last'].to_i)
    count = record['count']
    
    answers.each do |answer|
      answer.gsub!(/\.$/,'')
      if record['time_first']
        res << PDNSResult.new(self.class.name,response_time,query,answer,rrtype,
          0,firstseen,lastseen,count, 'yellow')
      else
        res << PDNSResult.new(self.class.name,response_time,query,answer,rrtype)
      end
    end
  end
  res
rescue Exception => e
  $stderr.puts "#{self.class.name} Exception: #{e}"
  $stderr.puts page
  raise e
end