From owner-freebsd-questions@FreeBSD.ORG Wed Jun 28 14:44:10 2006 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7CBA716A9DF for ; Wed, 28 Jun 2006 14:44:10 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from igloo.linux.gr (igloo.linux.gr [62.1.205.36]) by mx1.FreeBSD.org (Postfix) with ESMTP id 96AC443E5C for ; Wed, 28 Jun 2006 14:43:35 +0000 (GMT) (envelope-from keramida@ceid.upatras.gr) Received: from gothmog.pc (host5.bedc.ondsl.gr [62.103.39.229]) (authenticated bits=128) by igloo.linux.gr (8.13.7/8.13.7/Debian-1) with ESMTP id k5SEhED5010611 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 28 Jun 2006 17:43:15 +0300 Received: from gothmog.pc (gothmog [127.0.0.1]) by gothmog.pc (8.13.7/8.13.7) with ESMTP id k5SEh7LP001528; Wed, 28 Jun 2006 17:43:07 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Received: (from giorgos@localhost) by gothmog.pc (8.13.7/8.13.7/Submit) id k5SEh2jM001527; Wed, 28 Jun 2006 17:43:02 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Date: Wed, 28 Jun 2006 17:43:02 +0300 From: Giorgos Keramidas To: Drew Tomlinson Message-ID: <20060628144302.GC1161@gothmog.pc> References: <449C0711.3080803@mykitchentable.net> <20060623155433.GA30666@gothmog.pc> <449C5C69.1030702@mykitchentable.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <449C5C69.1030702@mykitchentable.net> X-Hellug-MailScanner: Found to be clean X-Hellug-MailScanner-SpamCheck: not spam, SpamAssassin (score=-3.398, required 5, autolearn=not spam, ALL_TRUSTED -1.80, AWL 0.83, BAYES_00 -2.60, NORMAL_HTTP_TO_IP 0.17) X-Hellug-MailScanner-From: keramida@ceid.upatras.gr X-Spam-Status: No Cc: freebsd-questions@freebsd.org Subject: Re: Simple DNS For Private LAN X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jun 2006 14:44:10 -0000 On 2006-06-23 14:26, Drew Tomlinson wrote: >> If you use NAT, then I can guide you through setting up a local >> ``master zone'' that is only visible inside your home network, and a >> ``slave zone'' that pulls stuff from ZoneEdit for the >> ``mykitchentable.net'' domain. I already have a similar setup at >> home, to let my internal systems (workstation, laptop) see each other >> with internal names and still use my ISP's name servers for >> everything else. >> >> If you don't use NAT, things are going to be much easier, since you >> only have to set up the names at ZoneEdit and pull the master zone >> from there. > > Thank you for your reply. You're welcome of course :-) > I use NAT for my servers that are visible from the outside so I set > ZoneEdit to return the same address for all servers at > mykitchentable.net which is currently 67.137.238.101. Excellent! This is exactly what I was hoping the setup would be. > Thus www.mykitchentable.net, drew.mykitchentable.net, > mykitchentable.net, and whatever else. all return 67.137.238.101. > Based up this, it seems that I should leave ZoneEdit alone and set up > a local "master zone" visible only to my private LAN as you describe > above. Being a slave and pulling from ZoneEdit wouldn't have any > benefit as the public address won't equal the private address. Quite right. > So assuming I understand correctly, yes, please guide me in setting up > a local master zone. Assuming that your local home network uses addresses in the 192.168.0.0/16 range, you have to set up a local name server which will recognize and reply for the following zones: "drew." # "*.drew" are local home network names 192.168.0.* # reverse IP address -> name for home hosts 127.0.0.* # localhost zone (optional) Optionally, you can set up a 'slave' zone for the `mykitchentable.net' hostnames, but this is not obligatory. To set up the local nameserver for the local zones mentioned above, you will need to modify (or create) at least the following files: /etc/namedb/named.conf /etc/namedb/master/drew /etc/namedb/master/drew.rev /etc/namedb/master/localhost.rev /etc/namedb/master/localhost-v6.rev /etc/rc.conf After you finish setting up all these files, you should be able to: * Resolve hostnames of the form foo.drew to IP addresses of your internal home network. * Resolve IP addresses of your internal home network to hostnames of the form foo.drew. * Resolve `localhost' to your 127.0.0.1 address (and its IPv6 equivalent). * Check your new named setup and see that it works as expected * Troubleshoot your setup, i.e. tweak the logging level of named and find out what it logs through syslog 1. Setting up named.conf ************************ The `named.conf' file is the one BIND reads to find out which `zones' to load (a `zone' is BIND terminology for what you may have heard being called a `domain'). The FreeBSD source tree contains a sample `named.conf' file at `/usr/src/etc/namedb/named.conf', which normally gets installed as `/etc/namedb/named.conf' on your system. This file is not used, until you decide to enable the `named' daemon though. The sample file installed as `/etc/namedb/named.conf' includes several commented parts that you can use as examples for writing your own `named.conf' file. After you have finished writing your own `named.conf' file it should contain: * An `options' section, with global options that apply to the way your `named' service works. * Optionally, a `logging' section, with the configuration options that define what is logged, where it is logged, etc. * A `root' zone entry, which points to the root DNS servers. An up to date list is distributed with the FreeBSD source tree, and can be found at `/usr/src/etc/namedb/named.root'. * Optionally, a `localhost' zone entry (for resolving 127.0.0.1 to a hostname of your choise). * Optionally, a `localhost-v6' zone entry (for resolving the IPv6 equivalent of 127.0.0.1 to a hostname of your choise). * A zone entry for your internal, home network. 1.1. Global `options' for `named.conf' ====================================== The `options' section of your `named.conf' file defines stuff that tunes global parameters of the `named' service. After removing the stuff that is commented out or an example, the `options' section of the default `named.conf' file looks like this: options { directory "/etc/namedb"; pid-file "/var/run/named/pid"; dump-file "/var/dump/named_dump.db"; statistics-file "/var/stats/named.stats"; listen-on { 127.0.0.1; }; }; Most of these defaults should work just fine for a standalone `named' server, but you will have to tweak a bit the `listen-on' option to make it work in an internal, home network. The default list of addresses that your `named' server will listen on includes only 127.0.0.1 and this will make it inaccessible to all the machines of your internal network (i.e. all machines that have an 192.168.0.0/24 address). To let all machines of your internal network query the `named' server running on your FreeBSD system, you have to add the internal IP address of the FreeBSD system to that list too, i.e.: listen-on { 127.0.0.1; 192.168.0.2; }; -------------------------------------------------------------------- IMPORTANT NOTE: Be carerul not to miss the ';' semicolon after the second IP address. If you do, then the bogus `listen-on' option will cause your `named' service to fail starting (but see section 4 below, ``Troubleshooting named problems'', to see how you can track this sort of problem and fix it. -------------------------------------------------------------------- There are various other options that you can set in this section. The most important is probably the `forwarders' list. This can be used to let your `named' process ask upstream DNS servers, like the ones your ISP is probably already using, instead of going all the way to a root NS for resolving host names and IP addresses. This is quite often a good idea, as it allows your local `named' process to take advantage of the cache your ISP's DNS servers already have, speeding up DNS queries a fair bit. A typical `forwarders' section looks a lot like the `listen-on' list you have already seen above, but this time it lists the IP addresses of the remote servers instead of your own: forwarders { 150.140.141.181; 150.140.141.182; }; This would let your `named' service ask the upstream DNS servers at 150.140.141.181 and 150.140.141.182 for hostnames it cannot resolve locally. 1.2. Setting up a `logging' section =================================== See section 4 further down for information about setting up a `logging' section, and how you can read the log messages your `named' service will write. 1.3. A `root zone' entry ======================== A `root zone' is a list of IP addresses for the DNS servers that are called `root name servers'. If you are not using forwaders, your `named' service will have to query these root name servers for information about the toplevel DNS domains (i.e. "com", "net", "edu", "gr", "de", "fr", etc.) An example root zone entry is part of `/usr/src/etc/namedb/named.conf'. You can typically keep this unchanged: zone "." { type hint; file "named.root"; }; This entry points `named' at the file `named.root' at the directory that is defined as the default directory in your `options' section. Since the default directory is set to `/etc/namedb', this entry refers to the file `/etc/namedb/named.root'. Normally, you shouldn't have to edit this entry in `named.conf' or the `named.root' file. Only change these two if you are *VERY* sure about what you are doing. 1.4. The `localhost' and `localhost-v6' local zones =================================================== The default `named.conf' file that is distributed with FreeBSD includes two zone entries that allow client-systems that ask your DNS server to resolve the IP addresses of `localhost' for both IP and IPv6. These addresses are listed in the usual ``reverse-logic'' order that is used for IP address -> hostname zones in `named.conf': zone "0.0.127.IN-ADDR.ARPA" { type master; file "master/localhost.rev"; }; // RFC 3152 zone "1.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" { type master; file "master/localhost-v6.rev"; }; These two zone entries depend on two files in `/etc/namedb/master' to work properly. To make things easier for you, FreeBSD provides a shell script that can auto-generate these files for you, guessing the proper hostname and domain information from the current hostname of the system (as reported by running the hostname(1) utility). All you normally have to do is to keep the entries shown above in your `named.conf' file and then run the `make-localhost' script in `/etc/namedb': # cd /etc/namedb # sh make-localhost Two new files should appear in `/etc/namedb/master' now: # cd /etc/namedb/master # ls -ld localhost* -rw-r--r-- 1 root wheel - 431 Jun 26 07:56 localhost-v6.rev -rw-r--r-- 1 root wheel - 431 Jun 26 07:56 localhost.rev This should be all it takes. You can manually check the contents of these files and make changes to them, but it is probably a good idea to keep them unchanged for now. At least, until you know what the contents of a ``zone file'' look like and what each part means, you should avoid making manual changes to these files. 1.5. Zone entries for your internal, home network ================================================= Now comes the interesting part. You should also add to your `named.conf' file a ``zone entry'' for your internal, home network. This is not so difficult, but there are a few details that you should get right and they are spread across at least three files: * The `named.conf' file, which contains the zone entries for mapping hostnames to addresses and for mapping addresses to hostnames. * A file under `/etc/namedb/master' that contains the actual information for mapping hostnames -> IP addresses. * A file under `/etc/namedb/master' that contains the actual information for mapping IP addresses -> hostnames. 1.5.1. Adding forward and reverse zone entries in `named.conf' -------------------------------------------------------------- The changes that should be done to `named.conf' are related to the following two types of hostname <=> address translations: * hostname of the form `*.drew' => internal home-network address * internal home network address => hostname of the form `*.drew' For these two DNS query types, you will need two zone entries in `named.conf' and two `zone files' in `/etc/namedb/master'. The entries in `named.conf' can be similar to: zone "drew." { type master; file "master/drew"; }; zone "0.168.192.in-addr.arpa." { type master; file "master/drew.rev"; }; The important points to watch out for while writing these entries are: * The zone name is quoted with double-quote characters * The zone entries refer to files of the form "master/foo", where file `foo' maps to `/etc/namedb/master/foo' * There are two zone entries for the same set of systems, one to map hostnames of the form "*.drew" to IP addresses (the "drew." zone entry), and one to map IP addresses in the IP range 192.168.0.* to hostnames (the "0.168.192.in-addr.arpa." zone entry). * The IP range 192.168.0.* is spelled _backwards_ in the zone entry that maps it to a file and it has an "in-addr.arpa." suffix. The two zone entries are commonly referred to as the `forward' and the `reverse' zone: 1. The `forward' zone is the one that maps hostnames to IP addresses. 2. The `reverse' zone is the one that maps addresses of the form "0.0.168.192.in-addr.arpa.", "1.0.168.192.in-addr.arpa.", "2.0.168.192.in-addr.arpa.", "3.0.168.192.in-addr.arpa.", ... "255.0.168.192.in-addr.arpa." to a hostname. You have to manually create the zone files for each one of these zones. It's not too difficult, since you already have at least two sample zone files to read as examples: /etc/namedb/master/localhost.rev /etc/namedb/master/localhost-v6.rev By looking at these two files and reading the next paragraphs, you should be able to create your own zone files too :-) 1.5.2. Creating a forward lookup zone ------------------------------------- A ``forward lookup zone'' is an entry in `named.conf' that points the local nameserver to a hostname -> address map. The smallest zone entry you will typically find in `named.conf' files looks like this: zone "drew." { type master; file "master/drew"; }; After adding this zone entry in your `named.conf' you should also create a file in `/etc/namedb/master' called `drew'. This is the file that will contain the `records' that map hostnames of the form "*.drew" to IP addresses. Semicolon characters `;' can be used to add comments to these files. The semicolon and everything else up to the next newline character are ignored. A small zone file can look like this: $TTL 3600 @ IN SOA bsd.drew. hostmaster.bsd.drew. ( 2006051501 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum IN NS bsd.drew. IN MX 5 bsd.drew. IN MX 10 linux.drew. localhost IN A 127.0.0.1 bsd IN A 192.168.0.1 linux IN A 192.168.0.2 laptop IN A 192.168.0.3 The format of the ``zone files'' is described online too and in the documentation of BIND[1], but I'll try to explain some of the more tricky details. * The ``$TTL'' line sets the default time-to-live for the records that follow. Setting the TTL to 3600 seconds, like above, means that other name-servers that query your own name-server will ask after 3600 seconds for a new copy of the records. * The '@' special record-name refers to the name of this zone, as it was defined in the `named.conf' file. In the case of the `/etc/namedb/master/drew' zone file, this is equal to "drew." -- as this the name of the zone recorded in `named.conf'. * The SOA record is a bit strange. It defines far too many things in one record, but you can read more about each field at [bind9] * The MX records are optional. You only need them if you plan to set up a local mail server that handles all outgoing email for your internal, home network. * Whenever a host name ends in a dot character `.', the currently defined name of the zone is _not_ appended to the host name. Adding the final dot means that you know what you are doing and that you refer to the host by its fully qualified name. * The most interesting records are the 'A' ones. They define host names for systems in the "drew." zone. The full name of the zone is not repeated as part of each line. It is, rather, implied by the defined name of this zone (in `named.conf' as usual). Whenever you make changes to this zone file, make ABSOLUTELY SURE that you also update the `Serial' field in your SOA record. Otherwise, other name-servers will ignore yours and your own name server will not necessarily reload the information of the zone file. 1.5.3. Creating a reverse lookup zone ------------------------------------- A reverse lookup zone is very similar to a forward lookup zone. The most important difference from the standpoint of someone writing the `named.conf' entry for this zone and the one writing the actual `records' in the `/etc/namedb/master/foo.rev' file is that this zone maps IP addresses to hostnames (reverse DNS lookup). Typically, the reverse zones look like this in `named.conf': zone "0.168.192.in-addr.arpa." { type master; file "master/drew.rev"; }; After adding this zone entry in your `named.conf' you should also create a file in `/etc/namedb/master' called `drew.rev'. This is the file that will contain the `records' that map IP addresses like "192.160.0.*" to hostnames. Semicolon characters `;' can be used to add comments to these files. The semicolon and everything else up to the next newline character are ignored. A small zone file can look like this: $TTL 3600 @ IN SOA bsd.drew. hostmaster.bsd.drew. ( 2006051501 ; Serial 3600 ; Refresh 900 ; Retry 3600000 ; Expire 3600 ) ; Minimum IN NS bsd.drew. IN MX 5 bsd.drew. IN MX 10 linux.drew. 1 IN PTR bsd.drew. 2 IN PTR linux.drew. 3 IN PTR laptop.drew. Note that this is *very* similar to the forward zone, except for a tiny detail. It contains `PTR' records instead of `A' (address) records. The `PTR' records map numeric addresses to hostnames with the following easy scheme: * The leftmost column of the `PTR' line is a number from 1 to 254. * This number (let's call it "NUM") is prepended to the `zone name' from `named.conf'. * The address "NUM.0.168.192.in-addr.arpa." resolves to the host name listed after the `PTR' text. For example this line: 1 IN PTR bsd.drew. when it is present in the zone file for `0.168.192.in-addr.arpa.' maps the address `1.0.168.192.in-addr.arpa.' to the hostname `bsd.drew.'. Note the trailing dot in the last-column hostnames, to prevent named from adding the current zone name as a suffix to the hostname. Similarly, you can map 2.0.168.192.in-addr.arpa. to "linux.drew." (as shown above), 3.0.168.192.in-addr.arpa. to "laptop.drew." etc. Just keep in mind, that when you need to add a hostname for the IP address `192.168.0.X', you can strip the trailing `.X' number, reverse the parts of the IP address, append `.in-addr.arpa' and then you end up with: 0.168.192.in-addr.arpa. This is the zone that you have to add a record for `X' and DNS will care care of doing the mapping for lookups from `192.168.0.X' to `X.0.168.192.in-addr.arpa.' for you. 2. Setting up your zone files in /etc/namedb/master *************************************************** If you have read and understood everything so far, then you are ready to set up zone files in your `/etc/namedb/master'. Copy the sample zone files from above, modify them at will and save them under `/etc/namedb/master' using the names configured at the "file" options of the zone entries in `named.conf'. Make sure that you do NOT confuse the `zone name', which is listed right after the `zone' keyword in `named.conf': ==> zone "drew." { and the `zone file name', which is listed as the argument of the `file' option in the zone entry: zone "drew." { type master; ==> file "master/drew"; }; These are two separate things. 3. Enabling named in /etc/rc.conf ********************************* With a fairly recent and up to date `/etc/rc.d/*' collection of startup files, all you have to do to enable the named daemon is to add a simple line in `/etc/rc.conf': named_enable='YES' Then, you can start the `named' daemon by running as `root': kobe# /etc/rc.d/named start If all goes well, you should be able to see the running daemon by using ps(1), pgrep(1) or any other tool you find convenient. The following bash(1) command shows `named' running here: kobe# ps xau | { read head; echo "$head"; grep 'named '; } USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND bind 12168 0.0 0.3 6124 3444 ?? Ss 1:06AM 0:00.05 /usr/sbin/named -t /var/named -u bind kobe# If this didn't work, then read the following stuff about named logging setup and try to find out what `named' writes to syslog. This should help you find out what went wrong. 4. Troubleshooting named problems ********************************* Whenever you have any sort of problem with the `named' daemon, you should first check /var/log/messages for any interesting information, and then you may find it useful to tweak the logging level and output of `named'. The BIND nameserver that is included with FreeBSD supports an extremely customizable logging mechanism. Some may argue that logging is *too* configurable, and thus ends up being confusing, but let's put this aside for now :) Logging is configured by modifying the `named.conf' file, and adding a `logging' section. There are several predefined `categories' of log messages and some predefined `channels' where these messages can be sent to be logged. These are described in the official BIND documentation[*], so I won't repeat them all here. An example of how a `logging' section can be added to `named.conf' is probably much easier to understand than reading through all the BIND documentation for logging tips. Here is what I use for the logging section of the caching named daemon I run at home: logging { category default { default_syslog; default_debug; }; category security { default_syslog; default_debug; }; category xfer-in { default_syslog; default_debug; }; category xfer-out { default_syslog; default_debug; }; category notify { default_syslog; default_debug; }; category update { default_syslog; default_debug; }; category update-security { default_syslog; default_debug; }; category lame-servers { default_syslog; default_debug; }; }; * NOTE: Watch out for missing semicolon `;' characters. Forgetting to add one after the last entry in a { ... } block of named.conf or missing the trailing ';' character _after_ a block is one of the most common bugs in configuration files that fail to load. This can be very annoying, especially if you have to spend several hours before you notice that there is just a tiny missing character that you can add to fix everything! To use this logging section, you can simply copy it into your existing `named.conf' file, right after the global `options' section and then restart `named': kobe# /etc/rc.d/named restart Stopping named. Starting named. If all has gone well, and you have no syntax errors in the logging section you just added, something like the following should appear in your `/var/log/messages' file: kobe# tail -3f /var/log/messages Jun 24 00:06:34 kobe named[12168]: starting BIND 9.3.2 -t /var/named -u bind Jun 24 00:06:34 kobe named[12168]: command channel listening on 127.0.0.1#953 Jun 24 00:06:34 kobe named[12168]: running Now just stand back and wait for any other messages from `named' that point towards a configuration error or other problem. 5. Making the local nameserver the default ****************************************** Now you are ready to make your local nameserver the default server to be contacted for DNS queries. This is done by updating the `/etc/resolv.conf' file to include something like this: $ cat /etc/resolv.conf search drew. nameserver 127.0.0.1 $ Now all DNS-using applications should use 127.0.0.1 for their queries. Similarly, for other machines of the 192.168.0.X network, you should configure a `resolv.conf' file like this: $ cat /etc/resolv.conf search drew. nameserver 192.168.0.1 $ 6. Checking your new BIND setup ******************************* If your name server has started without problems, then you are ready to test it. You can use host(1), dig(1) and nslookup(1) for this. You should test that at least the following work correctly: * Lookup of hostname -> address * Lookup of address -> name These are easy to do, if you keep in mind that your `name server' is now 127.0.0.1 (on the name server itself), or 192.168.0.1 (if you are using "bsd.drew." as your DNS server): 1. Testing that 127.0.0.1 resolves correctly to `localhost.drew.' bsd# host 127.0.0.1 127.0.0.1 1.0.0.127.in-addr.arpa domain name pointer localhost.drew. 2. Testing that `localhost.drew.' resolves correctly to `127.0.0.1' bsd# host localhost.drew. localhost.drew has address 127.0.0.1 3. Testing that `*.drew' resolve correctly: bsd# bash bash$ for hname in bsd linux laptop; do host "$hname"; done bsd.drew has address 192.168.0.1 linux.drew has address 192.168.0.2 laptop.drew has address 192.168.0.3 Useful BIND Resources ********************* [1] Internet Systems Consortium, Inc. ``BIND 9 Administrator Reference Manual''. 2000-2005. http://www.isc.org/sw/bind/ , http://www.isc.org/sw/bind/arm93/ , http://www.isc.org/sw/bind/arm93/Bv9ARM.ch06.html#id2564557