If you need to setup both a DNS Server and DNS Cache, consider http://www.fefe.de/djbdns/#splithorizon – there are some issues with the points below that need to be resolved (specifically the resolv.conf pointing to the dnscache, without pointing the dnscache at the djbdns).
DNS nameservers serve the purpose of mapping a domain name to an IP address. Typically, an individual machine does not have the DNS information needed to resolve a wide range of domain names, and must rely on lookups to other servers to accomplish this task. As each request takes time, and forces a dependence on other servers, it is often preferable to host your own nameserver for frequently accessed domains.
A typical example of such domains might include those that are hosted by the server. In this case, we are not trying to replace the primary nameserver that ‘the public’ will be using for resolution of our domain names, but rather, trying to avoid making our server lookup DNS information for sites located on the server.
The commonly used caching nameserver is BIND (aka
named), it is well documented, and available in the repositories of most distributions (including the amzn repository). However, it has a significant memory footprint, and is unnecessary for the purposes outlined above. A good replacement is TinyDNS (aka
djbdns). This is package serves as a caching nameserver and dns server, is light-weight, fairly easy to configure, and comprised of several individual components.
The following steps will outline a procedure for installing TinyDNS on Amazon’s Linux distribution (RHEL-like), and show a basic, manual configuration of the data file for single server hosting multiple sites (with public nameservers hosted elsewhere).
The first thing to setup is
daemontools, the software that manages the running of the DNS services:
cd /usr/local/bin wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz tar -xzvf daemontools-0.76.tar.gz mv admin daemontools cd daemontools/daemontools-0.76 sed -i 's/^gcc.*/& -include \/usr\/include\/errno.h/' src/conf-cc ./package/install
The download location is a personal preference, most of the above should be self explanatory, except for the second last line. The second last line appends a path to a header file at the end of the gcc line of
conf-cc; this is needed to address a compilation problem that would otherwise occur.
rm –f /usr/local/src/daemontools-0.76.tar.gz
You cannot delete the command folder that is created by the install script, as the scripts it installs are symlinked to files in that folder.
The next step, very similar to the one above, is to compile and install
cd /usr/local/src wget http://cr.yp.to/djbdns/djbdns-1.05.tar.gz tar -xzvf djbdns-1.05.tar.gz cd djbdns-1.05 sed -i 's/^gcc.*/& -include \/usr\/include\/errno.h/' conf-cc make && make setup check
rm –f /usr/local/src/djbdns-1.05.tar.gz rm –rf /usr/local/src/djbdns-1.05
It is now necessary to setup two system users, and set the IP that tinydns will listen on (usually the external IP).
useradd -d /var/dnscache -s /bin/false tinydns useradd -d /var/dnscache -s /bin/false tinylog /usr/local/bin/tinydns-conf tinydns tinylog /var/dnscache/tinydns YOUR_EXTERNAL_IP
Finally, we are going to setup some entries for TinyDNS. There are scripts located in
/var/dnscache/tinydns/root that can be used, or, for more versatility, the entries can be created manually.
The scripts are:
|Script and Parameters||Records Added|
|add-alias <domain> <ip>||A|
|add-childns <domain> <ip>||NS, A|
|add-host <domain> <ip>||A, PTR|
|add-mx <domain> <ip>||MX, A|
|add-ns<domain> <ip>||SOA, NS, A|
Each of these modifies the contents of the file
data’ file must be compiled into tinydns’ database format using ‘
Finally, we symlink tinydns to the service directory that is being monitored by daemontools.
ln -sf /var/dnscache/tinydns /service
Considerably more flexibility can be leveraged by directly editing the ‘data’ file. It is in a simple format, which each, plain text line corresponding to a specific set of records, denoted by the first character of the line. The rest of the line contains values separated by colons (:).
|.||NS, A, SOA||<domain>:<ip>:<ns_prefix>:<time_to_live>|
Each record may also contain option timestamp and location fields (last two fields) for a line. Further specifics can be found at: http://cr.yp.to/djbdns/tinydns-data.html. Much like with BIND, the use of CNAMEs appears to be frowned upon, and it is preferable to use A records instead.
A reasonable setup might resemble the following (can be repeated for each domain hosted):
.example.com:188.8.131.52::259200 @example.com:184.108.40.206:mail.example.com::86400 +www.example.com:220.127.116.11:86400 +ftp.example.com:18.104.22.168:86400
Do not forget to run ‘
make’ after saving the ‘
You can verify that TinyDNS is running by executing:
ps -ef | grep dns
Which should return at least two processes:
supervise tinydns /usr/local/bin/tinydns
To make the server start using the new DNS server, modify
/etc/resolv.conf, and prepend
nameserver 127.0.0.1. Amazon’s Linux automatically creates this file – for practicality, keep the existing nameserver entry, and put your new nameserver entry above it. Since this file is automatically recreated at startup, you must modify the creation script (
/sbin/dhclient-script) for the setting to persist between reboots.
echo nameserver 127.0.0.1 >> $rscf at line 68, as below:
. . . 65: if [ -n "$RES_OPTIONS" ]; then 66: echo options $RES_OPTIONS >> $rscf 67: fi 68: echo nameserver 127.0.0.1 >> $rscf 69: for nameserver in $new_domain_name_servers; do 70: echo nameserver $nameserver >> $rscf 71: done . . .
To verify that the server is using TinyDNS, try:
In addition to the information being correct, you should notice a line near the bottom that reads:
;; SERVER: 127.0.0.1#53(127.0.0.1)
If you wish to setup the DNS cache, create two users, set the cache to listen on the loopback address (normally you would need to specify addresses allowed to access the cache, but that does not appear to be needed on the local machine), and symlink
dnscacheto the service directory being monitored by
useradd -d /var/dnscache -s /bin/false dnscache useradd -d /var/dnscache -s /bin/false dnslog /usr/local/bin/dnscache-conf dnscache dnslog /var/dnscache/dnscache 127.0.0.1 ln -sf /var/dnscache/dnscache /service/
If you wish to setup ucspi-tcp, the procedure is very similar to those above:
cd /usr/local/src wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz tar -xzvf ucspi-tcp-0.88.tar.gz cd ucspi-tcp-0.88 sed -i 's/^gcc.*/& -include \/usr\/include\/errno.h/' conf-cc make && make setup check
rm –f /usr/local/src/ucspi-tcp-0.88.tar.gz rm –rf /usr/local/src/ucspi-tcp-0.88
Overall, compared to BIND, this seems like an excellent solution. In the first place, the memory usage is negligible, with response time being nearly instant. Furthermore, it eliminates a slight annoyance – the file system loop caused by running BIND chrooted.
A few quick addendums
Since this setup uses DaemonTools, starting, stopping, and monitoring tinydns and dnscache is done through svc and svstat:
/usr/local/bin/svc -u /service/tinydns
/usr/local/bin/svc -d /service/tinydns
/usr/local/bin/svc -h /service/tinydns
/usr/local/bin/svc -p /service/tinydns
/usr/local/bin/svc -c /service/tinydns
All of the above will also work with dnscache.
Some authentication mechanisms (including SSH) typically perform reverse DNS checks, and, will be affected by an incorrectly configured (or corrupt) DNS cache (typically manifesting as very slow logins (SSH, FTP) on an otherwise fast system).