<HEAD><TITLE>Being a slave DNS server</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">

</HEAD><BODY>

<!-- Copyright 2005,2020 Sam Trenholme

    TERMS

    Redistribution and use, with or without modification, are permitted
    provided that the following condition is met:

    1. Redistributions must retain the above copyright notice, this
       list of conditions and the following disclaimer.

    This documentation is provided 'as is' with no guarantees of
    correctness or fitness for purpose.

 -->

<i>I should point out here that "master" and "slave" is somewhat
outdated wording.  The more modern wording, "primary" and "replica",
is more accurate.  However, since this document was written back when
"master" and "slave" was standard terminology, since other mainstream
DNS servers still use the "master" and "slave" terminology, and since
the relevant DNS RFCs MaraDNS is based on use the words "master" and
"slave", this document uses that wording.</i>

<H1>Having MaraDNS be a slave DNS server</H1>

MaraDNS does not have direct support for being a slave DNS server.
However, MaraDNS can transfer zone files from other servers by using
the <tt>fetchzone</tt> client.  

<p>

<tt>fetchzone</tt> is a program that can transfer a zone from another
name server; the transferred zone is in the csv2 zone file format, which
can then be loaded by MaraDNS.

<p>

Here is an example of using <tt>fetchzone</tt> to transfer the zone
example.com from the server with the IP 10.5.6.7, placing the output
in the file "db.example.com":

<pre>
fetchzone example.com 10.5.6.7 > db.example.com
</pre>

<h2>Automating this with a shell script</h2>

If one wishes to use fetchzone to grab a number of zones, this can
be automated with a shell script:

<pre>
#!/bin/bash

cd /etc/maradns
fetchzone example.com 10.5.6.7 > db.example.com
fetchzone example.org 192.168.5.67 > db.example.org
fetchzone example.net 172.19.2.83 > db.example.net
</pre>

This shell script, however, has a problem.  Should there be a problem
getting a zone file from a remote system, the zone file in question will be
destroyed.  This can be avoided by checking the exit status of 
<tt>fetchzone</tt> in the shell script, making sure that the zone
was obtained normally before overwriting the zone file:

<pre>
#!/bin/bash

# For security reasons, put this file in a directory that only root
# may write to.  
TEMP=/root/tmp/foo

cd /etc/maradns
fetchzone example.com 10.5.6.7 > $TEMP
if [ $? -eq 0 ] ; then
	mv $TEMP db.example.com
fi
fetchzone example.org 192.168.5.67 > $TEMP
if [ $? -eq 0 ] ; then
	mv $TEMP db.example.org
fi
fetchzone example.net 172.19.2.83 > $TEMP
if [ $? -eq 0 ] ; then
	mv $TEMP db.example.net
fi
</pre>

Note that this script needs a directory, which only root may write
to, named <tt>/root/tmp</tt> (Linux has a long-standing tradition of
making root's home directory /root; place this file elsewhere on a system
with a different root directory).

<p>

While this script is workable for a small number of zones, this script will
quickly become unwieldy for a large number of zones.  If one wants
to grab a large number of zones, it makes more sense to have the list
of zones in a separate file.  We then have the shell script read this
file (list of zones and IPs), and make the zone files live if the
zones have been successfully fetched.

<p>

Here is what a shell script may look like:

<pre>
#!/bin/bash

ZONELIST=/etc/maradns.zonelist
# For security reasons, put this file in a directory that only root
# may write to.  
TEMP=/root/tmp/foo

cd /etc/maradns

cat $ZONELIST | awk '{print "fetchzone "$1" "$2" > '$TEMP'"
                      print "if [ $? -eq 0 ] ; then"
		      print "    mv '$TEMP' db."$1
		      print "fi";}' | sh
</pre>

The list of zones, which is in the file <tt>/etc/maradns.zonelist</tt> in
the above example, will look like this:

<pre>
example.com 10.5.6.7 
example.org 192.168.5.67 
example.net 172.19.2.83 
</pre>

Note that the presence of a given db.<i>name</i> file in the /etc/maradns
directory is not sufficient for MaraDNS to load a given zone file; the
zone file in question must be pointed to in the <tt>mararc</tt> file.
Note also that <tt>maradns</tt> must be restarted to reload the updated
zone files.

<p>

More complicated scripting, such as checking the serial number before loading
a given zone, is left as an exercise for the reader.

<h2>Bailiwick</h2>

For security reasons, the <tt>fetchzone</tt> client only allows records that 
end in the zone name to be in a given zone.  In other words, let us suppose we
have a zone for example.com that looks like this:

<pre>
example.com.      10.1.2.3
www.example.com.  10.99.88.76
www.google.com.   10.99.88.76
</pre>

<tt>fetchzone</tt>, when grabbing this zone, will disable the "www.google.com"
record because it doesn't end with "example.com".  The disabling will 
look something like this when the zone file is grabbed:

<pre>
example.com. 10.1.2.3
www.example.com. 10.99.88.76
# Disabled out-of-bailiwick record follows
#www.google.com. 10.99.88.76
</pre>

</BODY></HTML>
