Getting to know the BIND9 DNS Server with Docker
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