From Vixie's 2005 paper "Federated Domain Name Service Using DNS Metazones". I couldn't find an implementation, and I've got a feeling the example zone is missing the prefix.
Script is at the bottom. Here's the example zone:
$ORIGIN fh-sa.mz.vix.com.
$TTL 3600
@ SOA ( ns.lah1.vix.com. hostmaster.vix.com. 2005050704 3600 1800 604800 42 ) ;
@ NS ns.lah1.vix.com.
@ NS ns.sql1.vix.com.
masters RT 10 ns-lah1.servers
allow-transfer MG fh-sa.tsig.vix.com.
MG ns-ext.
also-notify RT 10 ns-ext.servers
;
$ORIGIN servers.fh-sa.mz.vix.com.
ns-lah1 A 204.152.188.234
AAAA 2001:4f8:2::9
ns-ext A 204.152.184.64
AAAA 2001:4f8:0:2::13
;
$ORIGIN zones.fh-sa.mz.vix.com.
vix.com PTR vix.com.
anog.net PTR anog.net.
anog.org PTR anog.org.
is to generate:
zone "vix.com" {
type slave;
file "sec/fh-sa.mz.vix.com/vix.com";
masters {
204.152.188.234;
2001:4f8:2:0:0:0:0:9;
};
also-notify {
204.152.184.64;
2001:4f8:0:2:0:0:0:13;
};
allow-transfer {
key fh-sa.tsig.vix.com;
key ns-ext;
};
};
zone "anog.net" {
type slave;
file "sec/fh-sa.mz.vix.com/anog.net";
masters {
204.152.188.234;
2001:4f8:2:0:0:0:0:9;
};
also-notify {
204.152.184.64;
2001:4f8:0:2:0:0:0:13;
};
allow-transfer {
key fh-sa.tsig.vix.com;
key ns-ext;
};
};
zone "anog.org" {
type slave;
file "sec/fh-sa.mz.vix.com/anog.org";
masters {
204.152.188.234;
2001:4f8:2:0:0:0:0:9;
};
also-notify {
204.152.184.64;
2001:4f8:0:2:0:0:0:13;
};
allow-transfer {
key fh-sa.tsig.vix.com;
key ns-ext;
};
};
script:
#!/usr/bin/env perl
# vim: set sts=2 sw=2 ts=8 et ai:
# 2014, Brad Forschinger
use strict;
use warnings;
use Net::DNS;
my $MZ_NAME = $ARGV[0] || "fh-sa.mz.vix.com";
my $res = Net::DNS::Resolver->new;
$res->nameservers("localhost");
my @mz = $res->axfr($MZ_NAME) or die "axfr: $!";
print make_zone_config(sort map { $_->ptrdname } grep { $_->type eq "PTR" } @mz);
exit;
sub make_zone_config {
my $name = shift or return;
"zone \"$name\" {\n",
"\ttype slave;\n",
"\tfile \"sec/$MZ_NAME/$name\";\n",
conf_from_rt("masters", $name),
conf_from_rt("also-notify", $name),
conf_transfer($name),
"};\n\n",
make_zone_config(@_);
}
sub conf_from_rt {
my $statement = shift or return;
"\t$statement {\n", (
map {
my $server = $_->intermediate;
map { "\t\t" . $_->address . ";\n" }
grep { $_->name eq $server && ($_->type eq "A" || $_->type eq "AAAA") } @mz;
}
sort { $a->preference <=> $b->preference }
grep { $_->type eq "RT" && $_->name =~ /^\Q$statement.\E/ } @mz
),
"\t};\n";
}
sub conf_transfer {
"\tallow-transfer {\n", (
map { "\t\tkey " . $_->mgmname . ";\n" }
grep { $_->type eq "MG" && $_->name =~ /^allow-transfer\./ } @mz
),
"\t};\n";
}