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 \

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/

The zone file 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 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

$TTL 1d

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

@      IN     A

@      IN     NS      ns1
ns1    IN     A

@       IN    NS
ns2     IN    A

@       IN    MX      10    mail
mail    IN    A
www     IN    CNAME
ftp     IN    CNAME

Here, is the domain name and is the zone file for the domain name

Now I have to edit /etc/bind/named.conf.local to tell bind to load the data file for the zone 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 brd scope global eth0
  • SOA Record: nameserver authoritative for a zone is and is an email address of a person responsible for this DNS zone.
  • NS Records: two nameservers for the zone are ns[1,2]
  • MX ( Mail Exchange): mail exachange record. Number 10 means a preference for discarding a records A – A simply means address or in other words in’s zone a ns1 would have an A ( address )
  • 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:


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 /var/cache/bind/
zone loaded serial 1
nano /etc/bind/named.conf.local
zone "" {
        type master;
        file "";

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

dig @ any

; <<>> DiG 9.18.0-2+ubuntu20.04.1+isc+1-Ubuntu <<>> @ 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

; EDNS: version: 0, flags:; udp: 1232
; COOKIE: f8ea8c503c5bc7d501000000622096e24e69af6e56bf8a80 (good)
;                   IN      ANY

;; ANSWER SECTION:            86400   IN      SOA 1 86400 600 259200 86400            86400   IN      A            86400   IN      NS            86400   IN      NS            86400   IN      MX      10

;; ADDITIONAL SECTION:        86400   IN      A        86400   IN      A       86400   IN      A

;; Query time: 0 msec
;; WHEN: Thu Mar 03 10:22:26 UTC 2022
;; MSG SIZE  rcvd: 230

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

dig @ any +noall +answer        86400   IN      CNAME

dig @ any +noall +answer        86400   IN      CNAME

dig @ any +noall +answer       86400   IN      A

dig @ any +noall +answer        86400   IN      A

dig @ any +noall +answer        86400   IN      A