Skip to main content

Getting to know the BIND9 DNS Server with Docker

Shenzhen, China

BIND is open source software that implements the Domain Name System (DNS) protocols for the Internet. It is a reference implementation of those protocols, but it is also production-grade software, suitable for use in high-volume and high-reliability applications. BIND 9 has evolved to be a very flexible, full-featured DNS system. You can download a current version from the ISC website. Or, install our updated ISC packages for Ubuntu, CentOS/Fedora, and the standard Debian package. I want to take a look at the official Docker Image.

Test Run

Download the official Docker Image and test run it with:

docker run \
--name=bind9 \
--publish 53:53/udp \
--publish 53:53/tcp \
--publish 127.0.0.1:953:953/tcp \
internetsystemsconsortium/bind9:9.18

The container can be accessed with:

docker exec -ti bind9 /bin/bash

Now run the following command to check whether BIND is running:

named -v
BIND 9.18.0-2+ubuntu20.04.1+isc+1-Ubuntu (Stable Release)

BIND 9 Configuration

All the configuration files of BIND 9 is in /etc/bind and /var/cache/bind directory. The main configuration files are named.conf, named.conf.default-zones, named.conf.local, and named.conf.options:

ls -la /etc/bind

-rw-r--r-- 1 root root 2403 Jan 28 07:53 bind.keys
-rw-r--r-- 1 root root 237 Jan 27 12:16 db.0
-rw-r--r-- 1 root root 271 Jan 27 12:16 db.127
-rw-r--r-- 1 root root 237 Jan 27 12:16 db.255
-rw-r--r-- 1 root root 353 Jan 27 12:16 db.empty
-rw-r--r-- 1 root root 270 Jan 27 12:16 db.local
-rw-r--r-- 1 root bind 463 Jan 27 12:16 named.conf
-rw-r--r-- 1 root bind 498 Jan 27 12:16 named.conf.default-zones
-rw-r--r-- 1 root bind 165 Jan 27 12:16 named.conf.local
-rw-r--r-- 1 root bind 846 Jan 27 12:16 named.conf.options
-rw-r----- 1 bind bind 100 Jan 28 08:25 rndc.key
-rw-r--r-- 1 root root 1317 Jan 27 12:16 zones.rfc1918

The /var/cache/bind directory contains all zone files. A zone file holds information about a certain domain name and its subdomains:

nano /var/cache/bind/hello.example.com

The zone file hello.example.com defines how a domain name is resolved and what IP it is resolved to. $ORIGIN defines a value for the @ symbol. Don’t forget the dot(.) after example.com as it is required for the FQDN (Fully Qualified Domain Name).

If you don’t put a FQDN in BIND zone file, then the value of $ORIGIN will be appended to the name. For example, ns1 is not a FQDN. So ns1 will be ns1.example.com.

$TTL 1d
$ORIGIN example.com.

@ IN SOA ns1 root (
1 ;Serial
1d ;Refresh
1h ;Retry
1w ;Expire
1h ;Minimum
)

@ IN A 172.17.0.2

@ IN NS ns1
ns1 IN A 172.17.0.2

@ IN NS ns2.example.com.
ns2 IN A 172.17.0.3

@ IN MX 10 mail
mail IN A 172.17.0.4
www IN CNAME example.com.
ftp IN CNAME example.com.

Here, example.com is the domain name and hello.example.com is the zone file for the domain name example.com.

Now I have to edit /etc/bind/named.conf.local to tell bind to load the data file hello.example.com for the zone example.com:

172.17.0.2 is the IP of the bind9 docker container:

ip a

13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
  • SOA Record: nameserver authoritative for a zone example.com is ns1.example.com and admin.example.com is an email address of a person responsible for this DNS zone.
  • NS Records: two nameservers for the example.com zone are ns[1,2].example.com
  • MX ( Mail Exchange): example.com mail exachange record. Number 10 means a preference for discarding a records A – A simply means address or in other words in example.com’s zone a ns1 would have an A ( address ) 192.168.0.10.
  • CNAME Record ( Canonical Name record ): restart the query using the canonical name instead of the original name

Run the following command to check the configuration:

named-checkconf

With this named-checkconf command no news is good news. If no output has been produced, your config files are OK. To check the DNS zone files we can use named-checkzone command:

named-checkzone example.com /var/cache/bind/hello.example.com
zone example.com/IN: loaded serial 1
OK
nano /etc/bind/named.conf.local
zone "example.com" {
type master;
file "hello.example.com";
};

To restart Bind I now have to stop/start the container and reconnect. I can now use my DNS service to resolve the example.com domain using dig (apt install dnsutils). @172.17.0.2 is used to tell dig to use the nameserver 172.17.0.2:

dig @172.17.0.2 hello.example.com any

; <<>> DiG 9.18.0-2+ubuntu20.04.1+isc+1-Ubuntu <<>> @172.17.0.2 example.com any
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9397
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 4

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: f8ea8c503c5bc7d501000000622096e24e69af6e56bf8a80 (good)
;; QUESTION SECTION:
;example.com. IN ANY

;; ANSWER SECTION:
example.com. 86400 IN SOA ns1.example.com. root.example.com. 1 86400 600 259200 86400
example.com. 86400 IN A 172.17.0.2
example.com. 86400 IN NS ns1.example.com.
example.com. 86400 IN NS ns2.example.com.
example.com. 86400 IN MX 10 mail.example.com.

;; ADDITIONAL SECTION:
ns1.example.com. 86400 IN A 172.17.0.2
ns2.example.com. 86400 IN A 172.17.0.3
mail.example.com. 86400 IN A 172.17.0.2

;; Query time: 0 msec
;; SERVER: 172.17.0.2#53(172.17.0.2) (TCP)
;; WHEN: Thu Mar 03 10:22:26 UTC 2022
;; MSG SIZE rcvd: 230

I can use the server to resolve the *.example.com domains using my own DNS server:

dig @172.17.0.2 www.example.com any +noall +answer
www.example.com. 86400 IN CNAME example.com.

dig @172.17.0.2 ftp.example.com any +noall +answer
ftp.example.com. 86400 IN CNAME example.com.

dig @172.17.0.2 mail.example.com any +noall +answer
mail.example.com. 86400 IN A 172.17.0.4

dig @172.17.0.2 ns1.example.com any +noall +answer
ns1.example.com. 86400 IN A 172.17.0.2

dig @172.17.0.2 ns2.example.com any +noall +answer
ns2.example.com. 86400 IN A 172.17.0.3