#!/usr/bin/perl -w # tristan+dns@ethereal.net 7mar2003 # # goes through a list of domains to slave, verifies their legitimacy, outputs # bind8/9 config # # whipped this up in about an hour, don't blame me for bugs :) @::iam = qw(ns1.ethereal.net ns.yikes.net spicy.datasoup.com); $::root = 'a.root-servers.net.'; use Net::DNS; use strict; sub runquery { my($res, $domain, $domains, $ns) = @_; $$res->nameservers($ns); my $packet = Net::DNS::Packet->new($domain, 'NS', 'IN'); my $query = $$res->send($packet); if ($query) { if ($query->answer) { my $good; my @nameservers; foreach my $rr ($query->answer) { next unless $rr->type eq 'NS'; my $name = lc $rr->nsdname; if ($::iam{$name}) { $good = 1; } else { push(@nameservers, $name); } } if ($good) { @{$$domains{$domain}{ns}} = @nameservers; } else { $$domains{$domain}{bad} = "exists, but I'm not a nameserver for it"; } return 1; } elsif ($query->authority) { my $results = 0; foreach my $rr ($query->authority) { next unless $rr->type eq 'NS'; $results++; last if runquery($res, $domain, $domains, $rr->nsdname); } $$domains{$domain}{bad} = "domain doesn't exist" unless $results; } } else { warn "query against $ns failed: ", $$res->errorstring, "\n"; } } sub main { my $res = Net::DNS::Resolver->new; my $res2 = Net::DNS::Resolver->new; $res->recurse(0); $res->udp_timeout(3); $res->tcp_timeout(3); my %domains; for (@::iam) { $::iam{$_} = 1; } while (<>) { chomp; if ($_ && !/^#/) { warn "doing $_\n"; runquery(\$res, $_, \%domains, $::root) if ($_ && !/^#/); } } foreach my $domain (sort keys %domains) { next if $domains{$domain}{bad}; my $lame = 1; for my $ns (@{$domains{$domain}{ns}}) { if ($lame) { $res->nameservers($ns); my $query = $res->query($domain, 'SOA'); if ($query && $query->answer) { foreach my $rr ($query->answer) { next unless $rr->type eq 'SOA'; my $mname = $rr->mname; if ($::iam{$mname}) { $domains{$domain}{bad} = "SOA MNAME is me"; last; } $res->nameserver($mname); my @zone = $res->axfr($domain); if ($#zone > 0) { my $query = $res2->search($mname); if ($query && $query->answer) { foreach my $rr ($query->answer) { next unless $rr->type eq 'A'; my $addr = $rr->address; print <