Professional Documents
Culture Documents
x
Glenn Sidman Updated: April 22, 2005
Note: This HOWTO is way out of date. Though the DNS specific information still applies today, the setup of BIND covered in this HOWTO no longer applies. Beginning with FreeBSD 5.3, BIND9 has replaced BIND8 as the default DNS server and comes installed to run in a chroot environment as user bind. Very briefly: With FreeBSD 5.3 and latter, simply run the "makelocalhost" script from the /etc/namedbd directory. Then enable BIND9 by adding named_enable="YES" to the /etc/rc.conf file. You can then start named with the command: /etc/rc.d/named start. This will give you a caching-only DNS server that listens on the localhost interface. You can now configure "named.conf" to suite your needs, and DNS zone files if applicable. Perhaps someday I will finish the updated HOWTO, but know that this one will always remain posted for archival purposes.
1 - About This HOWTO 2 - Some Theory: How Does A Client Resolve Names? o 2.1 - Caching And Forwarding Name Servers o 2.2 - Master vs. Slave Name Server 3 - Installing BIND o 3.1 - Replacing The Base System's BIND o 3.2 - Using The Default Installation For BIND o 3.3 - Configuring rndc For BIND 9 o 3.4 - Old Tools Vs. New Tools 4 - Configuring BIND o 4.1 - Our foobar.example domain o 4.2 - Overview of zone data files o 4.3 - localhost.rev (Localhost Reverse Lookup Zone) o 4.4 - db.foobar.example (forward Lookup zone) o 4.5 - db.1.168.192 (Reverse Lookup Zone) o 4.6 - named.root (Root Hints File) o 4.7a - named.conf For Master Name Server o 4.7b - named.conf For Caching-Only Name Server o 4.8 - Configuring Forwarding and Forward Only 5 - Starting BIND o 5.1 - BIND 8 Only: Starting And Controlling named o 5.2 - BIND 9 Only: Starting And Controlling named o 5.3 - Testing BIND (Both versions) o 5.4 - Starting BIND (named) At Boot 6 - Securing BIND with chroot 7 - Updating named.root (Root server list) 8 - Troubleshooting and Testing BIND o 8.1 - Troubleshooting Syntax And Other Configuration Errors
8.2 - Testing Forward Name Resolution 8.3 - Testing Reverse Name Resolution 8.4 - Testing External Name Resolution 8.5 - What Interface Is BIND Listening On? 8.6 - What Version of BIND Is Running? 9 - Additional Resources
o o o o o
FreeBSD 4.7 (All versions after 4.5 including 5.0 should work without changes). bind9-9.2.2 and/or bind8-8.4.1 (Be sure to use the latest release.)
2. Check the local machine's host file for the address of www.google.com. o Unix-like: /etc/hosts o 98/ME: C:\Windows\hosts o 2000/XP: C:\WINNT\system32\drivers\etc\hosts
3. Check the primary name server (1st listed DNS server) for the address of www.google.com. o Unix-like: /etc/resolv.conf o Windows: Look for TCP/IP Properties
4. Check the secondary name servers if the primary name server fails to respond. o Unix-like: /etc/resolv.conf o Windows: Look for TCP/IP Properties Steps 3 and 4 are why we are here. By the way, step 4 is very important! If we receive a negative answer from the first name server, "host not found," our client will never check the additional name servers. Why should it, we received an answer. Additional name servers are only queried when the primary name server does not return an answer. Also, if you are using Windows machines, be aware that they can resolve NETBIOS names via broadcasts on the local subnet, or even a WINS server if one is configured. Even Windows 2000/XP without NetBEUI (NETBIOS) installed will use NetBEUI over TCP/IP (enabled by default) if DNS queries fail. This can really fool you. Just as clients, the name servers themselves can also cache DNS data. This is controlled by the TTL (Time to Live) specified in the SOA (Start of Authority) record of a Zone's data. The TTL
could be minutes for hosts that change IP addresses frequently, or several hours (or days) for hosts that rarely change. Keep this in mind when DNS changes are not immediately evident. Now lets assume we are trying to access www.cool-lint.org and neither our client nor the name servers along the path have cached data. Our client machine first contacts it's primary DNS server, provided the name is not cached or listed in a host file. This is known as a recursive query. The name server will do all the work. Our client expects a complete answer, whether it is the IP address of www.cool-lint.org or the bad news that no records exist for www.cool-lint.org. The primary name server receives the query from our client, but does not have information about cool-lint.org. The primary name server, as it does not have "zone data" and is not authoritative for cool-lint.org, will need to start searching from the top of the DNS tree. The top is fittingly known as the "root" domain and is specified by "." (dot). Note that 'www.cool-lint.org' is actually 'www.cool-lint.org.' Notice the dot at the end of org? Go ahead, try adding a dot to the end of www.google.com. Remember that our client made a recursive query to our primary name server expecting the name server to do all the work? Now, our name server does not have it so easy. Our name server must plug away with iterative (non-recursive) queries until it can find an answer. Our name server will first query one of the "root" domain name servers for the addresses of the "org" name servers. Next, our name server will query one of the "org" name server for the addresses of the "coollint.org" name servers. Finally, our name server contacts one of the "cool-lint.org" name servers for the IP address of the "www" node at "cool-lint.org". Our name server has used several iterative queries to answer our client's recursive query for www.cool-lint.org. I hope there was something good there at cool-lint. Our name server will also keep this information around for as long as the TTL will allow. This includes the "org" and the "cool-lint" name server addresses as well as www.cool-lint.org address. There is at least one exception to the above scenario. If our name server had been configured as a "forwarder", it would have simply passed the duties of name resolution off to another name server. When a forwarder does not have an answer, it simply makes a recursive query to another name server on the client's behalf. This can help reduce Internet DNS traffic as the upstream name server (normally an ISP) will maintain a fairly populated cache.
master or slave name servers would. This can be beneficial for preserving bandwidth to remote sites on a slow link. Large environments will often use caching-only name servers to distribute DNS load while forwarding non-cashed queries to a single name server capable of resolving internal and/or external queries. There is one primary disadvantage of caching-only name servers. They cannot be authoritative for any zone. If you need to resolve names on your local network, you will need at least one master name server. If you do not need to resolve DNS names on your local network, but still need to resolve names on the Internet, then a cashing-only name server would make good sense. Forwarding is a feature that can be added to any name server configuration whether it be caching-only, master, or even a slave server. There are two primary reasons we might want to use forwarding. First, you can improve DNS performance by taking advantage of a larger DNS cache on an upstream name server. (Typically your ISP, or even a name server in your DMZ). This assumes that your upstream name server(s) are reliable. Second, you can add a layer of security by controlling whom your internal name servers converse with. This allows for much tighter firewall configurations. A "forward only name server will make recursive queries directly to specified name servers. Whereas iterative (non-recursive) queries, without using forwarding, will plug away at many different name servers. If we allow our internal name server(s) to perform iterative queries, we must also open our firewall to allow anyone and everyone to send answers back to our internal name server(s). With "forward only configured, we can close off all external DNS traffic while allowing only responses from two or three "trusted upstream name servers. There is a catch however, in order to benefit from this added layer of security we must disallow all iterative queries from our internal network. This is known as forwarding-only as apposed to the default behavior of forward first. With "forward only, if our upstream name server(s) go down, we go down. Whereas with "forward first, our internal name server will sigh for a moment and then proceeded on its own with iterative queries until if finds an answer. In other words, we have the more secure option of always forwarding queries to specified name servers. Or, the less secure option of only forwarding queries to said servers if they are responding, otherwise go get the answer ourselves from strangers. The options to configure forwarding are relatively simple and will be covered later in "4.8 Configuring Forwarding and Forward Only. Configuring a caching-only name server is even simpler as we simply omit zone statements from named.conf that would otherwise load local zone databases. The configuration you ultimately chose will depend on the reliability of your upstream name server(s), your firewall configuration and security needs, and whether or not you need a DNS zone for your internal network.
This HOWTO focuses only on setting up a single master name server. However, slave name servers are simple to implement in small to medium size environments. Note that it is possible for a single name server to be both a master for one zone while being a slave for another zone. Do not confuse a master name server with a primary name server. The term "primary name server typically refers to the client's primary name server which is the first name server in the client's list. Additional name servers on the client's list are referred to as secondaries. A primary name server for the client can be either a master name server or a slave name server. Simply put, a primary name server loads its zone data from a zone configuration file while a slave name server contains a read-only copy of the zone data retrieved from its master name server. The slave name server will keep a copy of the zone data in a [zone_name].bak file in the event that it is restarted and cannot immediately contact the master name server to retrieve zone data.
3.1 Replacing The Base System's BIND (which I have not attempted as of yet)
The prefix for the base system's BIND is /usr, and the configuration files are stored in /etc/namedb. This puts the binaries primary in /usr/sbin. When installing form the ports
collection, you should be able to replace the base build with extra options for make: (May also need to add PREFIX=/usr DESTETC=/etc/namedb if the below fails to do the trick.)
# cd /usr/ports/dns/bind98 (previously /usr/ports/net/bind9) # make PORT_REPLACES_BASE_BIND98=yes install
If you are building from the tar, you will need to configure with --prefix=/usr and -sysconfdir=/etc/namedb. Also, if you plan on upgrading your base system, add "NO_BIND= true" to /etc/make.conf to keep 'buildworld' from blowing away your current BIND install.
Obviously, adjust the version to match your package. You can verify installation by issuing pkg_info. Installing via the FreeBSD ports collection: You may want to check out HOWTO: Installing CVSup and the Ports Collection on FreeBSD 4.x. Be sure you have the latest port or that you have updated your ports collection with CVSup. You can issue the following to locate the BIND 9 port. Look for the "Path:". It should be /usr/ports/dns/bind9 (Previously /usr/ports/net/bind9).
make search name=bind9
Installation is quite simple. Change to the 'bind9' (or 'bind84') directory and make install. Running make install will download the source files, compile, and install. Use make clean if you want to delete the source tree when you are done. Note: Some folks use make all install. I have not found "all" necessary and quite honestly do not understand how it effects the ports build.
If you are installing BIND version 8, then you are done and can skip the 'rndc' configuration below. If you are using one of the FreeBSD default c-shells you will need to issue 'rehash' before the BIND installation is recognized. (Newbie Note: Issue 'set | grep shell' (without the quotes) to discover which shell you are using. Result will be something like /bin/csh. csh is our shell.)
rehash
/usr/local/etc/rndc.key (secret key) /usr/local/etc/rndc.conf (config file for rndc) /usr/local/etc/named.conf (named config file that we will cover later.)
BIND 9.2.2 includes 'rndc-confgen' to create the rndc secret key. With previous versions of BIND 9 it was necessary to generate the key with 'mmencode' or 'dnssec-keygen'. Lets proceed with creating the default key for BIND 9.2.2: (Check the rndc-confgen man page if you would like to change any of the defaults--man rndc-confgen.)
rndc-confgen a
You will now find 'rndc.key' in /usr/local/etc. Note: if rndc-confgen is not recognized, run 'rehash' and try again. Now lets look at /usr/local/etc/rndc.key:
more /usr/local/etc/rndc.key key "rndc-key" { algorithm hmac-md5; secret "Sk1vCuEoa193gfj=your-key-will-vary";
};
The "key" statement defines our key name which defaults to "rndc-key". The only algorithm support at this time is "hmac-md5". Our randomly generated "secret" is "Sk1vCuEoa193gfjFQoZshw==". That was simple. Now lets configure rndc.conf. You should already have either a rndc.conf or a rndc.conf.sample file in /usr/local/etc. We will not use either one, though you may want to look at the sample file. If you have rndc.conf just move it to rndc.conf.old (mv rndc.conf rndc.conf.old). The below method will allow us to create rndc.conf without having to type out the secret string.
cd /usr/local/etc cp rndc.key rndc.conf ee rndc.conf (Use the text
Now we just need to add the "options" statement to our new rndc.conf file. The "key" statement is already there. The sample file contains an "options" statement as well as a "server localhost" default key. We will not need the "server localhost" default key, but you may use it if you wish. It's intended for use when connecting to other BIND servers. Below is the basic rndc.conf file we will be creating. Yours should match assuming your key name is "rndc-key".
options { default-server localhost; default-key "rndc-key"; }; key "rndc-key" { algorithm hmac-md5; secret "Sk1vCuEoa193gfj=your-key-will-vary"; };
WATCH OUT: If you are not running IPv6 (Most of us still only use IPv4) and your /etc/hosts file has an IPv6 entry for localhost such as: "::1 localhost", then rndc will fail with "connection refused" when you use "default-server localhost;" in the rndc.conf file. This is because rndc will attempt to connect to IPv6 and will never try your real IPv4 address of 127.0.0.1. Either remove the line starting with "::1" from your /etc/hosts file, or change "default-server localhost;" to "default-server 127.0.0.1;" in rndc.conf. . Lastly, we need to configure named.conf--the named configuration file--though this might be a little difficult as you may not have one yet. Not to worry, I will explain how to modify named.conf here, and then include the needed statements later when we setup the real named.conf. First, we need a "controls" statement:
The "inet 127.0.0.1" tells named to only listen on the 127.0.0.1 interface and default port (TCP 953). The "allow { localhost; }" tells named to only accept connections from the local machine. The "rndc-key" must match your key name in the "key" statement. Second, we need to add a "key" statement. By default named.conf is often world readable which is no big deal until we insert our secret key. Rather than trust ourselves to change permissions on named.conf, we will use an include statement to add the "key" statement. The beauty of this lies in the fact that our secret key, rndc.key, just happens to have the exact "key" statement we need to include in named.conf. So assuming your secret key is the default /usr/local/etc/rndc.key, we just need to include that path in named.conf:
include "/usr/local/etc/rndc.key";
Now we just need to ensure rndc.key, and rndc.conf are owned by root and only readable by root. (If you are running BIND under a different user, then that user should also have read access. This is covered later when we chroot BIND.) (Check the FreeBSD handbook if you are not familiar with setting permissions and/or changing owner/group.)
cd /usr/local/etc chmod 600 rndc.conf chmod 600 rndc.key
Here we see that rndc.conf and rndc.key are readable and writeable only by the owner who happens to be root.
system's tools are typically found earlier in the path variable. If you specify 'dig' without specifying the full path, you will be using the old version. For example: The old version of 'dig' is located in /usr/bin, while the new version is located in /usr/local/bin. A typical path variable is shown below:
% set | grep path path (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ......)
Below are the locations of BIND's two most popular tools: /usr/sbin/nslookup (location of old 'nslookup') /usr/local/sbin/nslookup (location of new 'nslooklup') [This has moved to /usr/local/bin/nslookup] /usr/bin/dig (location of old 'dig') /usr/local/bin/dig (location of new 'dig') There are several solutions. For one, just specify the full path every time you use the tool, or change the order of your path variable. If you are daring simply delete the old versions. Below, I will simply move the old tools to [name]-8.3.
cd /usr/sbin mv nslookup nslookup-8.3 cd /usr/bin mv dig dig-8.3
Incidentally, the new version of 'nslooklup' will warn you that: "nslookup is deprecated and may be removed from future releases. Consider using the `dig' or `host' programs instead." Though 'dig' is more powerful, I will use 'nslookup' for this HOWTO as its output is simpler. Also, if you just ran 'nslookup', type "exit" to get out of interactive mode. We will cover 'nslookup' in greater detail later.
Some confusion may arise in distinguishing between the BIND configuration file and the DNS zone database files. Try to remember that named.conf is the configuration file for 'named' which is the BIND daemon. The named.conf file uses a structure specific to BIND while the zone database files are RFC compliant and can often be used on other flavors of name servers. Below is a list of files we will configure. Master Name Server: named.conf (Main configuration file for BIND's 'named' daemon) named.root (List of Internet root servers. AKA: db.cache or root.hints) localhost.rev (Localhost reverse lookup zone for 127.0.0.1) db.foobar.example (Forward lookup zone. This example name of "db.foobar.example" is explained below.) db.1.168.192 (Reverse lookup zone. AKA: in-addr.arpa. This example name is explained below.) Caching-Only Name Server: named.root (List of Internet root servers. AKA: db.cache or root.hints) named.conf (Main configuration file for BIND's 'named' daemon) localhost.rev (Localhost reverse lookup zone for 127.0.0.1)
default location after installing a new version of BIND (without replacing the base system's BIND) will be /usr/local/etc. /etc/namedb (the assumed location of zone files for this HOWTO.) /etc/namedb/named.conf (default location for the base system BIND.) /usr/local/etc/named.conf (default location after installing BIND.)
Reverse lookup zones are commonly named after the address for which they hold authoritative data. To stay hip with the reverse lookup theme, a zone for 192.168.1/24 is normally named in reverse: db.1.168.192 or 1.168.192.in-addr.arpa. (I suspect that in-addr.arpa stands for inverse address ARPA as DNS originated in the ARPAnet days, though I have yet to verified this.) The reverse lookup (in-addr.arpa) zones are an odd thing but required by certain applications, such as nslookup and mail, along with some authentication mechanisms. In other words, some things will not work if you do not configure you in-addr.arpa zones. Reverse lookups are beyond the
scope of this HOWTO. At this time, you just need to know that your in-addr.arpa zones map addresses to names. A reverse lookup zone contains the following resource records: SOA (Start of Authority record) Provides information about this zone. NS (Name Server record) You guessed it. This is the address to name mapping for your name server(s). PTR (address to name 'pointer record') Address to name mappings: Each address or interface on your network should have one of these.
That is it for localhost.rev! If you would like, you can view it with the following:
more localhost.rev
Your output will be similar, but not necessarily identical to the below:
; From: @(#)localhost.rev 5.1 (Berkeley) 6/30/90 ; $FreeBSD: src/etc/namedb/PROTO.localhost.rev,v 1.6 2000/01/10 15:31:40 peter Exp $ ; ; This file is automatically edited by the `make-localhost' script in ; the /etc/namedb directory. ; $TTL @ 3600 IN SOA ns1.foobar.example. root.foobar.example. 1 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum ns1.foobar.example. (
IN
NS
IN
PTR
localhost.ns1.foobar.example.
You can delete the comments if you choose. Delete the PTR record and update the NS and A records as shown below. The CNAME records are optional and shown only for examples. Remember to use names appropriate for your domain.
$TTL @
3600 IN SOA ns1.foobar.example. root.foobar.example. 1 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum ns1.foobar.example. A A A CNAME CNAME 192.168.1.100 192.168.1.200 192.168.1.1 host1 host2 (
IN
NS
As of this may seem a bit cryptic if you are new to DNS so I will try to briefly explain. But first, there are some things you should know about DNS zone file syntax:
A semicolon designates a one-line comment much like REM for DOS, or # for many other Unix configuration files. The "@" is a shortcut character specifying the current domain or origin. You could replace this with foobar.example. (with the trailing dot) and it would have the same effect. The "." (dot) at the end of a name designates the name as being fully qualified. Any name without a dot will have the origin "@" appended. For example, BIND would read foobar.example (without the dot) as foobar.example.foobar.example. Not the desired effect. The name, host1, without the dot would be host1.foobar.example. A desirable effect. However, include the dot on host1 and you have just indicated that host1 is a toplevel domain completely separate form foobar.example.
$TTL 3600
- This control statement specifies the maximum time a name server can cache records from this zone. Ours is set for 3600 seconds or 1 hour. We could also write this as "1h". You can set your TTL to anything you want. Incidentally, both BIND 8 and 9 understand the TTL, however, BIND 9 requires it. Specifies the Internet Record class. There are other classes, but you will likely never need them.
IN
Start of Authority record for @ (foobar.example.). This is the authoritative record for foobar.example. indicating that this is the end of the line for queries. If the answer is not here; it does not exist.
SOA ns1.foobar.example.
included. Email address indicating the responsible person of this zone. Again, include the trailing dot. The dot between root and foo is translated to "@", thus root@foobar.example. Inserting the actual "@" symbol here would likely have some ill effects.
root.foobar.example. ( )
- The opening and closing parentheses allow a line to be extended until the closing parentheses are encountered. Thus the next five values are actually all on the same line as the SOA record and are part of the SOA record. BIND 9 requires that the opening parenthesis is on the same line as SOA.
serial, refresh, retry, expire, minimum
- These values effect how this zone should be cached and/or handled by slave name servers. We really don't need to change these for our simple name server and they would take a while to explain. If you are employing slave servers, you will need to update the serial number before they will pull down new zone data. We have simply set ours at "1" though the common format is yyyymmdd## where "#" represents daily zone updates.
NS
Hosts in our zone. Notice that host1 and host2 do not have dots appended to their names. We could have written these as host1.foobar.example. and host2.foobar.example. if we appended the dots.
A CNAME
This is an alias for h1 to host1. We would see the same address if we pinged both h1 and
host1.
You can delete the comments if you choose. Add the appropriate PTR records for your domain. Our example domain looks like the following:
$TTL @
3600 IN SOA ns1.foobar.example. root.foobar.example. 20021111 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum ns1.foobar.example. host1.foobar.example. host2.foobar.example. ns1.foobar.example. (
IN
NS
Our origin is '1.168.192.in-addr.arpa' thus we only need to list the host portion of host1 and host2's addresses. Alternatively, we could have listed them as '100.1.168.192.in-addr.arpa.' and '200.1.168.192.in-addr.arpa.' respectively (with the trailing dots). We could have also included "@" at the beginning of our NS record, however, the "@" is implied and not needed. Again, do not forget the trailing dots.
The named.root file contains the list of DNS servers for the root domain. Both caching-only and master name servers will need this. You will be glad to know that you need not create, or even edit, a named.root file. One will be included in your /etc/namedb directory. You may want to take a look at it. You can get an updated named.root file from ftp.rs.internic.net, however, the recommended approach is to use 'dig'. Dig is simple and explained in "Updating named.root". Don't try it now though, as our server must be running before we can use dig. As with other zones, named.root can be named anything you choose so long as it matches your entry in named.conf. In fact, named.root is most commonly known as db.cache or root.hints, however, I will stick with the default name of named.root for this tutorial.
# /etc/namedb/named.conf - for base system's BIND 8 or 9 # /usr/local/etc/named.conf - for default install of BIND 8 or 9 options { directory "/etc/namedb"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; };
/* Remove comments and this sentence for BIND 9 controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; include "/usr/local/etc/rndc.key";
*/ zone "." { type hint; file "named.root"; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "localhost.rev"; }; zone "foobar.example" { type master; file "db.foobar.example"; allow-transfer { none; }; }; zone "1.168.192.in-addr.arpa" { type master; file "db.1.168.192"; allow-transfer { none; }; };
Remember that there are two thing we need to do with named.confset our options and load zones. Lets look at the options statement first:
options { directory "/etc/namedb"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; };
First thing we do is to declare the options statement. It is very important to remember the opening and closing brackets, and to end the options statement with a semicolon.
options { ...Control statements go here. We can list each one on a new line for clarity.. };
The following are our option control statements. Remember to end each control statement with a semicolon.
directory "path_to_named_directory";
(BIND will change to this directory, thus we do not need to include the full path when we call our zone files. We will be using /etc/namedb for our zone files no matter which BIND version or install method we used.)
allow-query { list_of_networks_or_specific_addresses };
(This determines which networks or addressed BIND is allowed to answer queries for. You can disregard this if you only have one network card, or intend to allow external users to lookup names on your network. Our example uses a duel homed machine. For that reason, we will only allow BIND to answer queries from our internal network (192.168.1/24) and from the loopback interface (27.0.0.1). Note that our network is written as 192.168.1/24 rather than 192.168.1.0/24.)
listen-on { list_of_interfaces };
(Again, we only want BIND to answer queries for our internal network and our loopback. This tells BIND to not even bother listening on our external interface.) NOTE: By default, BIND 4.9 and later will provide it's version information to anyone who asks. (dig txt chaos version.bind). You can tell BIND to return a text string in place of the version record. This helps keep the bad guys, and worms, guessing a bit should they have access to query your name server. Adding the below option would cause BIND to return the text string "unavailable":
version "unavailable";
BIND 9 Only: You will need to remove the comments ( /* and */ ) for BIND 9. Remember from earlier that the "controls" statement and "include" are used to configure BIND 9's rndc. Be sure that "include" contains the correct path to your rndc.key file.
controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; include "/usr/local/etc/rndc.key";
Next, we need to load our four zones. This should be fairly self-explanatory after looking over the named.conf file a few times. It goes as follows:
zone "origin_of_zone" { zone control statements.};
The first zone we load is "." (the root zone.) This is our list of Internet root name servers in named.root. This zone type is 'hint' and the file containing the hints is named.root. BIND will look in the directory specified earlier by the 'directory' option.
zone "." { type hint; file "named.root"; };
The next zone we load is our localhost or loopback zone. Its origin is '0.0.127.IN-ADDR.ARPA', the zone type is master, and the zone information is in the localhost.rev file we created earlier with the make-localhost script.
Moving on, we now load the foobar.example zone file. The only new control statement here is 'allow-transfer'. If we had slave name servers, we would list them here. As we have no salve servers we will allow transfers to 'none'. (NOTE: Change 'none;' to your local subnet or specific addresses if you need to list records with nslookup.)
zone "foobar.example" { type master; file "db.foobar.example"; allow-transfer { none; }; };
By this time things should seem very redundant. The last zone we load is our network's reverse lookup zone.
zone "1.168.192.in-addr.arpa" { type master; file "db.1.168.192"; allow-transfer { none; }; };
There are many more control statements available (especially for BIND 9), but we will not need them. You may, however, need to add the following to your 'options' section if you are going through a firewall:
query-source address [your_address] port [your_port];
The following would send queries out any interface via port 53:
query-source address * port 53;
By default BIND 8 and BIND 9 will send queries to other name servers from an unprivileged port (ports 1024 and above). The query will come from our port [1024+] to port 53 on the external name server. The response from that name server will come back to our port [1024+]. If you never receive answers from the root name servers, investigate 'query-source'. The sample named.conf suggests setting this to port 53. You will need to work with your "firewall engineer" to determine your best approach. Now that we know what named.conf does, how do we create it? BIND does come with an /etc/namedb/named.conf file, however, I find it easer to just create a new one and keep a copy of the original around for reference.
cd cd mv ee
/etc/namedb (default location for the base system BIND.) /usr/local/etc (default location after installing BIND.) named.conf named.conf.ori named.conf (start typing)
Alternatively you can edit the original. It is up to you. The most common mistake is to have one too few or too many semicolons or braces. Thankfully BIND will help you find syntax errors the first time you start it up.
# /etc/namedb/named.conf - for base system's BIND 8 or 9 # /usr/local/etc/named.conf - for default install of BIND 8 or 9 options { directory "/etc/namedb"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; };
/* Remove comments and this sentence for BIND 9 controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; include "/usr/local/etc/rndc.key";
*/ zone "." { type hint; file "named.root"; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "localhost.rev"; };
Remember that there are two thing we need to do with named.confset our options and load zones. Lets look at the options statement first:
options { directory "/etc/namedb"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; };
First thing we do is to declare the options statement. It is very important to remember the opening and closing brackets, and to end the options statement with a semicolon.
options { ...Control statements go here. We can list each one on a new line for clarity.. };
The following are our option control statements. Remember to end each control statement with a semicolon.
directory "path_to_named_directory";
(BIND will change to this directory, thus we do not need to include the full path when we call our zone files. We will be using /etc/namedb for our zone files no matter which BIND version or install method we used.)
allow-query { list_of_networks_or_specific_addresses };
(This determines which networks or addressed BIND is allowed to answer queries for. You can disregard this if you only have one network card, or intend to allow external users to lookup names on your network. Our example uses a duel homed machine. For that reason, we will only allow BIND to answer queries from our internal network (192.168.1/24) and from the loopback interface (27.0.0.1). Note that our network is written as 192.168.1/24 rather than 192.168.1.0/24.)
listen-on { list_of_interfaces };
(Again, we only want BIND to answer queries for our internal network and our loopback. This tells BIND to not even bother listening on our external interface.)
NOTE: By default, BIND 4.9 and later will provide it's version information to anyone who asks. (dig txt chaos version.bind). You can tell BIND to return a text string in place of the version record. This helps keep the bad guys, and worms, guessing a bit should they have access to query your name server. Adding the below option would cause BIND to return the text string "unavailable":
version "unavailable";
BIND 9 Only: You will need to remove the comments ( /* and */ ) for BIND 9. Remember from earlier that the "controls" statement and "include" are used to configure BIND 9's rndc. Be sure that "include" contains the correct path to your rndc.key file.
controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; include "/usr/local/etc/rndc.key";
Next, we need to load our four zones. This should be fairly self-explanatory after looking over the named.conf file a few times. It goes as follows:
zone "origin_of_zone" { zone control statements.};
The first zone we load is "." (the root zone.) This is our list of Internet root name servers in named.root. This zone type is 'hint' and the file containing the hints is named.root. BIND will look in the directory specified earlier by the 'directory' option.
zone "." { type hint; file "named.root"; };
The next zone we load is our localhost or loopback zone. Its origin is '0.0.127.IN-ADDR.ARPA', the zone type is master, and the zone information is in the localhost.rev file we created earlier with the make-localhost script.
zone "0.0.127.IN-ADDR.ARPA" { type master; file "localhost.rev"; };
That is it for a caching-only name server. If we were building a master name server, we would include additional zones for each domain our server would be authoritative for.
There are many more control statements available (especially for BIND 9), but we will not need them. You may, however, need to add the following to your 'options' section if you are going through a firewall:
query-source address [your_address] port [your_port];
The following would send queries out any interface via port 53:
query-source address * port 53;
By default BIND 8 and BIND 9 will send queries to other name servers from an unprivileged port (ports 1024 and above). The query will come from our port [1024+] to port 53 on the external name server. The response from that name server will come back to our port [1024+]. If you never receive answers from the root name servers, investigate 'query-source'. The sample named.conf suggests setting this to port 53. You will need to work with your "firewall engineer" to determine your best approach. Now that we know what named.conf does, how do we create it? BIND does come with an /etc/namedb/named.conf file, however, I find it easer to just create a new one and keep a copy of the original around for reference.
You might be wondering what will happen when you attempt to resolve local host names? Well, those queries will also be sent to your upstream name servers which most likely do not have
information about your local network and will fail. To prevent local name queries from being forwarded, simply add a null forwarders statement to each zone that you do not want to forward.
zone "foobar.example" { type master; file "db.foobar.example"; allow-transfer { none; }; forwarders { }; }; zone "1.168.192.in-addr.arpa" { type master; file "db.1.168.192"; allow-transfer { none; }; forwarders { }; };
The above "forward first examples will tell BIND to: First forward queries to upstream name servers. Second, in the event that none of the upstream name servers respond, then revert to iterative (non-recursive) queries. If you prefer that BIND only use forwarding, then simply add "forward only; to your list of options statements.
options { directory "/etc/namedb"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; forwarders { 10.1.2.3; 172.16.1.2; }; forward only; };
In reality, your firewall will determine whether or not BIND is free to partake in iterative queries with other name servers. However, using "forward only will eliminate unnecessary traffic, excessive timeouts, and is just more professional.
Replace your current 'nameserver' with 127.0.0.1. If you want to add additional name servers, add them to the list below 127.0.0.1. Our ns1.foobar.example resolv.conf looks like this:
The domain part is the "search domain" which allows you to lookup 'ns1' rather than using the fully qualified name of 'ns1.foobar.example'. (NOTE: Alternately you can use 'search' in place of 'domain'. Just don't use them both.)
BIND (specifically 'named') will immediately inform you of any syntax errors in your config files. Check out the "Troubleshooting and Testing BIND" section if you are having issues. If all is well we can move on to using 'ndc'. Happily 'ndc' does not require any configuration unlike 'rndc' of BIND 9. You can check the status of BIND 8 with "ndc status". You can use "ndc reload" to reload you zone files. You will need to do this anytime you make a change such as adding or removing a host address. You can use "ndc restart" to restart named. This will be required before any changes to named.conf will be effective. You can also stop named with "ndc stop". (As "ndc restart" sends a signal directly to the running 'named' process, it will always restart the correct 'named' version unlike "ndc start".) By the way, if you find yourself stuck in an interactive session with 'ndc', simply type "/h" for help or "/e" to exit.
First we will need to start 'named' which is the BIND daemon. We use 'rndc', the remote name daemon control program, to control BIND 9 much as we use 'ndc' to control BIND 8. Some configuration of 'rndc' is necessary before it will work. This was covered earlier in "Configuring rndc For BIND 9". Note that we can NOT use 'rndc' to start BIND 9 as 'rndc' requires BIND 9 to be running. Unfortunately the error is a bit misleading: "rndc: connect failed: connection refused". Remember that the base system's BIND will use /usr/sbin/named. Use this only if you have replaced your base system's BIND. Otherwise you will be starting BIND 8.3.x. Start BIND 9 with one of the following unless you have installed with something other than the default prefix:
/usr/sbin/named (default location for the base system BIND.) /usr/local/sbin/named (default location after installing BIND.)
If everything started correctly you will be quietly returned to the command prompt. If not, BIND (specifically 'named') is usually quite verbose in telling you where you went wrong. Check out the "Troubleshooting and Testing BIND" section if you are having issues. If you are familiar with BIND 8's 'ndc' you will find that BIND 9's 'rndc' uses options a little differently. For one, you cannot start 'named' with 'rndc'. For another, restart" is not yet implemented in 'rndc.' The good news is that "ndc reload" not only reloads zones but also forces 'named' to reread named.conf. You can check the status of BIND 9 with "rndc status", and you can clear the cache with "rndc flush". You can use "rndc reload" to reload you zone files and force 'named' to reread is configuration file--named.conf. You will need to do this anytime you make a change to a zone file or named.conf. You can also use "rndc reconfig" to reread named.conf and only load zones which have changed. Remember, you cannot use 'rndc' to start BIND 9, however you can stop it with "rndc stop".
Address:
127.0.0.1
Hey, look at that. Our server resolved its own address. Notice that "Server" and its corresponding address is the name server we connected to for name resolution. "Name" and its corresponding address is the answer to our query. You can also try this for any other hosts entries you may have added. If this did not work, try using your servers fully qualified name, ie: 'ns1.foobar.example'. If the fully qualified name works, then you may want to set your 'domain' in /etc/resolv.conf. Lets see if we can resolve and external name:
% nslookup www.google.com Server: localhost.foobar.example Address: 127.0.0.1 Name: www.google.com Address: 216.239.39.99
If this failed with a "Non-existent domain" error, check out the "Troubleshooting and Testing BIND" section. This means that you are not able to contact the domain root serversor google has vanished. Now lets check our reverse lookup zone. You will need to use the IP address of one of your hosts.
% nslookup 192.168.1.100 (This is our 'host1' address. Use one of your real addresses here.) Server: localhost.foobar.example Address: 127.0.0.1 Name: host1.foobar.example Address: 192.168.1.100
Worked? Good! Otherwise check out the "Troubleshooting and Testing BIND" section. Your inaddr.arpa zone is not loading or does not have correct data. One last thing. You should also check which version of BIND you are actually running. This is covered in more detail in "Troubleshooting and Testing BIND", however, the following will give you the version when run from a console on your name server. (Don't use "named v" as this will not necessarily give you the version of BIND that is actually running.)
%dig txt chaos version.bind @localhost
Default installation of BIND: If you have installed a newer version of BIND and did not replace the base system's BIND, you will need to add the path to named and add named_enable="YES" to /etc/rc.conf. (Note: I do not recommend editing /etc/defaults/rc.conf)
cd /etc cp rc.conf rc.conf.ori (always backup the original.) ee rc.conf Add named_enable="YES" anywhere in rc.conf provided it is not already there. Add named_program="/usr/local/sbin/named" anywhere in rc.conf
That is it. If needed, you can now configure your clients to use your new name server as their primary DNS server. You can also use 'nslookup' from a command prompt on Windows NT/2000/XP hosts. Whenever you make a change to one of your zone files, remember to issue 'ndc reload' for BIND 8 or 'rndc reload' for BIND 9. Whenever you make a change to named.conf, remember to issue 'ndc restart' for BIND 8 or 'rndc reload' for BIND 9. Be sure to use 'netstat n' if you want to check which interfaces BIND is listening on. More information is available in the "Troubleshooting and Testing BIND" section.
The following will describe how to run BIND as an unprivileged user and use chroot to place BIND in a sandbox where it cannot see our "real" file system. I will focus here on BIND 9 though the majority of this section will apply to BIND 8. There are a couple exceptions for BIND 8 which have been noted. You may also want to reference the FreeBSD hand book, especially if you are working with BIND 8. First we need an unprivileged user account and group to run BIND. It just so happens that FreeBSD already provides us with a user and group both named "bind. Another popular name for the BIND user is "named. If you need or want to create a new user account, be sure that the new user does not have a real logon shell. Now we will need to create the directory structure. I prefer to use /var/chroot/named, though you can build the sandbox anywhere you wish. You can even use /etc/namedb. The "tmp" directory should not be needed, but I create it anyway. I prefer to keep my master and slave zones in separate directories because user 'bind' will need write access to the "slave" directory to create the [domain].bak files, but not the 'master' directory. The user 'bind' will also require write access to var/run to create the pid file, thus we will make 'bind' the owner of these directories only. Remember that the 'bind' user account could be compromised so we want to restrict it's access as much as possible. Warning: Remember that you are working in a mock root directory of 'named'. If you accidentally append '/' to var or another directory when you really meant /var/chroot/named/var then you have just modified your real var directory.
mkdir -p /var/chroot/named chgrp bind /var/chroot/named cd /var/chroot/named mkdir -p etc dev tmp var/run master slave chmod 750 * chown bind:bind slave var/run
Now we need to create some device nodes. As long as you have already generated the rndc.key, you probably don't need the 'random' node, but we will create it anyway. Also, some versions of BIND 9 may require the 'zero' node, so will create it. You must have the 'null' device node otherwise 'bind' will not be able to take out the garbage. User 'bind' will need write access, so we will make 'bind' the owner and group as well. Again, be absolutely sure you are in the correct directory.
cd dev mknod null c 2 2 mknod zero c 2 12 mknod random c 2 3 chown bind:bind *
Now lets copy over the needed system file(s). For BIND 9 we just need localtime for logging. If you are having issues with syslog, you may need to copy syslog.conf to your etc directory. (If you are using BIND 8 and performing zone transfers, you will need to deal with building a statically linked copy of named-xfer and copying it over as well.)
cp /etc/localtime /var/chroot/named/etc
Now lets copy over the BIND configuration file, rndc.key, and zone files. I will assume your zone files are in the default location of /etc/namedb and that you performed a default installation on BIND 9 which placed your named.conf file in /usr/local/etc. You can copy the entire /etc/namedb directory over with cp -R /etc/namedb /var/chmod/named, however, I will demonstrate by copying each required file separately. I am using our earlier 'foobar.example' zone files. (HINT: If your zone files begin with "db", you can save some typing with: cp db* /var/chroot/named/master)
cd /etc/namedb cp db.1.168.192 /var/chroot/named/master cp db.foobar.example /var/chroot/named/master cp localhost.rev /var/chroot/named/master cp named.root /var/chroot/named/master chmod 640 /var/chroot/named/master/* cd /usr/local/etc cp named.conf /var/chroot/named/etc cp rndc.key /var/chroot/named/etc cd /var/chroot/named/etc chmod 640 named.conf rndc.key
We will need to update our directory paths in named.conf to suit our new environment. Since we will be telling BIND to chroot to /var/chroot/named and run as user 'bind', the user 'bind' will think that /var/chroot/named is the "real" root directory. When you tell user 'bind' to look in "/", 'bind' will actually be looking in /var/chroot/named. An attacker who has taken control of BIND will also be unable to access our "real" root. (Provided he or she is not able to brake out of our chroot environment.) Below is our 'foobar.example' named.conf from earlier. Changes are in bold.
# /etc/namedb/named.conf - for base system's BIND 8 or 9 # /usr/local/etc/named.conf - for default install of BIND 8 or 9 options { directory "/"; allow-query { 192.168.1/24; 127.0.0.1; }; listen-on { 192.168.1.1; 127.0.0.1; }; };
/* Remove comments and this sentence for BIND 9 controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; include "etc/rndc.key"; */
zone "." { type hint; file "master/named.root"; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "master/localhost.rev"; }; zone "foobar.example" { type master; file "master/db.foobar.example"; allow-transfer { none; }; }; zone "1.168.192.in-addr.arpa" { type master; file "master/db.1.168.192"; allow-transfer { none; }; };
Now it is time to make BIND chroot to the new environment. For FreeBSD, the best method is through /etc/rc.conf. You can always refer to /etc/defaults/rc.conf for more information about rc.conf options. Your changes, however, should always be made in /etc/rc.conf rather than the defaults file in /etc/defaults. The first two options were covered earlier and do not change. We simply pass additional parameters to BIND through named_flags. The "-u" indicates which user BIND will change to. Initially, BIND will start as root, bind to the privileged DNS socket, and then change to the specified user. (Note: BIND 9 does not use the "-g" (group) option as did BIND 8. BIND 9 uses the primary group of the specified "-u" user. You would add "-u bind" for BIND 8 only.) The "-t" options tells BIND to chroot to /var/chroot/named. The "-c" options tells BIND where the configuration file is in reference to the chroot environment. (Our configuration file is actually in /var/chroot/named/etc/, however, BIND has already chroot'd to /var/chroot/named and will see this as the root directory.) Our /etc/rc.conf looks like this:
named_enable="YES" named_program="/usr/local/sbin/named" named_flags="-u bind -t /var/chroot/named -c /etc/named.conf"
One last thing. When BIND is chroot'd, it cannot access the system's syslogd socket and thus we will need to create a new socket just for BIND. Once BIND starts, the log socket will be created in /var/chroot/named/dev/ and you should see messages from BIND logged to /var/log/messages. We do this by passing additional parameters to syslogd through /etc/rc.conf. Specifically "-l" (ell) and the path to our new log socket. Since we will be overriding the default syslogd_flags we will need to include "-s" or "-ss". The default for FreeBSD seems to always be "-s" which allows syslogd to listen for remote logging, whereas "-ss" will tell syslogd to not bind to an inet socket. I prefer the "-ss" options as I do not need to listen for remote logging.
syslogd_flags="-ss -l /var/chroot/named/dev/log"
You may want to test BIND prior to rebooting. If so, we just need to restart syslogd and named manually with the following:
killall syslogd /usr/sbin/syslogd -ss -l /var/chroot/named/dev/log rndc stop (or ndc for BIND 8) /usr/local/sbin/named -u bind -t /var/chroot/named -c /etc/named.conf
Hopefully your chroot experience was a good one. If not, most issues are usually related to a path or permissions issues and named will normally tell you exactly where the problem is. Also, you can use "ps -aux" to verify that named is now running under "bind" rather than "root".
;; ADDITIONAL SECTION: A.ROOT-SERVERS.NET. B.ROOT-SERVERS.NET. C.ROOT-SERVERS.NET. D.ROOT-SERVERS.NET. E.ROOT-SERVERS.NET. F.ROOT-SERVERS.NET. G.ROOT-SERVERS.NET. H.ROOT-SERVERS.NET. I.ROOT-SERVERS.NET. J.ROOT-SERVERS.NET. K.ROOT-SERVERS.NET. L.ROOT-SERVERS.NET. M.ROOT-SERVERS.NET. ;; ;; ;; ;;
599366 599366 577232 577232 599366 577232 599366 599366 577232 576552 577232 577232 577232
IN IN IN IN IN IN IN IN IN IN IN IN IN
A A A A A A A A A A A A A
198.41.0.4 128.9.0.107 192.33.4.12 128.8.10.90 192.203.230.10 192.5.5.241 192.112.36.4 128.63.2.53 192.36.148.17 192.58.128.30 193.0.14.129 198.32.64.12 202.12.27.33
Query time: 19 msec SERVER: 127.0.0.1#53(127.0.0.1) WHEN: Wed Oct 1 18:43:16 2003 MSG SIZE rcvd: 436
Notice that the output is conveniently formatted for a named.root file. Remember that semicolons are comments. Now change to the same directory that you store your named.root file. Backup your current named.root file. Then select any one of the Internet root servers from the list and issue the following: (We are using F.ROOT-SERVERS.NET as an example.)
cd /etc/namedb cp named.root named.root.old dig f.root-servers.net > named.root
You will need to restart BIND before the changes become effective. That would be 'ndc restart for BIND 8 and 'rndc reload' for BIND 9.
The 'question' will typically be the name or address of a host, and 'name_server_to_ask' will be the address of the name server you are checking. You can omit the name server address so long as the name server you wish to query is the ONLY name server in your DNS list. Note that you may need to clear the DNS cache on Windows clients for DNS changes to take immediate effect. This should not effect nslookup, but if all else fails, clear the cache or reboot. On Windows 2000/XP use 'ipconfig /flushdns'. Other Windows clients will need to be rebooted. Remember that you must use "ndc reload" for BIND 8 and "rndc reload" for BIND 9 before any zone files changes will be realized. Also, BIND must be restarted with "ndc restart" for BIND 8 and "rndc reload" for BIND 9 before changes to the main configuration file, named.conf, will be effective.
The most common mistake is the misuse of semicolons or braces "{ }" in named.conf. Remember that in named.conf semicolons end control statements and cannot be used as comments. However, semicolons ARE used as comments in zone data files. (This is due to the fact that zone files are RFC compliant while named.conf is specific to BIND). Remember that braces are used to contain control statements. Global control statements go within options { control_statement; }; and zone control statements go within zone "name_of_zone" { control_statement; };. Make sure you have set the directory option correctly in named.conf. The default location of the named directory on a non-jailed FreeBSD BIND is /etc/namedb, NOT /etc/named. When configuring your zone data, remember that any name ending with "." (a dot) signifies an absolute name. For example: host1. (with the dot) will resolve to host1, whereas host1 (without the dot) will have the origin domain appended and resolve to host1.foobar.example. Remember that the "@" symbol is a shortcut for the origin. In our example, using "@" in our zone file is the same as using 'foobar.example'. Never us the "@" symbol for the administrative email address, instead use a dot. The following are examples of some shortcuts:
Long: foobar.example. IN root.ns1.foobar.example. Short: @ IN root.ns1.foobar.example. SOA SOA ns1.foobar.example. ns1.foobar.example.
IN IN
A A
192.168.1.100 192.168.1.100
There are also some shortcuts for our reverse lookup zone:
Long: 1.168.192.in-addr.arpa. IN SOA root.ns1.foobar.example. Short: @ IN SOA root.ns1.foobar.example. Long: 100.1.168.192.in-addr.arpa. IN Short: 100 IN Correct: Incorrect: @ @ IN IN SOA SOA ns1.foobar.example. ns1.foobar.example. PTR PTR host1.foobar.example. host1.foobar.example. root.ns1.foobar.example. root@ns1.foobar.example.
Below is the correct and incorrect way to specify the administrative address:
ns1.foobar.example. ns1.foobar.example.
If this failed with "Non-existent domain" or "NXDOMAIN" then the most obvious problem may be that the hostname you attempted to lookup is not in your forward lookup zone file. If you are sure that your forward zone contains the correct name, you may need to reload the zone or try using your client's fully qualified name, i. e. 'host1.foobar.example'. If the fully qualified name works, then you may want to set your 'domain' in /etc/resolv.conf. Below is an example. Alternatively you will need to use the fully qualified domain name for each lookup.
domain nameserver foobar.example 127.0.0.1
If you receive error "Can't find server name for address 127.0.0.1......" Then your name server is either not running or not listening on 127.0.0.1. Check that named is running with the following: (You will need to run ps as root.)
ps ax | grep named
This should return the process ID and path to named. (Note: sometimes, instead of the path to named "/usr/local/sbin/named", you will receive "grep named". This is not named running but rather the grep command.) If this is ok, check which interface BIND is listening on with 'netstat' as explained below in "Test which interfaces BIND is listening on".
If you are still receiving "Non-existent domain" error, then make sure you have entered the name correctly in your forward lookup zone. Use a trailing dot only when you use the fully qualified domain name for a host. If you make changes to named.conf you will need to issue 'ndc restart' for BIND 8 and 'rndc restart' for BIND 9 before the changes take effect. If you make changes to any of your zone files, you will need to issue 'ndc reload' for BIND 8 and 'rndc restart' for BIND 9 before changes take effect. Now lets try resolving names from a client. We can use nslookup to test our name server from any Unix or Windows NT/2000/XP client connected to your network. For this example we will be using a Windows command prompt from 'host2' to resolve the address of 'host1'. We will append our name server address to the end of nslookup to ensure we are querying the correct name server.
C:\>nslookup host1.foobar.example 192.168.1.1 (replace 192.168.1.1 with the IP of your name server) Server: ns1.foobar.example Address: 192.168.1.1 Name: host1.foobar.example Address: 192.168.1.100
You are in good shape if your results were similar to the above example. If instead you received something similar to "*** Can't find server name for address 192.168.1.1: No response from server (or Time out:)" then your name server is not listening to you. We know it is running because we tested that earlier. First try to ping your name server:
ping 192.168.1.1
If, from a Windows machine, you received "Destination host unreachable" then you most likely have a networking issue on your local machine. If you received "Request timed out" then your name server is either not at the address you thought is was, your link to the server is broken, or your server is not returning ICMP ping requests. In any case you will need to endeavor in some basic network troubleshooting. If on the other hand, you are receiving ping replies from your server then you know your DNS is either broken or blocked. You will need to ensure that a firewall on your server, a router, or even your host is not blocking UDP/TCP ports 53 out from your client and into the server. Also be aware that DNS responses will almost always come back on a port above 1024 (usually UDP). You will also need to ensure that your name server is listening on the correct interface and ports. This is covered in more detail later. Note that you may need to clear the DNS cache on Windows clients for DNS changes to take immediate effect. This should not effect nslookup, but if all else fails, clear the cache or reboot. On Windows 2000/XP use 'ipconfig /flushdns'. Other Windows clients will need to be rebooted.
If this fails, ensure your reverse lookup zone (in-addr.arpa) is configured correctly and loaded from your named.conf file. Ensure your host's name and address have been added correctly. Any other issues are likely to have shown up during our forward name resolution testing earlier.
If you received something such as the following: "*** ns1.foobar.example can't find www.freebsd.org: Non-existent host/domain" ensure that you have a "hints" file listing the Internet root servers and that it is being loading from named.conf. The "hints" file is installed by BIND 8 and BIND 9 as /etc/namedb/named.root. The name of the file does not matter so long as it matches your entry in named.conf. The following section form named.conf would load a hints file named named.root form the directory specified by the directory option in named.conf.
zone "." { type hint; file "named.root"; };
If you are using "forwarders in your named.conf, then make cretin that those name servers (probably your ISP's) are accessible. The quickest was to check is to simply append your IPS's name server (123.123.123.123 for this example) to the end of your 'nslookup' command:
% nslookup www.freebsd.org 123.123.123.123 Server: name-server-at.myisp.net Address: 123.123.123.123 Name: www.freebsd.org Address: 216.136.204.117
Also be aware that a forwarding name server still requires a hints file. If you have included the "forward only; option, you will probably not need a hints file. If you are still having issues, ensure that your queries are not being dropped by a firewall and that you have Internet connectivityDuh.
The output from our ns1.foobar.example name server includes the following:
tcp4 tcp4 udp4 udp4 0 0 0 0 0 0 0 0 127.0.0.1.53 192.168.1.1.53 127.0.0.1.53 192.168.1.1.53 *.* *.* *.* *.* LISTEN LISTEN
Using the first line as an example, the important things to note here is that tcp4 indicates TCP version 4 as apposed to version 6 (most everyone still uses version 4). The "127.0.0.1.53 indicates that local address 127.0.0.1 is listening on TCP port 53. If instead we had and entry such as "*.53 then we would be listening for DNS queries on all interfaces. Notice also that UDP is a connectionless protocol and does not show as "LISTENING for connections like TCP. In case you are wondering, almost all DNS queries use UDP. In some cases, however, TCP will be used if the data is too large for UDP packets such as during complete zone transfers. So, if your server is not listening on the correct interfaces, or is listening on too many interfaces, you will want to look at named.conf. Below are the option statements which effect this behavior:
options {
If all else fails, don't forget about firewalls. Ensure that a firewall on your server, a router, or even your host is not blocking UDP/TCP ports 53 out from your client and in to your server. Also be aware that DNS responses will almost always come back on a port above 1024 (usually UDP). By the way, if you want to be fancy, you can also use 'sockstat' instead of 'netstat'. In the below example "-4 indicates TCP version 4 and we will pipe the output to grep filtering for "named.
sockstat 4 | grep named
Query time: 3 msec SERVER: 127.0.0.1#53(127.0.0.1) WHEN: Wed Oct 1 21:52:30 2003 MSG SIZE rcvd: 48
Also, you can simply pass the "-v" option to 'named' to ask for the version. If, however, you have more than one 'named' on your server, you will need to ask the question carefully. First, lets find the location of the 'named' that is running on our server:
%ps -ax | grep named 74 ?? Ss 0:00.08 /usr/local/sbin/named
Now we know BIND 9.2.2 is running. Just for fun, lets not specify the path to 'named':
%named -v named 8.3.3-REL Wed Oct 9 12:19:59 GMT 2002 root@builder.freebsdmall.com:/usr/obj/usr/src/usr.sbin/named
Oops, looks like the old 'named' is found earlier in our path variable. Luckily it is not the version that is currently running. If you run a tight ship, you will want to get this old version off you machine or at least make it non-executable.