How to run master and slave YADIFA on FreeBSD 9.0

Prime knots chartYADIFA is a nameserver implemented by EURid and is a clean implementation to serve as an alternate domain name server for TLD operators and ISPs alike. Actually it’s at an early stage of development: the current version is 1.0.0 release candidate 2. Anyway it’s worth a try since its declared benchmarks results compared to BIND and NSD (according to a presentation Peter Jannsen gave at RIPE64 in Ljubljana on april 18, 2012):

YADIFA BIND NSD load time comparison

Let me remind you that YADIFA is authoritative-only DNS, so if you need a recursive and caching resolver please consider using Unbound.

I’m going to show you how to install and configure YADIFA on two servers: master and slave. Some steps are the same for both master and slave instances.

Fetch our FreeBSD package from YADIFA website:
fetch http://www.yadifa.eu/download/yadifa-1.0.0rc2.tbz

Install it:
pkg_add yadifa-1.0.0rc2.tbz

Now on master:

Bearing in mind that 192.0.2.1 is our master’s ipv4 address and 192.0.2.2 is our slave’s ipv4 address, copy a fully commented configuration file in the right position:
cp /usr/local/share/examples/yadifa/yadifad.conf.example /usr/local/etc/yadifad.conf

Edit yatifad.conf. Feel free to use the following one slightly edited to serve as master:
vi /usr/local/etc/yatifad.conf


#
# Example yadifa configuration file.
#

<main>
# Detach from the console
daemon on

# Jail the application
chroot off

# The path where all the log files will be written
logpath "/usr/local/var/log"

# The path where the pid file will be written
pidpath "/usr/local/var/run"

# The path where all zone files will be written
datapath "/usr/local/var/zones"

# The path where the DNSSEC keys are found
keyspath "/usr/local/var/zones/keys"

# The path where the transfer and journaling files will be written (AXFR &amp; IXFR)
xfrpath "/usr/local/var/zones/xfr"

# The version returned by a query to version.yadifa. CH TXT
version "1.0.0rc2"

# Enable EDNS0 support (?)
edns0 on

# Set the maximum UDP packet size. Cannot be less than 512. Cannot be more than 65535. Typical choice is 4096.
edns0-max-size 4096

# The maximum number of parallel TCP queries.

max-tcp-queries 100

# The user id to use (an integer can be used)
uid root

# The group id to use (an integer can be used)
gid wheel

# The DNS port. Any DNS query will be made using that port unless a specific value is used.
port 53

# The interfaces to listen to.
listen 0.0.0.0

# Enable the collection and logging of statistics
statistics on

# Choose the query log format (0 for none, 1 for YADIFA, 2 for BIND compatible, 3 for YADIFA and BIND)
queries-log-type 1
# Drop queries with erroneous content
# answer-formerr-packets on

# Maximum number of records in an AXFR packet. Set to one for compatibility
# with very old name servers
# axfr-maxrecordbypacket 0

# Global Access Controlrules.
#
# Rules can be defined on network ranges, TSIG signatures, and ACL rules

# simple queries:
allow-query any

# dynamic update of a zone
allow-update none

# transfer of a zone (AXFR or IXFR)
allow-transfer 192.0.2.2

# notify of a change in the master
allow-notify 192.0.2.2
</main>

#
# Logging output channels configurations
#
# name stream-name arguments
#
# name is arbitrary
# stream-name defines the output type (ie: a file name or syslog)
# arguments is specific to the output type (ie: unix file access rights or syslog options and facilities

<channels>
# name stream-name arguments
database database.log 0644
dnssec dnssec.log 0644
server server.log 0644
statistics statistics.log 0644
system system.log 0644
zone zone.log 0644
queries queries.log 0644
all all.log 0644

syslog syslog USER,CRON,PID

# although possible, these two do not do make much sense if daemon is enabled

stderr STDERR
stdout STDOUT
</channels>

# Logging input configurations
#
# name debug-level channels
#
# name is predefined
# debuglevel uses the same names as syslog or * or all to filter the input
# channels is a comma-separated list of channels

<loggers>
# bundle debuglevel channels
database * database,all
dnssec * dnssec,all
server * server,all
statistics * statistics
system * system,all
zone * zone,all
queries * queries
</loggers>

#
# TSIG Key configuration
#

<key>
name abroad-admin-key
algorithm hmac-md5
secret WorthlessKeyForExample==
</key>

<key>
name master-slave
algorithm hmac-md5
secret MasterAndSlavesTSIGKey==
</key>

#
# Access Control List definitions
#

