Setting Up Split DNS on FreeBSD 4.1

Our home system (cfcl) has a firewall box which filters packets, provides NAT, maps our external address to internal addresses, etc. Because the firewall cannot reflect local traffic that is addressed to cfcl's external address back to cfcl's internal address, neither cfcl nor the other local machines can use the "official" DNS results.

So, we have set up "split DNS". In our case, this is implemented as two (named(8)) DNS servers, serving different user communities. The firewall box maps external DNS requests to one IP address, the local machines use another. Each community gets the answers it needs, so there is no confusion.

Firewall Box

Our firewall box (a SonicWall 10) is not a terribly sophisticated device. It can filter packets, redirect IP addresses, etc. By and large, this is exactly what we want. In our opinion, general purpose OSes have far too much going on to be secure enough for use as firewalls. In any case, this is why we don't use the standard FreeBSD firewall software...

The SonicWall is configured to redirect most incoming traffic to cfcl's primary LAN address (...193). The sole exception is made for DNS requests, which are redirected to ...199.

/etc/rc.conf

Because we want cfcl to listen on two IP addresses, we added an "alias" setting to the ifconfig(8) definitions in /etc/rc.conf. The first line defines our "internal" IP address. The second line tells cfcl to answer ...199, as well.
   ifconfig_de0="       inet 192.168.168.193 netmask 255.255.255.0"
   ifconfig_de0_alias0="inet 192.168.168.199 netmask 255.255.255.0"
    

/etc/rc.network

Because we want two instances of named(8) to run, we added some code to /etc/rc.network. The first entry sets up our external DNS server; the second sets up our internal DNS server, using its own named.conf file.
   echo -n ' named'
   ${named_program:-named} ${named_flags}

   echo -n ' named(int)'
   ${named_program:-named} ${named_flags} /etc/namedb/int/named.conf
    

/etc/namedb

This directory is primarily used for the "external" instance of our DNS server. It contains:
   int/                 "internal" DNS files (see below)
   localhost.rev        reverse DNS mapping information
   named.conf           top-level DNS configuration
   named.root           information about other servers
   p/                   primary DNS files
   s/                   secondary DNS files
    

/etc/namedb/namedb.conf

Because cfcl now answers two IP addresses, we need to tell this named which one to answer. The code below tells the server to "listen on" the IP address (...199) that the SonicWall uses for our external DNS requests.
   options {
     ...
     listen-on {
       192.168.168.199;      // external DNS server address
     };
   }
    

/etc/namedb/p

The files in this directory provide forward and reverse IP mapping for cfcl's external address.

/etc/namedb/s

This directory is used for secondary DNS information and (possibly) dump files.

/etc/namedb/int

This directory subtree is used for the "internal" instance of our DNS server. It contains:
   localhost.rev      symlink to /etc/namedb/localhost.rev
   named.conf         top-level DNS configuration
   named.root         symlink to /etc/namedb/named.root
   p/                 primary DNS files
   s/                 secondary DNS files (mostly empty)
    

/etc/namedb/int/named.conf

Because this instance of the DNS server is an "add-on", it must make certain accomodations (e.g., in /var/run) to stay out of the way of the "standard" server. The listen-on code below tells this server to monitor both cfcl's standard IP address (...193) and its loopback address (127.0.0.1) for internal DNS requests. The remaining code tells named and ndc to use distinctive file names in /var/run for their "internal" process IDs.
   options {
     ...
     listen-on {
       192.168.168.193;    // internal address for cfcl.com
       127.0.0.1;          // loopback address for cfcl.com
     };

     pid-file  "/var/run/named_int.pid";     // _PATH_PIDFILE
   };

   controls {
     unix "/var/run/ndc_int" perm 0600 owner 0 group 0;
   };
    

/etc/namedb/int/p

The files in this directory provide forward and reverse IP mapping for cfcl's internal address.

/etc/namedb/int/s

This directory is not used for anything except (possibly) dump files.