Hacking Linux Exposed

About
Authors
Contents
Reviews
Foreword
Purchase

Articles
Books
Sourcecode
Tools
Errata

Home

 


previous article
index
next article
Wrapping Up DJBDNS
By Bri Hatch.

Summary: This week, Bri wraps up the DJBDNS discussion by explaining how to import your existing BIND zones into tinydns data format and then start up the axfrdns server to let you finally become BIND-free.


At the beginning of this trip down DJBDNS lane, I tagged a challenge at the end of the message. Unlike my previous [1] challenge, this one had almost no response, probably because it was lost in obscurity at the bottom of the email. I'm re-issuing it again this week, and you'll find it at the end of this article.

Welcome to the home stretch, my last [2] ITworld article on installing DJBDNS. I'll cover two things here. First, I'll show you how to 'import' your existing BIND zones into tinydns data format so you don't need to convert those files by hand. Lastly, I'll show you how to start up the axfrdns server, which will allow DNS secondaries running BIND to mirror your DNS zones.

Import Your Existing BIND Zones

First, both of these require another piece of DJB software, ucspi-tcp (Unix Client Server Program Interface). Run the following to install it:

  $  mkdir /tmp/src
  $  cd /tmp/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
  $  make
  #  make setup check

This installs a bunch of different TCP client and server programs in /usr/local/bin, though we'll only be using two of them: tcpserver and tcpclient.

So, let's see how we can snag our existing BIND zone files. I'll assume we want to get the 'example.dom' domain. First, make sure that BIND allows you to perform DNS transfers for our IP address. Assuming you are doing this on the same machine, localhost should be allowed in /etc/named.conf:

  allow-transfer { 127.0.0.1; };

If you don't have an allow-transfer directive, then create one like the one above. Test to verify that you can do a transfer using 'host':

  $  host -l example.dom
  example.dom SOA example.dom. hostmaster.example.dom 10 3600 180 25920 8640
  example.dom name server ns1.example.dom
  example.dom name server ns2.example.dom
  www.example.dom has address 192.168.1.1
  ...

If you don't get a listing, then check your logs and make sure that localhost is allowed to perform a transfer. If all's well, then do the following:

  #  cd /etc/tinydns/root
  #  tcpclient -v 127.0.0.1 53 axfr-get example.dom example.dom.zone tmpfile

This connects to the local BIND server, snags a copy of the zone, and saves in the proper format as example.dom.zone in the local directory. You can do this for all the domains that you support, it's that easy. Once you've got all the zones saved, you can edit them if you want to make them more tinydns-ish, for example deleting the TTLs, converting Z and & lines to .domain lines instead, etc.... However, even if you leave them as is, they'll work exactly as before. All that's left to do is merge these files into the data file:

  #  cat *.zone > data
  #  make
  /usr/local/bin/tinydns-data

That's it. You've just taken all your BIND data and turned it into tinydns data format. Kill off BIND, tell tinydns to listen on the old IP address (192.168.1.1 for example), and restart tinydns:

  #  killall named
  #  echo 192.168.1.1 > /etc/tinydns/env/IP
  #  svc -d /etc/tinydns
  #  svc -u /etc/tinydns

You are BIND free. Isn't that a great feeling! Of course, since we're not using BIND, there are a few BIND-specific niceties we're missing

  • The ability to mirror other BIND servers' data
  • The ability for secondary BIND servers to mirror our data

Start Up axfrdns

The 'official' way to send and receive zone updates for DJBDNS is to simply rsync /etc/tinydns/root/data from one host to another. This is great if you are in control of all your DNS servers, but doesn't work if you rely on third party BIND name servers as well. However, you can use the axfrdns program to allow BIND servers to mirror your domains. axfrdns was installed as part of DJBDNS already, but we still need to configure it. axfrdns only listens on TCP port 53 and, since tinydns only listens on UDP port 53, you can have axfrdns run on the same IP as tinydns. Let's assume that's 192.168.1.1 for this example:

  #  axfrdns-conf axfrdns dnslog /etc/axfrdns /etc/tinydns 192.168.1.1

Those arguments, from left to right, are the user id for axfrdns, userid for logging, the new axfrdns directory, the location of your existing tinydns directory, and the IP to listen on. axfrdns looks at the very same data.cdb file that tinydns uses, so it's always in sync. Let's start up axfrdns with:

  #  cd /etc/axfrdns
  #  make
  tcprules tcp.cdb tcp.tmp < tcp
  #  ln -s /etc/axfrdns /service

