How to Install and Configure a BIND9 DNS Server on Ubuntu

Setting up your own DNS server is one of the best ways to truly understand how the internet works behind the scenes. DNS, or Domain Name System, is like the phonebook of the internet — it translates human-friendly domain names into machine-readable IP addresses. 

Whether you're a network engineer or a Mulesoft Architect, getting hands-on with DNS basics is essential. In this tutorial, we'll walk through installing BIND9 (Berkeley Internet Name Domain version 9), the most widely used open-source DNS server software, on an Ubuntu system. Using BIND9, we can quickly spin up a lab environment to create our own custom domains, simulate real-world DNS scenarios, and gain a deeper understanding of how network name resolution really works.


Prerequisites and Lab setup description

Our lab setup will consist of three servers:
  • ns1 - This will host our bind9 DNS server
  • node-01 - An Ubuntu server that we’ll use as DNS client
  • node-02 - Another Ubuntu server to be used as DNS client.
With this setup, we will configure node-01 and node02 to use our ns1 bind server as their DNS server. We’ll then test how we can ask the IP address of node-02 from node-01 and viceversa.


Step 1: Update Our System

First, we sharpen our tools. We update the system to make sure everything is fresh.

sudo apt update
sudo apt upgrade -y

This gives us the latest security patches and prepares us for a smooth installation.


Step 2: Install BIND9

Now, we install the Bind9 server

sudo apt install bind9 bind9utils bind9-doc -y
  • bind9 is the core server.
  • bind9utils gives us helpful tools.
  • bind9-doc gives us clear documentation for deeper learning.


Step 3: Start and Enable the Service

We want BIND9 to rise up automatically with the system.

sudo systemctl start named
sudo systemctl enable named

We can check if it is alive and working:

sudo systemctl status named

If we see "active (running)" in green, we are on the right path.


Step 4: Configure the DNS Server

Our server needs a purpose. We will give it a zone to manage. For that, we open the main configuration file:

sudo vi /etc/bind/named.conf.local

Remove all the content of the file and add a simple zone block:

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

This tells BIND9 that it controls the "mulesoft.local" domain.. There are two arguments for the 
mulesoft.local file
  • type master indicates this is a primary DNS server for the zone.
  • file "/etc/bind/db.mulesoft.local" this indicates the location of the zone file that we’re going to configure next.

Step 5: Create a Zone File

Now, we give life to the domain with a zone file. Normally, by convention, the file of a zone starts with db. and then the name of the domain. We start by copying the file content from the db.local template:

sudo cp /etc/bind/db.local /etc/bind/db.mulesoft.local

We open it:

sudo vi /etc/bind/db.mulesoft.local

We edit it carefully:

$TTL    300
@ IN SOA ns1.mulesoft.local. admin.mulesoft.local. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.mulesoft.local.
ns1 IN A 172.31.24.209
node-01 IN A 172.31.23.49
node-02 IN A 172.31.42.6

Where:

  • First we’ve got the mandatory field $TTL 300 - This sets the default TTL in seconds for every record in the zone, telling the resolvers how long to cache responses.
  • Then, the next line defines the Start of Authority record (SOA), specifying that ns1.mulesoft.local is the primary nameserver for this zone. The second field, admin.mulesoft.local is actually an email address with the @ symbol replaced by a dot. So, if it was a normal email address, it would be admin@mulesoft.local. The numbers in parentheses represent:
    • Serial - serial number which increments with each zone file change.
    • Refresh - specifies how often a secondary nameserver will check for updates
    • Retry - specifies how long the server waits to try again if the refresh fails
    • Expire - this is used when secondary servers discard the data if no successful refresh occurs.
    • Negative Cache TTL - How long will Resolvers cache a non existing domain or other negative responses.
  • After that we need the NS records of the zone, that is the nameservers that actually resolve the domain names for this zone. In here:
    • @ points to the domain itself.
    • Then, the IN NS and the hostname of the server ns1.example.com. This tells resolvers that ns1.mulesoft.localis the authoritative nameserver for this zone. This record, in combination with the SOA record, completes the definition of which server holds the authoritative data for mulesoft.local
  • The combination of TTL, SOA record and NS record gives us the basic framework for our DNS zone file. However, this is not enough, because we still haven’t provided a glue record pointing to an actual IP. Without that, queries will get lost since there’s no way to find the IP address for ns1.mulesoft.local
  • To include the glue record, we’ll add the following line:
ns1     IN      A       172.31.23.32

This tells DNS that our nameserver, ns1.example.com, is at the IP address of this server (in here, this is 192.168.1.10). 


Lastly, we will add the A records to resolve the IP addresses of our two DNS clients. 

node-01 IN      A       172.31.42.5
node-02 IN A 172.31.42.6


Step 6: Check the Configuration

We must be precise. We check the syntax:

sudo named-checkconf

Then, we check the zone file:

sudo named-checkzone mulesoft.local /etc/bind/db.mulesoft.local


If there are no errors, we can move forward with confidence.


Step 7: Restart BIND9

We breathe life into the new configuration:

sudo systemctl restart named

Now, the server knows its new role.


Step 8: Set up the DNS clients

Now, let’s set up our two servers node-01 and node-02 to use our bind9 as DNS server for their DNS queries. Login to these servers and follow the next steps in both.

The DNS client configuration of an Ubuntu server is located at /etc/resolv.conf. This file contains the DNS servers that this server will use to send the domain name queries. Create a copy of this file and save it in a secure location, just in case anything goes wrong so that you can always restore the initial status.

sudo vi /etc/resolv.conf

Remove the content of the original file and add the following line:

nameserver 172.31.24.209

Replace the IP address with the IP address of your Bind9 server.


This tells the node-01 and node-02 servers to use Bind9 as DNS server to resolve the queries.


Step 9: Test the Server

Let us test with dig, to see if our DNS server works. From node-01 or node-02 run the command:

dig node-01.mulesoft.local
dig node-02.mulesoft.local

We should see a clean response with our server’s IP addresses.




Summary

As you’ve seen, setting up a BIND9 DNS server on Ubuntu is a straightforward process that only takes a few simple steps. With just a basic installation and a few configuration tweaks, you can have a fully functional DNS server up and running in no time. This kind of lab setup is perfect for experimenting, learning, and even preparing for larger production deployments. Understanding and practicing with BIND9 not only demystifies how DNS works but also gives us valuable skills that are fundamental for any network or systems administrator.
Previous Post Next Post