Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

DNS Lookups with Perl Net::DNS::Resolver

Sometimes when parsing logs or files you need to know what the IP resolves to. This Perl script uses Net::DNS::Resolver to Automate DNS Lookups.

The advantage of using Net::DNS::Resolver over other methods is the ability to get more information from the DNS servers, and specify which DNS servers to use.

#!/usr/bin/perl

# takes list of DATA and does dns lookup
# gethostbyaddr uses whatever is confiogured on said client
# Net DNS Resolver allows you to specify lookup servers in script

#usage: perl resolver.pl > hosts.csv

$|++;
use warnings;
use strict;
use Socket;
use Net::DNS::Resolver;

my %ips;	# will hold deduped list of ips addresses

# process the data handle and load up the hash
while (<data>) {
	my $ip = $_;
	chomp $ip;
	$ips{$ip}++;
}

# get counts
my $ips = %ips;
my $count = 0;
print "FOUND $ips IPs\n";

# deduped, now proceed by looping over hash keys
foreach my $ip (keys %ips) {

	$count++;  # real count of found ips, different than input ips

	# if you want to see status on a large list (sometimes it takes hours to process large lists)
	#warn "$count -> $ip\n";

	# very crude, use real regex module if you care
	# if your input isn't tested, you need to fix this
	if($ip =~ /^\d+.\d+.\d+.\d+$/) {

	    # NET::DNS::Resolver way:
		# create new Resolver Object, YMMV
		my $res = new Net::DNS::Resolver(
			nameservers => [ '192.168.1.1', '208.67.222.222', '208.67.220.220' ],
		#debug       => 1 # spews entire DNS query results
    		recurse     => 1,
    		# 1 = recursive, accurate, keeps asking anyone, even poisoned caches until it thinks answer is right
    		# 0 = iterative, final answer, no verification from others
    		#iterative is probably how security should be handled.
		);

		# even with timeout of 5 this can take hours on a large list
		$res->tcp_timeout(5);

		# change IP from 192.168.1.15 to 15.1.168.192.in-addr.arpa for searching
		my $target_IP = join('.', reverse split(/\./, $ip)).".in-addr.arpa";

		# query DNS
		my $query = $res->query("$target_IP", "PTR");

		# if a result is found
		if ($query){
		    print("'$ip,'");

		    # for every result, print the IP address
		    foreach my $rr ($query->answer){
		        # show all unless the type is PTR (pointer to a canonical name)
		        next unless $rr->type eq "PTR";

		        # remove the period at the end
		        printf(substr($rr->rdatastr, 0, -1));
		        print "'\n";
		    }
		} else {
			print "'$ip','UNKNOWN'\n";
		}

    } else {
        print " Expected: <host>, got <$ip>\n";
    }

}

__DATA__
1.1.1.1
10.10.0.10
192.192.192.192
8.8.8.8
Last updated on 10 Oct 2018
Published on 10 Oct 2018