<acl>
transferer key master-slave
admins 192.0.2.0/24, 2001:db8::74
master 192.0.2.1
slave 192.0.2.2
</acl>

#
# Master domain zone config
#

<zone>
type master
domain localhost
file masters/localhost.zone
allow-transfer slave
allow-update none
allow-update-forwarding none
</zone>

<zone>
type master
domain localhost6
file masters/localhost6.zone
allow-transfer slave
allow-update none
allow-update-forwarding none
</zone>

<zone>
type master
domain 0.0.127.in-addr.arpa
file masters/0.0.127.in-addr.arpa.zone
allow-transfer slave
allow-update none
allow-update-forwarding none
</zone>

<zone>
type master
domain 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
file masters/0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.zone
allow-transfer slave
allow-update none
allow-update-forwarding none
</zone>

<zone>
# This server is master for that zone (mandatory)
type master

# The domain name (mandatory)
domain myzone.demo

# The zone file, relative to 'datapath'. (mandatory for a master)
file masters/myzone.demo.zone
allow-transfer slave
</zone>

Put the zone for myzone.demo in the right position:
vi /usr/local/var/zones/masters/myzone.demo.zone


$TTL 86400
$ORIGIN myzone.demo.
myzone.demo. 600 IN SOA ns1.myzone.demo. (
hostmaster.myzone.demo.
2012041403
86400
7200
604800
86400
)
NS ns1.myzone.demo.
NS ns2.myzone.demo.
ns1 A 192.0.2.1
ns2 A 192.0.2.2

A 192.0.2.10
www CNAME myzone.demo.
ftp CNAME myzone.demo.
MX 0 ASPMX.L.GOOGLE.COM.
MX 5 ALT1.ASPMX.L.GOOGLE.COM.
MX 5 ALT2.ASPMX.L.GOOGLE.COM.
MX 10 ASPMX2.GOOGLEMAIL.COM.
MX 10 ASPMX3.GOOGLEMAIL.COM.

Start YADIFA:
/usr/local/sbin/yadifad

Verify the daemon is listening:
netstat -anfinet|grep '.53'
tcp4 0 0 *.53 *.* LISTEN
udp4 0 0 *.53 *.*

Now query YADIFA for myzone.demo:
dig +norec @localhost -t ANY myzone.demo

; <<>> DiG 9.8.1-P1 <<>> +norec @localhost -t ANY myzone.demo
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24048
;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 3

;; QUESTION SECTION:
;myzone.demo. IN ANY

;; ANSWER SECTION:
myzone.demo. 600 IN SOA ns1.myzone.demo. hostmaster.myzone.demo. 2012041403 86400 7200 604800 86400
myzone.demo. 600 IN NS ns2.myzone.demo.
myzone.demo. 600 IN NS ns1.myzone.demo.

;; ADDITIONAL SECTION:
ns1.myzone.demo. 600 IN A 192.0.2.1
ns2.myzone.demo. 600 IN A 192.0.2.2
ns2.myzone.demo. 600 IN A 192.0.2.10

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Apr 20 18:28:44 2012
;; MSG SIZE rcvd: 160

On your slave server.
Edit the configuration file. Again, feel free to use the following one slightly edited to serve as slave:
vi /usr/local/etc/yadifad


#
# Example yadifa configuration file.
#

<main>
# Detach from the console
daemon on

# Jail the application
chroot off

# The path where all the log files will be written
logpath "/usr/local/var/log"

# The path where the pid file will be written
pidpath "/usr/local/var/run"

# The path where all zone files will be written
datapath "/usr/local/var/zones"

# The path where the DNSSEC keys are found
keyspath "/usr/local/var/zones/keys"

# The path where the transfer and journaling files will be written (AXFR &amp; IXFR)
xfrpath "/usr/local/var/zones/xfr"

# The version returned by a query to version.yadifa. CH TXT
version "1.0.0rc2"

# Enable EDNS0 support (?)
edns0 on

# Set the maximum UDP packet size. Cannot be less than 512. Cannot be more than 65535. Typical choice is 4096.
edns0-max-size 4096

# The maximum number of parallel TCP queries.

max-tcp-queries 100

# The user id to use (an integer can be used)
uid root

# The group id to use (an integer can be used)
gid wheel

# The DNS port. Any DNS query will be made using that port unless a specific value is used.
port 53

# The interfaces to listen to.
listen 0.0.0.0

# Enable the collection and logging of statistics
statistics on

# Choose the query log format (0 for none, 1 for YADIFA, 2 for BIND compatible, 3 for YADIFA and BIND)
queries-log-type 1
# Drop queries with erroneous content
# answer-formerr-packets on

