DDNS updating of ranges
Kevin Darcy
kcd at daimlerchrysler.com
Thu Dec 2 01:46:41 UTC 2004
James Baldwin wrote:
> We are in the process of setting up Bind to act as a RBL internally.
>As we have several hosts who will be updating the zones therein we will
>be running with dynamic dns. One of the issues we've come across,
>however, is how to efficiently update records for large CIDR ranges. We
>can do some trickery if the CIDR range falls on an octet boundary (at
>least I think we can), but we're having trouble coming up with an
>elegant fashion to add non round numbers (!= /8, /16, /24, /32).
> I looked through the nsupdate manpage and did not see anything that
>suggested range updates are available. Are there any dynamic dns update
>tools which allow actions similar to the $GENERATE directive and/or for
>removal of records created in that fashion? Is there anything else that
>might give a similar experience or am I left having to wrap nsupdate in
>something else and call it repeatedly?
>
For an RBL, you should be able to use wildcards at each octet boundary.
Between octet boundaries, you'll have to do several updates (which may
themselves be wildcards), up to a maximum number of 128 updates. But
doing multiple updates shouldn't always entail calling nsupdate
repeatedly: you can make several updates in a single update transaction,
as long as they are all for the same zone. E.g. to specify the
192.168.16/22 range, you could do
zone 168.192.rbl.
update add *.16.168.192.rbl. 1d a 127.0.0.2
update add *.17.168.192.rbl. 1d a 127.0.0.2
update add *.18.168.192.rbl. 1d a 127.0.0.2
update add *.19.168.192.rbl. 1d a 127.0.0.2
send
Here's a quick-and-dirty (should do more input validation) piece of Perl
code that will take a list of address prefixes on stdin, along with a
domain suffix as a command-line parameter, and generate the appropriate
nsupdate commands, including the "send", for adding 127.0.0.2 A records
and/or wildcards under that prefix in the reverse-octet convention, for
the corresponding address range. It assumes each prefix given on stdin
falls within a given RBL zone. If an address prefix spans RBL zones,
then the input should be preprocessed accordingly. If, on the other
hand, you only have one huge RBL zone, then you could move the "send"
out of the loop to the very end of the script, since it will always be
possible to do all of the updates in a single transaction.
#!/usr/bin/perl
use integer;
($domain = $ARGV[0]) =~ s/\.$//;
while (<STDIN>) {
($addr, $prefix) = split(m%/%);
die "prefix out of range" if (($prefix > 32) || ($prefix < 1));
@octet = split(/\./, $addr);
$wildcard = '*.' x ((32 - $prefix) / 8);
$fixed = "";
if ($prefix > 8) {
$fixed = ".".(join('.', reverse(@octet[0..(($prefix-9)/8)])));
}
$fixed .= ".$domain";
for ($i = 0; $i < (1 << ((32 - $prefix) % 8)); $i++) {
printf("update add %s%s%s. 1d a 127.0.0.2\n",
$wildcard, $octet[($prefix - 1)/8]++, $fixed);
}
print "send\n";
}
- Kevin
More information about the bind-users
mailing list