(2) checking dns records from named.conf (incl script)
Evren Yurtesen
yurtesen at ispro.net.tr
Tue Jul 22 01:05:49 PDT 2003
OK So I finished working on it :) I think you will find this script very
useful. Now it opens the named.conf file and checks all the domains if
they show your name servers or not.
Any comments or suggestions?
I still wonder how you manage the domain files of 350000 domains?
Evren
On Mon, 21 Jul 2003, Peter McGarvey wrote:
> * Evren Yurtesen <yurtesen at ispro.net.tr> [2003-07-21 14:57:35 BST]:
> > I have about 1000 domain names in my named.conf file.
> > I wonder if it would be possible to check the validity of these domains
> > or even if they are pointing to my name server or not easily...
> > Is there a ready script or something somebody knows here?
> >
>
> Well, I'm trying to combine the DNS platforms of 4 different companies
> onto a single standard platform. I've got over 350,000 domains.... all
> of which need redelegating. And just to make life fun these 4 different
> platforms have all been left to rot for years.
>
> None of the tools I've found have provided me with any of the
> information I need to speed up the process. So I've resorted to using a
> variety of tools, and writing my own.
>
> For checking the actual zonefiles, I tend to use named-checkzone which
> is part of the bind distribution - but not part of the BSD install
> unfortunately.
>
> As for my scripts... well they are rather nasty :-(
>
> But I've attached a re-hacked hack of a hack script of mine that may be
> useful.
>
> cat domainlist | perl auths.pl
>
>
>
> --
> TTFN, FNORD
>
> Peter McGarvey
> Freelance FreeBSD Hacker
> (will work for bandwidth)
>
-------------- next part --------------
#!/usr/bin/perl
#
#
# Creation Date: 21st July 2003
#
# Author:
# Peter P. McGarvey <xaphod at techie.com>
#
# Additional Code:
# Evren Yurtesen <yurtesen at ispro.net.tr>
#
# VERSION HISTORY
#
# format x.y.z
# - x = Major version number
# - y = Minior version number
# - z = Burst number
# I work in bursts. Weekend here, couple of hours a night
# there, then a night (a week etc.) off to think. The
# `burst number' helps me keep track of different versions
# methinks CVS would be a good idea one day.
#
# 0.0.1 2003-07-21 - Peter P. McGarvey <xaphod at techie.com>
# * A NASTY hack of a perl script.
# 0.1.1 2003-07-22 - Evren Yurtesen <yurtesen at ispro.net.tr>
# * Added named.conf file parsing
# * Added automatical nameserver checking
#
use vars qw($VERSION);
$VERSION = '0.1.1';
#
# =============================================================================
#location of named.conf file
$named_conf="/etc/namedb/named.conf";
#the name servers you expect to see
@name_servers=('ns1.ispro.net','ns2.ispro.net','dns1.ispro.net.tr','dns2.ispro.net.tr');
#the min number name servers must be set in domain correctly
$name_server_num=2;
#debugging level (the higher, the more text!)
#0 only shows errors
#10 shows if domain is OK too
#20 shows name servers too
#30 shows everything
$debug=0;
# =============================================================================
# Starting the Code
use Net::DNS;
my $timeout=0;
my @domainlist = &get_domain_list;
foreach my $zone (&get_domain_list) {
#while(my $zone = <domainlist>) {
$error=0;
$rightdns=0;
#find parent zone
my ($parent_zone) = $zone =~ /^[^\.]*\.(.*)/;
#get auth primary
my $parent_auth_primary = &get_auth_primary($parent_zone, $timeout);
#get name server list
if ($parent_auth_primary != -1) {
@auth_servers = &get_ns_list($zone, $parent_auth_primary, $timeout);
} else {
$error=1;
}
#if there are no ns servers then error
if (scalar(@auth_servers) == 0) {
$error=1;
}
foreach my $ns (@auth_servers) {
chop($ns);
foreach my $nserver (@name_servers) {
if(lc($nserver) eq lc($ns)) {
$rightdns+=1;
}
}
}
if ( $rightdns < $name_server_num) {
$error=1;
}
#print our findings
if ($debug >= 10 && $error == 0) {
print ("\n# zone\tOK\t\t\t: $zone\n");
}
if ($error != 0) {
print ("\n# zone\t!!! ERROR !!!\t\t: $zone\n");
}
if ($debug >= 30) {
print "# parent zone\t\t\t: $parent_zone\n";
if ($parent_auth_primary != -1) {
print "# parent auth primary is\t: $parent_auth_primary\n";
}
}
if ($parent_auth_primary == -1) {
print "# error\t\t\t\t\t: DEAD ZONE - ABORT\n";
}
if ($debug >= 20 && ! ($rightdns < $name_server_num) && (scalar(@auth_servers) != 0) && $parent_auth_primary != -1) {
$num=0;
foreach my $ns (@auth_servers) {
$num+=1;
print ("# nameserver $num\t\t\t: $ns\n");
}
}
if ((scalar(@auth_servers)) == 0 && $parent_auth_primary != -1) {
print ("# error\t\t\t\t: NO AUTH SERVERS - DEAD ZONE\n");
} elsif ( $rightdns < $name_server_num && $parent_auth_primary != -1) {
print ("# error\t\t\t\t: NAME SERVERS SET INCORRECTLY\n");
$num=0;
foreach my $ns (@auth_servers) {
$num+=1;
print ("# nameserver $num\t\t\t: $ns\n");
}
}
}
# =============================================================================
# End of the Code - Start of the Sub-Functions
# &get_domain_list - Returns the list of domains from named.conf.file
# &get_auth_primary - Takes the name of a zone
# Return the MNAME field from the SOA
# &get_ns_list - Returns the list of NS records reported by that server
# =============================================================================
# Returns the list of domains from named.conf file
sub get_domain_list {
open(NAMED_CONF,"< $named_conf") or die "Can not open $named_conf";
#set some variables to 0
$comment_block_starting=0;
$comment_block_started=0;
#make a list of domains
while($line=<NAMED_CONF>) {
#find if there is double backslash and use only left of it
#we must put newline
if($line =~ /\/\//) {
$line=(split /\/\//,$line)[0]."\n";
}
#find if there is both /* my text */ in $line and use only outside
if ($line =~ /\/\*/ && $line =~ /\*\//) {
@values1=split(/\/\*/,$line);
@values2=split(/\*\//,$line);
$line=$values1[0].$values2[1];
} else { #find if there is only one of them?
#if there is only /* take left side and wait until finding */
if($line =~ /\/\*/) {
$line=(split /\/\*/,$line)[0];
#count the occurances in case if they are nested
$comment_block_starting+=1;
}
#if there is only */ then stop waiting and take right side
if($line =~ /\*\//) {
$line=(split /\*\//,$line)[1];
if(($comment_block_starting-=1) == 0) {
$comment_block_started=0;
}
}
}
if (($comment_block_started=$comment_block_starting) == 0) {
if($line =~ /zone.+\".+\"/ && ! ($line =~ /zone.+\"."/ || $line =~ /zone.+\".*ARPA\"/i)) {
$line=(split /\"/,$line)[1];
#cut out left and right spaces just to be sure
$line =~ s/^\s+|\s+$//g;
push(@domainlist,$line);
}
}
}
close(NAMED_CONF);
return sort @domainlist;
}
# =============================================================================
# Takes the name of a zone
# Return the MNAME field from the SOA
sub get_auth_primary {
my $zone = shift;
my $tcp_timeout = shift;
my $res = new Net::DNS::Resolver;
my $packet = new Net::DNS::Packet($zone, "SOA", "IN");
$res->tcp_timeout($tcp_timeout) if $tcp_timeout;
my $req = $res->send($packet);
return -1
unless defined($req);
return -1
unless ( ($req->header->ancount >= 1)
&& (($req->answer)[0]->type eq "SOA") );
return ($req->answer)[0]->mname . ".";
# Return the FQDN
}
# =============================================================================
# Returns the list of NS records reported by that server
sub get_ns_list {
my $zone = shift;
my $server = shift;
my $tcp_timeout = shift;
my @ns_list;
my $res = new Net::DNS::Resolver;
$res->tcp_timeout($tcp_timeout) if $tcp_timeout;
#die "FAIL: NS has no address (" . $res->errorstring . ")"
return @ns_list
unless $res->nameservers($server);
my $req = $res->query($zone, "NS");
#die "WARN: NS query results were bad (" . $res->errorstring . ")"
return @ns_list
unless ( defined($req)
&& ($req->header->ancount > 0) );
foreach my $rr_ns ($req->answer) {
push @ns_list, $rr_ns->nsdname . "."; #FQDN!
}
return sort @ns_list;
}
More information about the freebsd-isp
mailing list