How should I configure BIND9 to forward a zone?

Edit: I now have a lot more experience with domain name servers and resolvers. The root of this problem is having multiple authoritative name servers for a zone. This means two different name servers claim to be the authoritative source to resolve a DNS query for a particular zone (like 'example.com'). A nameserver claims authority via a SOA (start of authority) record, saying "Come to me for any lookups in the example.com zone."

I had used a public domain name (in this explanation, 'example.com') to refer to publicly available URLs (like www.example.com = 183.34.22.82, which gets redirected and translated to some private address like 192.168.1.2) AND for private URLs (private-server-1.example.com = 192.168.1.1). I had directed two different name servers to have authority over the same domain. The first would be a public DNS (in my case, Cloudflare). The second is my private DNS - the BIND server running on an internal, private URL (private-dns-server-1.example.com). This server would not be accessible to a computer outside my local network (the ubiquitous 192.168.x.x addresses).

This dual SOA works, but kind of. When you're at some public computer, you easily get to www.example.com because your public computer must use the public DNS as the authoritative answer to "What is the IP address of www.example.com?" The public computer can't reach the other authority (private-dns-server-1.example.com). The public computer has no knowledge of names or IP addresses within the private network. When you're at work, on the private network (you have an IP address like 192.168.1.32, and some other ranges also work), your computer will likely get the answer to "IP for www.example.com" from the internal private-dns-server-1.example.com. This will send you directly to 192.168.1.1, instead of sending you to the example public address I used above (183.34.22.82) then redirecting and translating to the private 192.168.1.1 address.

Sounds good, until you consider DNS caching. The DNS resolvers (these are 'clients' in DNS terminology) store prior answers for reuse. This speeds up your browsing, and reduces the load on servers overall. Let's re-run the example above.

While connected to the airport public wifi, you browsed to www.example.com. Your DNS resolver asked Cloudflare, and got back 183.34.22.82. The translation and redirection worked, and you saw your web page.

After returning to the office, you connected to the office wifi. You refreshed your browser, but the DNS query still directed you to 183.34.22.82, which may or may not work the same as if you went directly to 192.168.1.1. In many cases, you'll get the same web page. In some cases, you won't get the same behavior. This is the issue. Troubleshooting something that seems to behave one way at one time and another way at a different time is perhaps the most difficult task.

It's best to avoid multiple authoritative nameservers for a single zone. DNS servers like BIND9 have some clever constructs to solve this problem. An alternative is to pick an internal zone that is separate from your external zone. This doesn't mean you have to be 'example.com' to everyone, and 'awful324.int' inside your organization. You can carve out a zone within 'example.com' like 'int.example.com' as your internal addresses. Whatever you do choose, make sure you own it publicly (i.e. you've registered the domain name 'awful324.com') so nobody else registers it and creates a start of authority (SOA) record for that domain name/zone.

What I wrote a few years ago, while still flopping around with Linux and internet protocols generally:

In this case, I used tail to monitor the log file at /var/log/syslog by using $ tail -f /var/log/syslog. My configuration had multiple issues:

  • I had put my forwarding directive within a zone definition. I moved it to /etc/bind/named.conf.options.
  • As a separate problem, some public DNS queries were not resolving. By monitoring the syslog file, I found the server's time was not synchronized. I configured ntp on the server to resolve this issue.