There are two main (Perl) scripts involved, dns2xml and xml2dns, that handle the necessary conversions, along with some additional scripts such as d2xpp that work in conjunction with them. The next few sections describe the roles they play and how to use them. A more development-oriented overview can be found here.
@
symbol is used to denote the current origin. The origin is the name of the current zone as derived from the named.conf
file.IN
class is assumed.
The d2xpp script will attempt to expand these shortcuts, substituting the origin for @
, adding the origin to any DNS names that don't end in a period, and adding explicit owner and class fields to each resource record as needed.
The following zone file fragment (for zone mydomain1.com.
) illustrates the transformation.
Before:
@ IN SOA ns1.mydomain1.com. root.ns1.mydomain1.com.( 1999082501 ; Serial (YYYYMMDDNN) 3600 ; Refresh 600 ; Retry 604800 ; Expire 10800 ) ; Minimum TTL @ NS dns1.mydomain1.com. @ NS dns2.mydomain1.com. www IN A 1.2.3.4 A 1.2.3.5 A 1.2.3.6 cheddar IN A 1.2.3.7 swiss IN A 1.2.3.8
After:
mydomain1.com. IN SOA ns1.mydomain1.com. root.ns1.mydomain1.com.( 1999082501 ; Serial (YYYYMMDDNN) 3600 ; Refresh 600 ; Retry 604800 ; Expire 10800 ) ; Minimum TTL mydomain1.com. IN NS dns1.mydomain1.com. mydomain1.com. IN NS dns2.mydomain1.com. www.mydomain1.com. IN A 1.2.3.4 www.mydomain1.com. IN A 1.2.3.5 www.mydomain1.com. IN A 1.2.3.6 cheddar.mydomain1.com. IN A 1.2.3.7 swiss.mydomain1.com. IN A 1.2.3.8
domain-name
. Any DNS names that don't end with a period will have this origin appended. There is an implicit $ORIGIN zone-name
at the beginning of the file.file-name
into the current file at the point of the directive statement. An optional origin
can be provided for the processing of the included file. This origin is only used for the included file and reverts back to the original origin after the inclusion.default-ttl
can range from 0-2147483647.The d2xpp script will take any origin directives into account when completing domain names, and will physically import any included files into the current file. However, per-record ttl values are not currently supported by the GANY_DNS document type definition, so d2xpp does not process the $TTL
directive in any meaningful manner.
Unfortunately, d2xpp currently performs no such error checking. It was hacked together at the beginning of this project just to have uniform data to feed to dns2xml, and has barely been touched since. It definitely needs to be enhanced/rewritten.
The end result of the preprocessing is a series of zone files that have all the common typing shortcuts expanded (most importantly, all DNS names are fully qualified, taking into account any $ORIGIN
directives), and physically contain all the external files that were originally specified by the $INCLUDE
directive. The transformed zone files are valid zone files in their own right, just fully expanded. As mentioned earlier, error-checking should also take place, but currently doesn't. At this point, the zone files should be in a form that the dns2xml script can reasonably work with.
d2xpp -i input-directory -o output-directory [-d]
input-directory
.$TTL
directive.A|PTR|CNAME|MX|TXT|HINFO|NS|SOA
. This needs to be generalized so it recognizes the other possible types. I don't want to do it now because it's 2am and I'll screw something up! (The dns2xml script can handle types other than those listed if it comes across them, they'll just never get past d2xpp if they're not recognized.)
dns2xml -c conf-file -i in-dir -o out-file -n bind-conf -p subpart-method -x -s -h -d
dns2xml.conf
in the input directory (where the preprocessed zone files are located.) Many of the command line options can be specified in this configuration file, but most importantly, it defines the (required) default forward and reverse zone information.
The configuration file is actually Perl code defining variables that get imported into dns2xml via a do
statement. It looks like this:
# dns2xml.conf - Configuration file for dns2xml. # Values on command line override corresponding values below. # The directory where the preprocessed zone files are located. $Input_Dir = "/path/to/preprocessed/zone/files/"; # The name of the XML file to be generated. $Output_File = "d2x_output.xml"; # The name of the BIND configuration file. $Named_Config_File = "named.conf"; # The level of debugging information output. $Debug = 0; # 0...3 # The method by which ambiguous systems are handled. $Sub_Part_Method = ""; # none|sys_unique|ip_unique # Explicitly generate all info that is usually implied in the XML. $Expand = 0; # Don't generate the pretty-printing indentation for the XML output. $Squash = 0; # The default info for forward zones. Edit as necessary. REQUIRED. $Default_Forward = { # Basics 'TYPE' => 'DEFAULT', 'NAME' => 'FORWARD', 'FILE' => '', # SOA Values 'REFRESH' => 10800, 'RETRY' => 600, 'EXPIRE' => 604800, 'MINTTL' => 21600, 'HOST' => 'ns1.mydomain1.com.', 'MAILADDR' => 'root.ns1.mydomain1.com.', # Nameservers 'NS' => { 'dns1.mydomain1.com.' => 1, # The '1' value just indicates 'dns2.mydomain1.com.' => 1, # that the hash key is defined. }, # Default MX hosts 'MX' => { '10 mxhost1.mydomain1.com.' => 1, '15 mxhost2.mydomain1.com.' => 1, }, }; # The default info for reverse zones. Edit as necessary. REQUIRED. $Default_Reverse = { # Basics 'TYPE' => 'DEFAULT', 'NAME' => 'REVERSE', 'FILE' => '', # SOA Values 'REFRESH' => 10800, 'RETRY' => 600, 'EXPIRE' => 604800, 'MINTTL' => 21600, 'HOST' => 'ns1.mydomain1.com.', 'MAILADDR' => 'root.ns1.mydomain1.com.', # Nameservers 'NS' => { 'dns1.mydomain1.com.' => 1, 'dns2.mydomain1.com.' => 1, }, # Default MX hosts 'MX' => { '10 mxhost1.mydomain1.com.' => 1, '15 mxhost2.mydomain1.com.' => 1, }, }; 1; # required to return an 'OK' value to the 'do' statement.
d2x_output.xml
in the input-directory
.named.conf
in the input-directory
.Here's an example (with extremely simplified notation):
x IN A 1 x IN A 2 x IN A 3 y IN A 1 y IN A 5In this case,
x
would be designated the system by dns2xml, and y
the name of the 1
interface of x
. The problem lies with the 5
interface. It is not related to x
, but is related to y
, and y
IS related to x
. How does 5
actually fit in?
The choices for resolving the ambiguity are as follows:
<SYSTEM>
can also appear in other <SYSTEM>
elements, but that the uniqueness of DNS names between systems must be maintained. In the given problem, the 1
interface is repeated in both systems but the y
DNS name only appears in System 2
:
System 1: x IN A 1 x IN A 2 x IN A 3 System 2: y IN A 1 y IN A 5
<SYSTEM>
can have the same name as an entirely different <SYSTEM>
, but interfaces can't overlap between the two systems.
In the given problem, the y
DNS name is repeated in both systems but the 1
interface only appears in System 1
:
System 1: x IN A 1 x IN A 2 x IN A 3 y IN A 1 System 2: y IN A 5
<SYSTEM>
elements as just described. The resource records are the same in both cases, they are just assigned to different systems depending on the method chosen.
PTRTYPE
attribute can encode which PTR
resource records are associated with the system without having to explicitly list any <PTR>
elements in the system itself. Using implied values in this way reduces the size of the XML file considerably and reduces the visual clutter quite a bit.
This option is useful for debugging purposes and if the application that reads the XML doesn't know the rules for extracting and applying the implied values.
named.conf
file.xml2dns -c conf-file -i xml-file -o out-dir -n bind-conf -s serial-file -v verbosity -a -f -d -h
xml2dns.conf
in the output-directory
(where the generated zone files are to be located.)
The configuration file is actually Perl code defining variables that get imported into xml2dns via a do
statement. It looks like this:
# xml2dns.conf - Configuration file for xml2dns. # Values on command line override corresponding values below. $Output_Dir = "output"; $Input_File = "d2x_output.xml"; $Named_Config_File = "x2d.named.conf"; $Debug = 0; $Serial_Num_File = "lastserial.dat"; $Alias_As_Cname = 0; $Verbosity = 3; 1;
d2x_output.xml
in the output-directory
.named.conf
in the output-directory
.lastserial.dat
in the output-directory
.0
indicates that all shortcuts should be taken, while 1..3
indicate decreasingly aggressive shortcutting (fully-qualifying domain names, replacing @
with the origin, etc.)
This is basically only for the benefit of human readers and debugging. Since the files are automatically generated, the shortcuts don't serve any timesaving functions, and the level should probably just be left at 3
.
named.conf
file.<RECORD>
elements?)Given a directory of BIND zone files called named
, the roundtrip process usually goes something like this:
named_pp
) to contain the pre-processed versions of the zone files in named
.named
directory, specifying named_pp
as the output directory. This should generate pre-processed versions in named_pp
of the zone files in named
, and should also copy the BIND config file (usually named.conf
) to the named_pp
directory.dns2xml.conf
file (by editing a copy of the default one) and place that in named_pp
.named_pp
as the input directory and test.xml
as the XML file to output.At this point the complete XML file is generated and can be examined. The next stage is to generate new zone files from test.xml
:
named_out
) to contain the newly generated zone files.xml2dns.conf
file (by editing a copy of the default one) and place that in named_out
.test.xml
as the input file and named_out
as the output directory, using verbosity level 3
.named_pp
with the generated files in named_out
(sortdiff* can help with this.)(*)The sortdiff script is a quick little hack that is basically a Perl wrapper around 'diff' that will examine two directories file-by-file, or two single files, that have first been sorted. This seems to be a simple but effective way to check content without regard to spacing or ordering. It's not really part of the dns/xml scripts so isn't described further here.