configure bind9 in debian/ubuntu

This guide will cover setting up the Bind9 DNS Server for Ubuntu/Debian systems, we will setup a Forward Lookup Zone as well as a Reverse Lookup Zone. In other distributions like Centos, the package will be named but the configuration is mostly the same. Here we will work on creating a Master DNS Server, this is your primary DNS Server for the organization. The domain that i will be using is linuxman.local and my DNS server will be with a Windows 7 machine as a client.

We will presume you have the following already setup and ready to go before we begin:

  • Static IP
  • Domain name in mind
  • Server setup with an FQDN
  • PC used for testing

If you need to setup your FQDN on your machine, go to my page Set Hostname in Linux.

1. First lets install the package bind9 using apt.

sudo apt install bind9 -y

2. After Bind9 has finished installing lets go ahead and cd into our bind directory and list its contents.

debian@debian:/etc/bind$ cd /etc/bind/

debian@debian:/etc/bind$ ls -l
total 56
-rw-r--r-- 1 root root 3923 May 3  15:34 bind.keys
-rw-r--r-- 1 root root 237  May 3  15:34 db.0
-rw-r--r-- 1 root root 271  May 3  15:34 db.127
-rw-r--r-- 1 root root 237  May 3  15:34 db.255
-rw-r--r-- 1 root root 353  May 3  15:34 db.empty
-rw-r--r-- 1 root root 270  May 3  15:34 db.local
-rw-r--r-- 1 root root 3171 May 3  15:34 db.root
-rw-r--r-- 1 root bind 463  May 3  15:34 named.conf
-rw-r--r-- 1 root bind 490  May 3  15:34 named.conf.default-zones
-rw-r--r-- 1 root bind 239  May 11 10:07 named.conf.local
-rw-r--r-- 1 root bind 881  May 11 10:04 named.conf.options
-rw-r----- 1 bind bind  77  May 11 00:06 rndc.key
-rw-r--r-- 1 root root 1317 May 3  15:34 zones.rfc1918

The files we are going to be working with are:

  • named.conf.local: Will be the one responsible for specifying custom zones that we will be adding.
  • named.conf.options: Will be the one responsible for configuring extra options we want to add to our server such as Forwarders.

    A forwarder is used to forward DNS Queries to an external/remote DNS server if the query does not exist in the zone. Example if i query from my Windows machine. The query will go to the Windows machine's DNS server, the server will check its zones for, if it does not find it then it will Forward the query to whatever DNS server is setup as a Forwarder.
  • db.local: This is the template we are going to use to build up our own zone.

Forward Lookup Zone

1. Lets make a copy of the db.root file and give it the name of our zone. Lets call it db.linuxman.local.

sudo cp db.root db.linuxman.local

2. Using your favorite text editor, lets edit our zone.

sudo vim db.linuxman.local

This is what the zone currently contains so we will change some values to match our domain:

; BIND data file for local loopback interface
$TTL  604800
@  IN  SOA  localhost. root.localhost. (
     2 ; Serial
  604800 ; Refresh
   86400 ; Retry
   2419200 ; Expire
  604800 )  ; Negative Cache TTL
@  IN  NS  localhost.
@  IN  A
@  IN  AAAA  ::1

We are going to change the bolded values to the following:

; BIND data file for linuxman.local domain
$TTL  604800
@  IN  SOA  linuxman.local. root.linuxman.local. (
   20190511  ;Serial
  604800 ; Refresh
   86400 ; Retry
   2419200 ; Expire
  604800 )  ; Negative Cache TTL
@  IN  NS  ns1.linuxman.local.
@  IN  A
ns1  IN  A

Something that i rarely find explained in other tutorials is what to put in the SOA record. The SOA record is devided into the following:

  • NAME: Name of the zone which should be left as @, that will default to the name of our root domain which is linuxman.local.
  • IN: Zone class, IN for Internet
  • SOA: Abreviation of Start of Authority
  • MNAME: This is the Primary Master name server for the zone, idealy your root domain which would be linuxman.local.
  • RNAME: This is the email address of the person responsible for the zone but encoded as a name. So if i want to use the email root@linuxman.local, it would be root.linuxman.local.
  • SERIAL: This is usually used for slave/secondary DNS servers. When an update has been made to a master server, the serial number will increase indicating to the slave servers that an udpate has been made which will then start a zone transfer. Most of the time the date of initial creation of the zone is used but can start at any number, just be sure to increase this after every change so your slave servers are aware.
  • REFRESH: This is the rate at which slave servers will check for updates.
  • RETRY: This is the number of seconds after which secondary name servers should retry to request the serial number from the master if the master does not respond. It must be less than Refresh.
  • EXPIRE: This is the number of seconds after which secondary name servers should stop answering request for this zone if the master does not respond. This value must be bigger than the sum of Refresh and Retry.
  • TTL: This is the Time to Live for negative caching.

3. Lets continue by adding some DNS Records. I will go over some common records you would see in a business.

A (Address) Record

@        IN        A

Using @ as the host will resolve to the root domain, linuxman.local. These records point a hostname/FQDN to an IP Address.

www      IN        A

This A record will point to the www host which will be a webserver. The FQDN would be www.linuxman.local.

CNAME/Alias Record

tech     IN        CNAME    www