In about five seconds axfrdns will be started by svscan. By default, axfrdns will reject any requests for a zone transfer. This is good, because it keeps the bad guys from easily getting a list of all your machines names and IPs. The access restrictions are located in the file /etc/axfrdns/tcp. Let's look at a sample file to illustrate:

  #  allow 10.0.0.1 to get any zone
  10.0.0.1:allow

  # allow 10.0.0.2 to get only these two zones
  10.0.0.2:allow,AXFR="example.dom/some_domain.org"
  
  # deny 10.0.0.3 entirely
  10.0.0.3:deny
  
  # allow all other 10.0.0.x machines to get another_domain.edu
  10.0.0.:allow,AXFR="another_domain.edu"
  
  # deny all others. (Default deny is good.) 
  :deny

There are more ways of specifying hosts than just these. See http://cr.yp.to/ucspi-tcp/tcprules.html for the full man page. But in the simplest case, you create a line for each secondary dns server you have, and list all the domains that it should be allowed to transfer in the AXFR="" section.

So, you now have all the pieces you need to get rid of BIND. Let's do a quick recap:

  • dnscache functions as your recursive DNS resolver, pointed to by /etc/resolv.conf for example.
  • tinydns serves your DNS data.
  • axfrdns allows you to have BIND servers secondary your DNS data.
  • normal tinydns data mirroring is accomplished by rsyncing the data file to the remote servers, ala:
           $  rsync /etc/tinydns/root/data secondary:/etc/tinydns/root 
           $  ssh secondary 'cd /etc/tinydns/root; make' 
    
  • axfr-get can be used to snag data from BIND or axfrdns servers.

In fact, if you don't want to use rsync to get your data to your tinydns secondary DNS servers, you could set up a cron job to simply use axfr-get much as we did at the beginning of this article to snag all the domains:

  #  cd /etc/tinydns/root 
  #  cat *.zone data.local > data 
  #  make 

We're only missing two things with DJBDNS that we don't have with BIND. The first is the 'notify' functionality, which lets a DNS master tell its secondaries to update the zones. However, this isn't necessary if you use rsync to update zones, or if you have frequent enough cron jobs to do the same.[3]

And the second thing we no longer have when we switch to DJBDNS is a horrible security track record. You'll need to get used to not patching your systems every few months. Hopefully, you'll have some other software that is still buggy so those parallel upgrade skills don't go to waste.

The Challenge

One of the members of my local Linux User Group asked for a quick way to delete the first four bytes from a file. This begat a rapid series of emails showing the many, many ways you can do things on Unix systems. Tail, dd, sed, and of course perl all came into play. In the spirit of TMTOWTDI (there's more than one way to do it), I challenge folks on this list to create a file that can strip the first four bytes from the file 'modifyme' in the current working directory. The file may not be an executable, but instead must be one of the following types:

  • A man page /usr/share/man/man1/stripfourbytes.1 viewed with 'man stripfourbytes'.
  • A postscript file, 'stripfourbytes.ps', viewed with ghostview or ghostscript.
  • A LaTeX file stripfourbytes.tex, viewed with 'latex stripfourbytes'
  • A PDF file, stripfourbytes.pdf, viewed with xpdf or acroread, etc....
  • An image file, viewed with any standard Linux image viewer (eeyes, qiv, xv, etc....)
  • Any other non-executable file that you can use to trick a standard Linux program into running arbitrary code. (An attack against grep, for example.)

Some of the above are definitely possible. Others I've heard of folks doing, but have never tried myself. Others I doubt are exploitable at all.

The first or best winner of each category will get a postcard from sunny Seattle from yours truly, and get their name immortalized in a future column. I'll post answer and discussion in two weeks, so get coding!

NOTES

[1] http://www.hackinglinuxexposed.com/articles/20020416.html

[2] Yes, if you were getting bored of this thread, you can resubscribe now.

[3] There are a few programs linked from http://www.tinydns.org that will let you send BIND NOTIFY packets to trigger instant updates from BIND secondary DNS machines.


Bri Hatch is Chief Hacker at Onsight, Inc, and author of Hacking Linux Exposed and Building Linux VPNs. He looks forward to the day when he moves out of his one bedroom apartment to a place where he has a desk and a sturdy tree for his daughter's swing. Until then, he'll just keep typing away on his laptop from the kitchen table, and Reegen will need to be content with the 'Daddy Jungle Gym 2002'. Bri can be reached at bri@hackinglinuxexposed.com


Copyright Bri Hatch, 2002.

This article was first published here in ITworld.com Inc., 118 Turnpike Rd., Southborough, MA 01772  on 13-Aug-2002.

previous article
index
next article