Using BIND

Overview/commentary

At this time, this guide is designed for BIND. Previously, this software was included with OpenBSD, which was considered to be a point in BIND's favor. Now, BIND has been moved to OpenBSD ports. Still, since pre-existing directions were made for BIND, those directions were used for convenience.

If a person is going to learn how to use a DNS server, BIND is really not a bad choice to be familiar with. The “zone” configuration files for BIND are widely recognized.

Install

With new-enough (starting... some specific time...) versions of OpenBSD, BIND needs to be installed.

Back up the user database

A user account is about to be added during the installation process. (At least, that is true with some installations, including the OpenBSD package.) Now that you know that, it makes sense to routinely back up the information before it changes. (The following is copied from Early actions for “child” virtual machines: Accounts/Names, which had just a tad bit more commentary.)

export FILETOBK=$( sudo ${SHELL} -c " ls -1aF /etc/*group /etc/*passwd* /etc/*pwd.db* /etc/*shadow* 2>&1 " | grep -v "No such file or directory" | xargs )

Now that you've got the filenames in a variable, the rest of this process is to perform the actual backup. That part of the process may now be easier than the first time these instructions recommended backing up this data (because the cpytobak program hadn't been installed earlier).

echo ${FILETOBK}
sudo cpytobak ${FILETOBK}
sudo -i pkg_add -ivv isc-bind