CNAME records will point to an existing record of your choosing. I will alias www with tech. Be aware that the CNAME Record must be defined BEFORE the A Record that the CNAME is pointing to.

MX Record

         IN        MX   10  mail.linuxman.local
mail     IN        A

The MX record will define where email should be sent to and what priority. Requires an A record for the mail server itself, it is not considered an Alias.

NS (Name Server) Record

         IN        NS       ns
ns       IN        A

NS Records define which servers serve copies of the zone, must point to an A Record and not a CNAME/Alias.

SPF Record

@        IN        TXT      "v=spf1 ip4: -all"

DKIM Record

selector._domainkey        IN        TXT        "v=DKIM1; k=rsa; p=<public key>"

DMARC Record

_dmarc    IN       TXT      "v=DMARC1; p=reject; fo=1;;"

SPF, DKIM and DMARC are a set of TXT Records used for verifying outgoing email addresses.


; BIND data file for linuxman.local domain
$TTL  604800
@  IN  SOA  linuxman.local. root.linuxman.local. (
   20190511  ;Serial
  604800 ; Refresh
   86400 ; Retry
   2419200 ; Expire
  604800 )  ; Negative Cache TTL
; NS Records
  IN  NS  ns.linuxman.local.

; CNAME/Alias Records
tech  IN  CNAME  www.linuxman.local.

; A Records
@  IN  A
ns  IN  A
www   IN  A
mail  IN  A

; MX Records
  IN  MX  10  mail.linuxman.local.

; TXT Records
; SPF Records
@  IN  TXT  "v=spf1 ip4: -all"
; DKIM Records
selector._domainkey  IN  TXT  "v=DKIM1; k=rsa; p="
; DMARC Records
_dmarc  IN  TXT  "v=DMARC1; p=reject; fo=1;;"

4. Now we will add the new zone to the named.conf.local that way the new zone is loaded with Bind9.

sudo vim named.conf.local

5. Add the new zone as below making sure your file is the absolute path of the zone file.

zone "linuxman.local" {
  type master;
  file "/etc/bind/db.linuxman.local";

Reverse Lookup Zone

1. Lets make a copy of our db.linuxman.local file and modify it to use it for our reverse lookup zone. You can name the new file using db.<first octet>.

sudo cp db.linuxman.local db.172

Remember that Reverse Lookup Zones resolve IP Addresses to Domain Names, so we're going to remove about half of the records we created.

2. Using your favorite text editor, delete all SPF, DKIM, DMARC, CNAME, and MX Records leaving only the NS and A Records.

; BIND data file for linuxman.local domain
$TTL 604800
@ IN SOA linuxman.local. root.linuxman.local. (
  20190511 ;Serial
 604800 ; Refresh
  86400 ; Retry
  2419200 ; Expire
 604800 ) ; Negative Cache TTL
; NS Records
 IN NS ns.linuxman.local.

; A Records
@ IN A
ns IN A
www  IN A
mail IN A

3. Now that we have a base to work off of, you are going to reverse the records where the last octet of the IP Address will be on the left and the hostname will be in the right followed by a dot. The NS Record will use an @ on the left and the hostname on the right. Last, instead of A records, they will be Pointer Records (PTR).

; BIND data file for linuxman.local domain
$TTL  604800
@  IN  SOA  linuxman.local. root.linuxman.local. (
   20190511  ;Serial
  604800 ; Refresh
   86400 ; Retry
   2419200 ; Expire
  604800 )  ; Negative Cache TTL
; NS Records
@  IN  NS  ns.

; A Records
5  IN  PTR  @
5  IN  PTR  ns.
2    IN  PTR  www.
3  IN  PTR  mail.

4. Next lets modify the named.conf.local to add our Reverse Lookup Zone.

sudo vim named.conf.local

Add the reverse lookup zone using the first 3 octets of the subnet reversed as shown:

zone "" {
  type master;
  notify no;
  file "/etc/bind/db.172";

Named Options

1. Lets add a Forwarder into the options file by editing named.conf.options. Uncomment the Forwarders option and add your preferred DNS server to forward queries to.

forwarders {;


1. Lets apply changes and start testing DNS Queries with our Windows client.

sudo systemctl reload bind9.service

Check for any errors on reload

sudo systemctl status bind9.service

2. Set the client's DNS server to our new DNS server and pull up a command prompt.

3. Lets start by running nslookup on all records in the Forward Lookup Zone.

NS Records

For NS Records you need to use the -q=NS as an argument in nslookup.

CNAME Records

For CNAME Records you need to use the -q=CNAME as an argumment in nslookup. We will check for CNAME Records on tech.linuxman.local.

A Records

NOTE: For TXT records you need to use the -q=TXT argument in nslookup.

SPF Records

DKIM Records

DMARC Records

SOA Records

For SOA Records you need to use the -q=SOA as an argument in nslookup.

MX Records

For MX Records you need to use the -q=MX as an argument in nslookup.

4. Now we will check our PTR Records for the IP Addresses that have one.


PTR Records

5. Lastly we will test to see if unknown queries are forwarding to our DNS server of choice.

This concludes a pretty basic but working DNS Server for your network. For more information on Bind9 you can reference the man pages or visit Ubuntu's Documentation -> BIND9ServerHowTo

If you are interested in learning more about Linux, i highly recommend this book on Linux Administration