I was recently helping someone troubleshoot an issue in which one of their DNS servers was returning incorrect IP information for certain domains. Below is a Perl script that makes use of the Net::DNS module to compare the resolved IP addresses for a specified list of domains from a specified list of nameservers. I have it commented out in the script below, but by uncommenting the appropriate line you can also execute a system call to flush the DNS cache of the machine before each set of DNS requests.
#!usr/bin/perl
use Net::DNS;
use strict;
use warnings;
my @domains = ('perl.org','cpan.org','perlmonks.org','perlfoundation.org','perlweekly.com','perlbuzz.com','perlsphere.net');
my @DNServers = ('167.206.112.138','8.8.8.8','208.67.222.222');
foreach my $DNS (@DNServers){
#flush DNS cache by uncommenting OS specific option
#system('/etc/init.d/nscd restart');
#system('ipconfig /flushdns');
print "Results for $DNS:\n";
my $res=Net::DNS::Resolver->new;
$res->nameservers($DNS);
foreach my $domain(@domains){
#queries server
my $answer = $res->search("$domain");
#extract IPs specified in A records
foreach my $record ($answer->answer) {
next unless $record->type eq "A";
print "$domain:" . $record->address . "\n";
}
};
print "\n\n";
}
4 comments:
nice.
I would add a timeout on the request :
$res->tcp_timeout(5) for example.
Moreover i would add an error handling in case $answer is undefined
if($answer) {
foreach my $record...
...
}
else{
print "unable to access $domain \n"
}
anyway, thanx
I found it useful to print the DNS response time:
#!/usr/bin/perl
use Net::DNS;
use Modern::Perl;
use Time::HiRes qw(tv_interval gettimeofday);
my @domains = ('perl.org','cpan.org','perlmonks.org','perlfoundation.org','perlweekly.com','perlbuzz.com','perlsphere.net');
my @DNServers = ('192.168.1.254','8.8.8.8','208.67.222.222');
foreach my $DNS (@DNServers){
#flush DNS cache by uncommenting OS specific option
#system('/etc/init.d/nscd restart');
#system('ipconfig /flushdns');
say "Results for $DNS:";
my $res=Net::DNS::Resolver->new;
my $t0 = [gettimeofday];
$res->nameservers($DNS);
foreach my $domain(@domains){
#queries server
my $answer = $res->search("$domain");
#extract IPs specified in A records
foreach my $record ($answer->answer) {
next unless $record->type eq "A";
say "$domain:" . $record->address;
}
}
say "Time elapsed: " . tv_interval($t0);
say "\n";
}
For those visitors coming in from search engines, this code discussed in the article is only good for trouble-shooting situations.
Most of the time, when you want to resolve names, you should use the operating system's resolver, because the operating system knows best. See IO::Socket::IP and Socket.
FYI: A "cleaner" way of clearing the nscd cache is with /usr/sbin/nscd -i hosts.
Post a Comment