Some impacts:

  • Created user: _bind (which is a bit interesting... when BIND was installed as part of OpenBSD, the dedicated username was “named”. So, that's a change...)
  • Created /var/named (e.g., when installing, the output includes:
    installed /var/named/etc/named.conf from /usr/local/share/examples/bind9/nam ed.conf
Make user for chroot

(Ignore this... this was written before realizing that _bind was auto-created.)

When ISC BIND was part of OpenBSD, it came with a user called “named”. You can name this user something else if you like. Since this is being added after the operating system is installed, this guide recommends having it start with _ (to help indicate it is a custom “system” account).

Adding users in OpenBSD
sudo adduser
Adding users elsewhere

Here is a resource. It is not considered to be a part of this guide, but may be helpful:
adding users

Set the shell to /sbin/nologin (in OpenBSD, the path must not be typed; just type the executable name of the pre-recognized shell “nologin”, and that ends up working okay.)

This user should not be part of “wheel”, nor “_sshok”.

In fact, after making the user, set the shell to /sbin/nologin (use “ sudo chsh username ” if that helps.)

Make config dir current

With OpenBSD, BIND's configuration has typically been under /var/named/ but other operating systems have used other locations.

sudo find / -iname named.conf

That shows a /var/named/etc/named.conf file.

cd /var/named/.
Understanding paths in BIND

Note: References are made to filenames like the ./etc/named.conf file. The etc/ directory being mentioned is NOT the same thing as /etc/ off of the system's root directory. Instead, it is in reference to the current directory. So, if /var/named/ is the current directory, then ./etc/ refers to /var/named/etc/

Even more confusing, the BIND program's configuration files may have a reference that says /etc/ but that actually does NOT refer to the /etc/ directory off of the root on the entire system. When BIND is reading the configuration files, any references to the “root” directory (starting with a slash) really points to a location that is within BIND's directory. So, if BIND's directory is /var/named/ then references in BIND's configuration file to /etc/ are really pointing to /var/named/etc/ and not the system's /etc/ directory.

(That might just be because of the effects of a “chroot”, rather than any code that is part of the BIND software.)

Editing configuration files

For the purposes of editing these configuration files, we'll use a temporary variable called BINDCFHM (BIND configuration home). That may make things simpler for people who have BIND pre-installed to look for configuration files in a different location.

export BINDCFHM=/var/named/.
${BINDCFHM}/etc/named.conf

echo ${BINDCFHM}
sudo cp -pi ${BINDCFHM}/etc/named.conf ${BINDCFHM}/etc/named-orig.conf
cpytobak ${BINDCFHM}/etc/named.conf ${BINDCFHM}/etc/named-orig.conf
echo ${VISUAL}
sudoedit ${BINDCFHM}/etc/named.conf

We're going to support “split horizon”, because it can be quite nice and there is little reason not to.

BIND ACLs
Pre-existing content: Clients
(HTML update here would be appropriate)
acl clients {
	localnets;
	::1;
};
Desired changes

Keep the “acl clients”, and add more content.

Add some more BIND ACLs to support private addresses. An example of this is shown by BIND configuration: BIND ACLs, which shows them (the ietfbcp5 and ipv6priv sections) just below the “acl clients” section.

As a note, the term “localnets” is described (see BIND configuration: BIND opts for details about the configuration term “localhost”, which is not a reference to the familiar DNS entry in a hosts file).

Options
Pre-existing content
options {
version "";

listen-on { any; };
listen-on-v6 { any; };

enable-zones-enable yes;

allow-recursion { clients; };
};
Desired changes

Yes. There are some desired changes.

  • First, make the section look like BIND configuration: BIND opts which has these changes:

    • An easy way to add more options without needing to change the main configuration file.
    • Restricting what addresses to listen on
    • Recognize the new ACLs
  • Then, add the IP addresses (except for lookback addresses) to the listen-on lines.
    • You'll need to figure out what IP addresses the DNS server has. (Check documentation, or leave the text editor and use ifconfig)
    • e.g.:

      listen-on { localhost; 198.51.100.4; };
      listen-on-v6 { localhost; 2001:db8:1::4; };

    • (The reason why this step gets done is to help make sure that BIND doesn't stop listening to some addresses. This topic gets discussed further by the “Troubleshooting: BIND fails over time” section. This step is one part of proactively avoiding that problem.)
Defining zones by view
Private view

Next, before the “zone” data, add these lines:

view "onlyint" {
match-clients { ietfbcp5; ipv6priv; };

(This is discussed by the “Using Split-horizon in BIND” section, underneath BIND configuration: BIND opts.)

Notice the mismatched curly brace: the “view line uses an “opening” “left” curly brace. In that nearby text, there is not a “closing” corresponding “right” brace to match it. (There is a “closing”/“right” brace at the end, but that matches a different “opening”/“left” brace nearer the middle of the text file content that was just quoted.)

How, go to the end of the “Standard zones” section, which is:

  • After the 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"
  • Before the start of the next section, where it says “// Master zones

At that spot, add some more text. The text to add is:

include "etc/prvzones.cnf";

}; // end of view "onlyint"

Ideally, the text in the middle (the “zone "." {, and related text up until the end of the five-line block related to zone "1.0.0.0.....ip6.arpa") will all be tabbed (except for the actual zone "1.0.0.0.....ip6.arpa" line, which may remain less tabbed for easier reading on columns that are less than 81 columns wide). That isn't done in the default file, so it would need to be done manually (if it is going to be done). That is not technically necessary for BIND to work, but it does make the configuration file's contents look more properly organized. If that minor tabbing effort is done, then the result will look similar to section called “The private domain(s)” found under BIND configuration: BIND opts.)

Public view
Pre-existing content

A bunch of comments:

// Master zones
//
//zone "myzone.net" {
// type master;
// file "master/myzone.net";
//};
// Slave zones
//
//zone "otherzone.net" {

// type slave;
// file "slave/otherzone.net";
// masters { 192.0.2.1; [...;] };
//};
Updates to make

Before the start of the “// Master zones section, add:

view "worldview" {
match-clients { any; };

Then, tab the remaining part of the file, which consists entirely of comments.

At the end of the file, add:

include "etc/pubzones.cnf";

} // end view "worldview"

An example of what this looks like, at the end, is shown by the “Public view” section under BIND configuration: BIND opts.

Making additional files

The named.conf file referenced some additional files. The touch command can help make sure that those files exist. (If the file already exists, this will have the side effect of updating the timestamp of a file.)

echo ${BINDCFHM}
sudo touch ${BINDCFHM}/etc/named.opt
sudo touch ${BINDCFHM}/etc/pubzones.cnf

Support forwarders. This is done by placing configuration in the options block of the named.conf file that gets used. If this guide is being followed, the named.conf file may point to:

echo forwarders \{ 198.51.100.3\; 203.0.113.4\; 8.8.8.8\; \}\;| sudo -n tee -a ${BINDCFHM}/etc/named.opt
  • Be sure to customize the sample addresses. (The topic of fowarders is is discussed further on BIND page.)

The pubzones.cnf file will be used if a public IP address gets supported by Reverse DNS. That file will also be used if any public domains are supported.

Also, a prvzones.cnf file needs to exist. If there are any private addresses, then that file is about to be edited (which will create the file). If you're actually not using “split horizon” and have no private addresses, then make sure that file exists (if it is referenced by the main named.conf configuration file). Basically, the goal here is to make sure that a file exists for every filename that is required due to a reference in the main named.conf configuration file.

Supporting domain(s)
Supporting private domain(s)

First, identify what domains you wish to support. Chances are that an internal domain has been used when machines have been given names.

This example show show the creation of two domains that provide private addresses. One is an internal domain named example.zz, and the other one is a domain with the name example.net

Note: You should not ever use example.net on systems that actually get used. Basically, it is not meant to be used on real systems. Using example.net on actual systems is likely a violation of point number one of RFC 6761: “Special-Use Domain Names”, section 6.5, “Domain Name Reservation Considerations for Example Domains”. This is discussed further by DNS: Official domains.

echo ${BINDCFHM}
sudo mkdir ${BINDCFHM}/master/internal/

...

echo ${VISUAL}
sudoedit ${BINDCFHM}/etc/prvzones.cnf

...

	zone "example.zz" {
		type master;
		file "master/internal/iexamplz"
	};

	zone "example.net" {
		type master;
		file "master/internal/iexampln"
	};

...

sudo cat ${BINDCFHM}/etc/prvzones.cnf | grep file

Now, each of those files needs to exist.

There's some detail at BIND zone files about the zone files. You can take a look at such an example, and then use “copy and paste” to place that in a file. Or...

Copying from an lo* file

You can use a pre-existing file that is on the computer that will be running the DNS server.

sudo cat ${BINDCFHM}/standard/localhost | sudo -n tee -a ${BINDCFHM}/master/internal/iexampln

Note that any of the sample files will likely need some substantial updating.

No matter which example is used at the start of the process, you'll likely be needing to make some changes, so:

  • Edit the file.
sudoedit ${BINDCFHM}/master/internal/iexampln

There's some detail at BIND zone files about the zone files. Basically, the easy way is to start by setting the $ORIGIN to the name of the domain that will be used.

Understanding some BIND shortcuts

If a later domain does not end with a period, then that domain is assumed to be a “sub-domain” of the origin. For example, BIND zone files shows a line that says:

NS a.ns ; Nameserver

At first glance, it looks like this line might be quite simple, having just three pieces including the last piece, which is a comment. However, the line is actually equivilent to:

example.net IN NS a.ns.example.net ; Nameserver

Let's see how that happened.

Perhaps the most important thing to understand is that the a.ns is not a FQDN (fully qualified domain name). In the DNS master zone files, if a domain name does not end with a period, then it is not considered to be an FQDN. So, since there isn't a period at the end of “a.ns”, it got converted to be treated like a sub-domain of the origin. The origin (of the sample file that was referred to earlier) is example.com, so the a.ns gets converted to a.ns.example.com

Since the first part of the line is white space, the system name will be copied from the previous (non-blank) line. Actually, in this example, the previous line also has a white space, so that pattern continues until a line doesn't have white space. That ends up going all the way back to the parentheses. The parentheses are used to treat multiple lines like a single line, so that single line is treated as if it looks something similar to this:

@ IN SOA ( someStuff )

The @ is surrounded by white space, so it is treated as a shortcut for the domain name which is the $ORIGIN. (Specifically, the white space before the @ are the “newline” character(s) (which is simply a “line feed” character for most Unix systems.)

As you can see, the presense of a “white space” character had a profound effect on how the line was being treated. (The term “white space”, in this particular case, refers to a “tab” character or a standard “space” character. Those two characters are treated the same.) Therefore, it is quite essential that lines do not start with one of these “white space” characters unless the intent is to match whatever system name shows up earlier in the configuration file.

To discuss the topic of leading white space even further, Zytrax.com open: Pro DNS and BIND: Chapter 8, SOA records says, “We are reliably informed that while a blank is a perfectly valid format certain DNSSEC signing tools may choke on this format.” There's also been people complaining that people have had some troubles when trying to use a blank system name with some forms on web pages. Although this may be valid syntax with BIND, know that some third party software may be less likely to fully support such syntax. Fully specifying the system name ought to work in all cases, and so that may be the safer approach.

Finally, there is the IN. That refers to a “class”. The DNS class refers to a type of network that was used. Since DNS is a very old protocol, the DNS configuration standards supported some classes other than the Internet. However, in modern times, the general expectation is that people are using the class called IN which stands for “Internet”.

There is a rule that says that each master zone file should have a class, and only one class. So the IN class can be specified only once, or multiple times. If the class isn't mentioned, when the DNS server simply uses whatever was specified earlier in the file. Every time the class is mentioned, it should be the same value as every other time that the class is specified in the same master zone file. For modern networks, that value should be IN.

[#mkzonedt]: Things to do in the zone file
Set the ORIGIN

(optional) Set the TTL

Create required records

RFC 2181 (“Clarifications to the DNS Specification”) Section 6.1 (“Zone authority”) says, “The authoritative servers for a zone are enumerated in the NS records for the origin of the zone, which, along with a Start of Authority (SOA) record are the mandatory records in every zone.” Based on that quotation, there are two types of records that are required for every zone.

SOA record

This contains some text (like an E-Mail address), and some numbers. The section about SOA resource records describes each value in more detail.

Create NS records

This specifies a DNS name for a computer running a “DNS server” that contains information about this zone.

Create host records (“AAAA” records for IPv6 and “A” records for IPv4)

External/“publicly accessible” domains

When working with a brand new domain that is unlikely to be accessed by visitors (because nobody is aware of that brand new domain yet), there is probably no problem with creating a DNS server that works on the internal network. For established domain names where customers may already be aware of the name, client software (such as a web browser) may be trying to look up such a domain. A DNS server can actively respond with information that the domain is not supported by that DNS server, and such a response could conceivably be recognized by a DNS client in a different way than if no DNS server responded at all. Whether this is an issue, or not, might depend on factors like which client software is being used, and how the results get presented to a user, and who that user is. (Different users might respond different to identical messages.)

Since support for external domains is something that an be sensibly delayed, at least in some cases, this documentation doesn't cover that detail until after discussion on how to perform tests that verify successful functionality of supporting internal domains.

Testing internally

At this time, some preliminary testing could occur, at least for small networks. (For larger scale situations, it might be better to delay testing until the public DNS configuration is also set up well enough to be operational. Being unresponsive may be better than providing details like saying that a DNS name doesn't appear to have an address configured.)

old

Run “ sudo /etc/rc.d/isc_named start ”.

old

Run “ sudo named -t /var/named -u _bind ”.

FreeBSD forum post about “named[PID #]: the working directory is not writable” log message

Now, if you want to test the private addresses, you can send a DNS query to the IP address on the non-loopback NIC. If you want to test the public addresses, youc an send a DNS query to the loopback address. The host command comes with BIND 9. Other options include using the nslookup command or the the dig command.

(The # character causes the rest of the command line to be treated as a comment. So, in the upcoming example, anyone manually typing these commands will not need to the characters # character nor any of the later characters on the same line.)

host example.org 192.0.2.1 # check public name, query external NIC using internal IP address
host example.zz ::1 # check public name, query IPv6 loopback
host example.zz 127.0.0.1 # check public name, query IPv4 loopback

nslookup example.org 192.0.2.1 # check public name, query external NIC using internal IP address
nslookup example.zz ::1 # check public name, query IPv6 loopback
nslookup example.zz 127.0.0.1 # check public name, query IPv4 loopback

dig example.org @192.0.2.1 # check public name, query external NIC using internal IP address
dig example.zz @::1 # check public name, query IPv6 loopback
dig example.zz @127.0.0.1 # check public name, query IPv4 loopback

To test IPv6:

host -t AAAA example.org 192.0.2.1 # check public name, query external NIC using internal IP address
host -t AAAA example.zz ::1 # check public name, query IPv6 loopback
host -t AAAA example.zz 127.0.0.1 # check public name, query IPv4 loopback

nslookup -q=AAAA example.org 192.0.2.1 # check public name, query external NIC using internal IP address
nslookup -q=AAAA example.zz ::1 # check public name, query IPv6 loopback
nslookup -q=AAAA example.zz 127.0.0.1 # check public name, query IPv4 loopback

dig # does this by default, so use the IPv4 examples
[#rdnsnbnd]: Reverse DNS (in BIND)

In general, every reserved IP address should have a “Reverse DNS” entry.

Internal lookups

First of all, make sure that the domain is supported.

echo ${BINDCFHM}
cpytobak ${BINDCFHM}/etc/prvzones.cnf
echo ${VISUAL}
sudoedit ${BINDCFHM}/etc/prvzones.cnf

Add the following lines (assuming they are not there already):


	# Reverse DNS settings for private addresses
	zone "d.f.ip6.arpa" {
		type master;
		file "master/internal/rdns/rdnsfds8"; # fd00::/8
	};

	zone "2.0.192.in-addr.arpa" {
		type master;
		file "master/internal/rdns/19202s24"; # 192.0.2/24
	};

Notes:

Next, edit the appropriate files. For example, for IPv6:

echo ${BINDCFHM}
sudo mkdir ${BINDCFHM}/master/internal/rdns/
  • (This example is assuming that the file doesn't pre-exist. If it does, make sure to back it up before making changes (simply to follow a good regular habit of backing up configuration files before making changes).)

Use a template.

  • One way to do this is by copying an existing file. e.g.:

    echo ${BINDCFHM}
    sudo cp -pi ${BINDCFHM}/standard/loopback6.arpa ${BINDCFHM}/master/internal/rdns/rdnsfds8
  • Another way to do this is to find some documentation that can be easily followed, hopefully even by using “copy and paste”. (making zone data covered this a bit, in part by referring to zone files (for BIND).)
echo ${VISUAL}
sudoedit ${BINDCFHM}/master/internal/rdns/rdnsfds8
  • (This example is assuming that the file doesn't pre-exist. If it does, make sure to back it up before making changes (simply to follow a good regular habit of backing up configuration files before making changes).)

Set the following:

$ORIGIN

The value of the ORIGIN should match the zone line in the BIND configuration file. (If this guide is being followed, the relevant BIND configuration files are the prvzones.cnf file for private domains, or pubzones.cnf file for public domains.) For example:

  • $ORIGIN d.f.ip6.arpa.
  • or “$ORIGIN 2.0.192.in-addr.arpa.
SOA

Generally, the first part of the SOA record (which RFC 1035 calls teh “MNAME”) will be a reference to the $ORIGIN, and that is done simply by using a @ (starting at the beginning of the line, and containing white space afterwards). (Specifically, the white space before the @ are the “newline” character(s) (which is simply a “line feed” character for most Unix systems.)

NS records

The NS records are simply NS records, just like a zone file that has nothing to do with Reverse DNS.

PTR records

Each “Reverse DNS” zone is related to a group of addresses. So, when modifying the text file related to a single “Reverse DNS”, only IPv6 addresses or IPv4 addresses will be getting used in the PTR records, not both. Following is information about both, so one (but not both) of these sections will apply while editing a single “Reverse DNS” zone file.

PTR records related to IPv6 addresses

For IPv6, this is particularly nasty.

  1. First, unabbreviate the address fully. For example, fd00::1234:c would become fd00:0000:0000:0000:0000:0000:1234:000c
  2. Then, reverse the order of all of the digits. So, fd00:0000:0000:0000:0000:0000:1234:000c would become: c000:4321:0000:0000:0000:0000:0000:00df
  3. Then, remove all of the colons, and put a period in between every single hexadecimal digit. So, this now becomes: c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f
  4. Then, add the text “.ip6.arpa.”. This represents the full value of the left part of a PTR record.
  5. By using the value of the $ORIGIN, this will be able to be abbreviated, which is about to be discussed.
PTR records related to IPv4 addresses

...

Then, things can be abbreviated a bit:

Abbreviating the PTR record names

Then, look at the value of the $ORIGIN. In this example, the value of the “$ORIGIN” is d.f.ipv6.arpa.”. For the PTR record, we can remove the text that is also in the value of the “$ORIGIN”. To do this, the value needs to NOT end with a period, so also get rid of the period that came just before value of the “$ORIGIN”. So, if the full PTR record was “c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa.”, and the “$ORIGIN” was set to “c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa.”, then the text needed to the left of the PTR record in the zone file is “c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0”.

For IPv6 addresses, the portion of the full system name, which appears to the left of the text “PTR” (which is the DNS “resource record” “type”) should contain enough hexadecimal digits to have a total of 32 hexadecimal digits when combined with the $ORIGIN's value, not counting any of the charaters in the phrase “.ipv6.arpa.”.

Here is an actual sample of what a couple of lines might actually look like:

c.00000000000000000000000000000 PTR name
; ; comment
  • The name is something to customize. That needs to either be a relative name, or it needs to be a FQDN which ends with a period.
  • Note the semi-colon at the start of the line. In general, it is a safest habit to not start a line with a semi-colon unless you are trying to copy the prior contents.
  • The number of zeros was precisely counted: there were 29 zeros. In additon to the c and the fd, that makes for 32 hexadecimal digits. For zones where you may be using a longer origin, you would want to have fewer hexadecimal digits specified in the lower section of the configuration file. The total number of hexadecimal digits, when combined with the ORIGIN, should be 32 hexadecimal digits. (Each hexadecimal digit represents 4 bits of the 128-bit address.)
Enabling firewall rule for DNS
Configuration on “firewall” system

On the “firewall” virtual machine, allow DNS traffic to pass if it is going to the authorized DNS servers (regardless of which network interface the traffic arrives on, and regardless of which network address the traffic is coming from).

OpenBSD PF
cpytobak /etc/pf.conf
echo | sudo -n tee -a /etc/pf.conf
echo \# Enable DNS to main \(both public and internal\) DNS server| sudo -n tee -a /etc/pf.conf
echo pass quick proto udp to { \$dnsint } port domain keep state| sudo -n tee -a /etc/pf.conf
echo ${VISUAL}
sudoedit /etc/pf.conf

(No further changes are needed... this is just a chance to review, and easily make changes if needed.)

sudo pfctl -nf /etc/pf.conf
echo ${?}
sudo pfctl -nf /etc/pf.conf&&sudo pfctl -ef /etc/pf.conf
Configuration of DNS server's firewall
OpenBSD PF
cpytobak /etc/pf.conf
echo | sudo -n tee -a /etc/pf.conf
echo \# Enable incoming DNS| sudo -n tee -a /etc/pf.conf
echo pass in quick proto udp to self port domain keep state| sudo -n tee -a /etc/pf.conf
echo ${VISUAL}
sudoedit /etc/pf.conf

(No further changes are needed... this is just a chance to review, and easily make changes if needed.)

sudo pfctl -nf /etc/pf.conf
echo ${?}
sudo pfctl -nf /etc/pf.conf&&sudo pfctl -ef /etc/pf.conf
Configuration of “physical” system's firewall
...
Testing
host example.org 192.0.2.1 # check public name, query external NIC using internal IP address
host example.zz ::1 # check public name, query IPv6 loopback
host example.zz 127.0.0.1 # check public name, query IPv4 loopback

nslookup -q=PTR c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa. 192.0.2.1 # check public name, query external NIC using internal IP address
nslookup -q=PTR c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa. ::1 # check public name, query IPv6 loopback
nslookup -q=PTR c.0.0.0.4.3.2.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.f.ip6.arpa. 127.0.0.1 # check public name, query IPv4 loopback

dig -x fd00::1234:c @192.0.2.1 # check public name, query external NIC using internal IP address
dig -x fd00::1234:c @::1 # check public name, query IPv6 loopback
dig -x fd00::1234:c @127.0.0.1 # check public name, query IPv4 loopback

Yeah, nslookup looks the most hideous, showing the full proper IPv6 domain to look up. Well, that is the most compatible syntax.

Newer nslookup syntax

However, some versions of nslookup (hmm... probably the one that comes with BIND, and probably not the one bundled with Microsoft Windows?) supports an easier syntax:

nslookup -q=PTR fd00::1234:c 192.0.2.1 # check public name, query external NIC using internal IP address
nslookup -q=PTR fd00::1234:c ::1 # check public name, query IPv6 loopback
nslookup -q=PTR fd00::1234:c 127.0.0.1 # check public name, query IPv4 loopback

Just don't rely on such support for multi-platform portable code (without doing some sort of check to see whether this actually works).

External/public lookups

If somebody from the outside world is asking for information about the public IP address that you use, then that person's computer will ask the DNS server that is in charge of that IP address. Very commonly, at least for IPv4, this does not mean asking your DNS server if you're just using a single IP address.

Instead, the common approach to take is this:

  • The IP address needs to be a “static IP address”
  • Customer must contact the ISP, and ask the ISP to set up the “Reverse DNS” entry.
  • Customer needs to tell the ISP what the response should be for a “Reverse DNS” request.

Painfully, there have been a lot of experiences with an ISP where this process may take some time. After requesting a change, the update might not take effect for a number of days. Unfortunately, it seems that there is nothing that a standard individual customer can do to speed up that common process.

With many major ISPs, another issue is that many “customer service” staff members seem to be unaware of the company's policies regarding how to submit a “Reverse DNS” request. Transferring a phone call to an escalated tier of support may improve the chances of being able to talk with somebody who does know the process.

Once the employee requests the “domain name”, then the customer should ask how long the process takes. Make a note of that answer. (Times of a matter of minutes or hours would be reasonable, but, sadly, a timeframe like 3 to 7 days might be more common.) Some companies may have a “reference number” that gets generated as part of their internal process. In case things go imperfectly, it may be worthwhile to ask for such a “reference number”. (If no “reference number” is generated, and therefore no “reference number” is available, that seems like an entirely believable situation that is not a cause of concern. This simply relates to what method the company uses to organize the status of the requests.)

So, setting up “Reverse DNS” involves exchanging information (with a knowledgable employee, who knows about how to handle “Reverse DNS”, asking for a domain name, and then the customer requesting information about the expected timeframe). Once the information has been exchanged , there is no real way to verify that things have been correctly done, except to check the public “Reverse DNS” records. Since it takes some time for that to occur, verification may not be possible for some time (possibly even a matter of days).

  • If the deadline passes, then contacting the ISP again is appropriate.
  • Also, if a change occurs, and the domain name is misspelled, then contacting the ISP right away is appropriate.
  • (If the name shows up correctly, then be happy that this got taken care of.)

Until any of these things happen, the only really useful actions are to try to make one of those things happen, by checking for changes and waiting for the deadline.

Supporting external/public domain(s)
Using main zone files
...
Testing from remote
OpenBSD (using rdr syntax from OpenBSD 4.7's pf)
(This section still needs a bit of clean-up...)

send the DNS query to the DNS server's address. Or, if the DNS server has no public address, but the firewall does, you can redirect the traffic. This is particularly common with IPv4. You an also do the same thing with IPv6: This demonstrates both:

On the firewall: define ext_if, then:
# redirect DNS traffic to internal DNS server
pass in on $ext_if inet6 proto udp from any to self port domain \ rdr-to 2001:db8::4
pass in on $ext_if inet proto udp from any to self port domain \ rdr-to 192.0.2.4

  • The reason that domain works is that the /etc/services defines that term as one of the names related to UDP port 53.
    • There is also an alternate name of “domain but avoid that, because that term may match TCP port 42 (related to Internet Engineering Note 116: Basic/Internet Name Server). So avoid that name. However, the TCP port name of “domain” is widely known, and so that ought to be safe to use.
  • This example, as shown, is presuming that most machines will attempt to use the firewall as the DNS server, and that the “DNS server” software is running on a system other than the firewall. That probably is the sensible design if the DNS server does not have its own publicly accessable address, which might commonly be true for IPv4 communications coming from the public Internet. For internal traffic, you may prefer a more straightforward design of having the traffic go straight to the actual DNS server. In that case, a simpler pass rule could be used. (Take off the “rdr-to and every part after that, and make the part after the word “to” contain the address for the DNS server.)
  • Instead of “self”, another option could be “($ext_if)” (not including the quotation marks, but including the parentheses), which translates to any address on the one NIC that is specified inside the parenthesis. You can do that (and might prefer to do that) if all DNS traffic is going to a specific address on the firewall.

OpenBSD manual page for the /etc/pf.conf file

Troubleshooting
[#bndifitv]: BIND fails over time
Problem overview

The /var/log/messages file may show “named: could not listen on UDP socket: permission denied”, which leads to another log message, “creating (some type of) interface (with a specific name) failed; interface ignored” message (e.g. when BIND tries creating IPv4 interface).

Just to throw some fuel into the fire of speculation, here are some observances:

  • olli's post about when BIND stops listening seems to indicate the problem may be related to “a dynamic interface (like tun0 in this case)”
  • On a sample machine, this was known to happen to IPv4 but not IPv6. At the time, IPv4 was being served by DHCP/IPv4 but IPv6 addresses were assigned statically. Maybe the less-than-an-hour timing had to do with the DHCP/IPv4 lease renewal rate?

In practice, this has been known to cause problems on having a dynamic interface listen on an IPv4 address. Curiously, the exact same system did not have the same problem with listening on an IPv6 address, so IPv6 address continued to work even after BIND started logging these messages that indicate BIND started ignoring IPv4 communications.

None of the techniques discussed here worked entirely. Trying to listen to a specified IPv4 address (and no other IPv4 address specified) seemed to let BIND work from 15:57 (3:57pm) to 9:13am, about 17 and a quarter hours, before the problem re-surfaced. Eventually these thoughts were experienced:

  • perhaps BIND could listen on a higher port, and a firewall redirect could send traffic from 53 to the high port.
  • Based on Chris Buxton (of “Men & Mice”)'s post (part of thread on BIND dropping an interface), it seems this may be known behavior, and Chris notes, “You might be able to work around this on Linux by setting capabilities”. This work-around is not available on BSD systems that don't use the Linux-specific “capabilities” feature.
  • Another solution would be to run BIND as root. (That would require running named instead of the pre-supplied (non-customized) /etc/rc.d/isc_named which specifies a different user.) This is less preferable due to the idea that BIND's security is generally less trusted than the security of some other DNS servers.
  • Maybe some other DNS server software might be able to be set up rather quickly, instead of using BIND

Currently, this guide is recommending two approaches to help deal with this problem. To clarify: both approaches are recommended. Do both of these things.

Setting interface-interval 0;

The /var/log/messages file may show some messages described by Forum post: named: could not listen on UDP socket: permission denied discusses a potential problem. This forum post also applies to the related “creating (some type of) interface (with a specific name) failed; interface ignored” message (e.g. when BIND tries creating IPv4 interface).

The curious part about this forum post is that the forum post indicates that things continued to work. In practice, an actual experience indicates that people reported the DNS server stopped functioning.

Based on a post by olli@ on FreeBSD forums,“ you can also add "interface-interval 0;" to your named.conf file. This will disable the interface scanning that normally occurs every 60 minutes by default. Since named doesn't run as root by default so it cannot re-bind port 53 (unless you use the "portacl" MAC module), interface scanning is useless anyway, so it can be safely disabled.” (Related: BIND Administrator Reference Manual: Periodic Task Intervals documents this. Zytrax: Pro DNS and BIND: DNS BIND Periodic (Time controlled) Statements states, “This option may only be specified in a 'global' options statement.”)

Using options file

If the rest of this guide has been followed, then a slick way of handling this is to actually make use of the named.opt (“options”) file.

echo ${BINDCFHM}
cpytobak ${BINDCFHM}/etc/named.opt
echo interface-interval 0\;| sudo -n tee -a ${BINDCFHM}/etc/named.opt

Then, follow the upcoming instructions to restart BIND, which will cause BIND to start using this file.

Manual

To do this:

echo ${VISUAL}
echo ${BINDCFHM}
sudoedit ${BINDCFHM}/etc/named.conf

Then look for

options {

It might make sense to place the needed line underneath the section about listen-on (and listen-on-v6). However, the only real requirement is that the new line ends up being one of the lines within this “options” block.

Add the desired line:

interface-interval 0;
Listen on each local non-loopback IP address

On the listen-on lines (the IPv4listen-on” line, and the listen-on-v6 line), include the IP addresses.

  • You'll need to figure out what IP addresses the DNS server has. (Check documentation, or leave the text editor and use ifconfig)
  • e.g.:

    listen-on { localhost; 198.51.100.4; };
    listen-on-v6 { localhost; 2001:db8:1::4; };

  • (The reason why this step gets done is to help make sure that BIND doesn't stop listening to some addresses. This topic gets discussed further by the “Troubleshooting: BIND fails over time” section. This step is one part of proactively avoiding that problem.)

Hmm...

Additional ideas
CPanel forums: BIND not listening blamed an incorrect reference to the named.pid file.

Then, BIND should reload the configuration files.

Reloading BIND configuration files

A “man” page has suggested that the rndc is preferred over sending signals. However, sending signals is an older technique that doesn't require configuring a security key like what rndc may require, so it is a good approach that is recommendable despite the man page's comment.

sudo kill -HUP $(pgrep named )

The other approach would be to check currently running software: see what is running, note the command, stop it (“currently running software”, “adjusting running software” section), and repeat it (with sudo.

Checking a log

If there is trouble with a single zone file, but other zone file(s) work fine, BIND just might start up and provide DNS services on the zones that didn't work.

It is worth checking the system log to see if BIND had any other complaints.

The use of -20, in the following example, is picked rather imprecisely. On one system, BIND was seen to output 14 lines when things worked well, and 16 lines when a zone was being skipped, so tail's default of 10 lines may be a bit short of ideal. There is probably no need to catch the first lines if at least part of the header is shown.

sudo tail -20 /var/log/messages
Additional step(s)
Supporting rndc

This is quite optional. There is no need to do this, but this guide mentions this step to help paint a picture of a “more complete” installation.

About rndc

The “r” in the name “rndc” probably stands for “remote”, and the rest of the name might stand for “name daemon control”.

rndc is a “command line” utility that can give some orders to the BIND software, such as a command to reload zone files that may have been updated. Doing things that way might be a bit more efficient than restarting the entire BIND software, in part because BIND may be more prone to keep using some cached information (like details about remote servers).

In practice, there may be little-to-no reason to go through the steps of supporting rndc until after there are any perceived plans to possibly use that software. For some organizations, uptime is less critical, and needing to re-obtain DNS details (instead of relying on a local cache) is not a big deal. For such situations, there may be little reason for a technician to spend time using the rndc software, rather than simply performing familiar processes like sending a HUP signal to BIND's process ID.

You may wish to start by checking if “rndc” is already supported. (It apparently was, rather automatically, by older OpenBSD versions that came bundled with BIND. However, with newer versions that have had BIND moved to a package, this does not appear to be done by default.)

Otherwise, generate a new key, store that key in a file, secure the file (meaning to set permissions so that it is not unnecessarily widely readable), and use that file (by pointing to it from a configuration file that BIND uses). The whole process (in a slightly different order than what was just described, but which should work also work fine) is described by Red Hat Enterprise Linux 3: Reference Guide, Chapter 12: Berkeley Internet Name Domain (BIND), section 12.4: Using rndc. BIND 9 documentation: Administration Reference Manual Chatpter 6: BIND 9 Configuration Reference also discusses this a bit, noting “The rndc.key feature was created to ease the transition of systems from BIND 8”... and later mentions “the rndc.key feature is only intended to allow the backward-compatible usage of BIND 8 configuration files”.

Starting the server automatically

The specific details will vary based on what operating system is being used. (Info: system startup)

Auto-starting BIND in OpenBSD

If BIND was added as a package, consider this:

cpytobak /etc/rc.local
echo /etc/rc.d/isc_named start| sudo -n tee -a /etc/rc.local

(With older versions of OpenBSD, there may have been a /etc/rc.conf.local entry for named_flags or something similar to that.)

Keeping BIND stable

It may seem like BIND is working... and maybe it is, for the next 45 to 60 minutes, when you may find that it just stops working. If you'd like to proactively prevent that problem, see: Troubleshooting BIND: BIND fails over time.

Second hard drive...

(This might wait until later... there may be a high likelihood of additional changes as several other systems may be getting added.)

Other/Misc notes
../../../../../../../techns/trblshot/usedres/usedres.htm#whotcp refers to: https://www.freebsd.org/doc/en/books/faq/security.html#idp60176336