# Maximum number of records in an AXFR packet. Set to one for compatibility
# with very old name servers
# axfr-maxrecordbypacket 0

# Global Access Controlrules.
#
# Rules can be defined on network ranges, TSIG signatures, and ACL rules

# simple queries:
allow-query any

# dynamic update of a zone
allow-update none

# transfer of a zone (AXFR or IXFR)
allow-transfer none

# notify of a change in the master
allow-notify none
</main>

#
# Logging output channels configurations
#
# name stream-name arguments
#
# name is arbitrary
# stream-name defines the output type (ie: a file name or syslog)
# arguments is specific to the output type (ie: unix file access rights or syslog options and facilities

<channels>
# name stream-name arguments
database database.log 0644
dnssec dnssec.log 0644
server server.log 0644
statistics statistics.log 0644
system system.log 0644
zone zone.log 0644
queries queries.log 0644
all all.log 0644

syslog syslog USER,CRON,PID

# although possible, these two do not do make much sense if daemon is enabled

stderr STDERR
stdout STDOUT
</channels>

# Logging input configurations
#
# name debug-level channels
#
# name is predefined
# debuglevel uses the same names as syslog or * or all to filter the input
# channels is a comma-separated list of channels

<loggers>
# bundle debuglevel channels
database * database,all
dnssec * dnssec,all
server * server,all
statistics * statistics
system * system,all
zone * zone,all
queries * queries
</loggers>

#
# TSIG Key configuration
#

<key>
name abroad-admin-key
algorithm hmac-md5
secret WorthlessKeyForExample==
</key>

<key>
name master-slave
algorithm hmac-md5
secret MasterAndSlavesTSIGKey==
</key>

#
# Access Control List definitions
#

<acl>
transferer key master-slave
admins 192.0.2.0/24, 2001:db8::74
master 192.0.2.1
slave 192.0.2.2
</acl>

#
# Master domain zone config
#

<zone>
type slave
domain localhost
file slaves/localhost.zone
master 192.0.2.1
</zone>

<zone>
type slave
domain localhost6
file slaves/localhost6.zone
master 192.0.2.1
</zone>

<zone>
type slave
domain 0.0.127.in-addr.arpa
file slaves/0.0.127.in-addr.arpa.zone
master 192.0.2.1
</zone>

<zone>
type slave
domain 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
file slaves/0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.zone
master 192.0.2.1
</zone>

<zone>
# This server is master for that zone (mandatory)
type slave

# The domain name (mandatory)
domain myzone.demo

# The zone file, relative to 'datapath'. (mandatory for a master)
file slaves/myzone.demo.zone
master 192.0.2.1
</zone>

Start the daemon:
/usr/local/sbin/yadifad

Verify that YADIFA is listening:
netstat -anfinet|grep '.53'
tcp4 0 0 *.53 *.* LISTEN
udp4 0 0 *.53 *.*

Now query the slave server for myzone.demo:
dig +norec @localhost -t ANY myzone.demo

; <<>> DiG 9.8.1-P1 <<>> +norec @localhost -t ANY myzone.demo
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62606
;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 3

;; QUESTION SECTION:
;myzone.demo. IN ANY

;; ANSWER SECTION:
myzone.demo. 600 IN SOA ns1.myzone.demo. hostmaster.myzone.demo. 2012041403 86400 7200 604800 86400
myzone.demo. 600 IN NS ns1.myzone.demo.
myzone.demo. 600 IN NS ns2.myzone.demo.

;; ADDITIONAL SECTION:
ns2.myzone.demo. 600 IN A 192.0.2.10
ns2.myzone.demo. 600 IN A 192.0.2.2
ns1.myzone.demo. 600 IN A 192.0.2.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Apr 20 18:27:13 2012
;; MSG SIZE rcvd: 160

What you have now is a fully working testbed for playing with YADIFA. I remind you that this is just a quick guide to get started. You are encouraged to read the background documentation and the manuals as well.

Creative Commons License
How to run master and slave YADIFA on FreeBSD 9.0 by Antonio Prado is licensed under a Creative Commons Attribution-ShareAlike 4.0 International

3 comments

  1. Hi,
    thanks for your feedback and input.

    When I wrote this article YADIFA was at an early stage therefore I didn’t expect to test a production ready software and, actually, I wasn’t interested too much in discovering issues or put any effort into finding workaround to make it properly function from a production perspective.

    According to the roadmap, release 2.0.0 (Q2 2013) will be an interesting one, hopefully.

    Thank you.

Leave a Reply