Setup a DNS Server on VPS with BIND

By Raman Kumar

Updated on Oct 08, 2024

In this tutorial, we'll explain how to Setup a DNS server on VPS with BIND. 

We'll walk through the process of setting up and configuring BIND (Berkeley Internet Name Domain), one of the most popular DNS server software, on your VPS. BIND allows you to manage your custom domain names and provide DNS services for those domains.

BIND (Berkeley Internet Name Domain) is the most widely used open-source DNS (Domain Name System) software, responsible for translating domain names into IP addresses. It serves as a DNS server for authoritative name servers, recursive resolvers, and DNS caching. BIND is highly configurable, supports DNSSEC for secure DNS queries, and allows advanced zone management, making it a popular choice for managing custom domains and DNS infrastructure on the internet.

Prerequisites:

  • A VPS running Ubuntu or AlmaLinux (this guide uses Ubuntu 24.04).
  • Root access or a user with sudo privileges.
  • A domain name that you want to configure DNS for.

Setup a DNS Server on VPS with BIND

Step 1: Update Your Server

First, ensure that your server's package lists and installed software are up to date.

sudo apt update && sudo apt upgrade -y

Step 2: Install BIND9

On most Linux systems, BIND9 is the version included in the package manager.

sudo apt install bind9 bind9utils bind9-doc -y

After the installation, BIND will automatically start. You can check its status with:

sudo systemctl status bind9

Step 3: Configure BIND9

The BIND configuration files are located in /etc/bind/. We'll mainly be working with the following files:

  • /etc/bind/named.conf.options: Global configuration options.
  • /etc/bind/named.conf.local: Local domain zone configuration.
  • /etc/bind/db.local: Template for the forward zone file.

3.1 Configuring Global Options

Open the named.conf.options file to define global DNS server settings.

sudo nano /etc/bind/named.conf.options

Uncomment the forwarders section and add Google or your preferred DNS resolvers for external queries:

options {
    directory "/var/cache/bind";

    forwarders {
        8.8.8.8;   // Google's DNS
        8.8.4.4;
    };

    dnssec-validation auto;
    auth-nxdomain no;
    listen-on-v6 { any; };
};

Save and exit the file.

3.2 Creating a Forward Zone File

Next, you'll create a zone file for your domain to point domain names to IP addresses.

Open named.conf.local to configure your custom zone.

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

Add the following configuration for your forward zone:

zone "example.com" {
    type master;
    file "/etc/bind/db.example.com";
};

Now, create a zone file based on the default db.local file.

sudo cp /etc/bind/db.local /etc/bind/db.example.com

Edit the zone file to reflect your domain and server IP.

sudo nano /etc/bind/db.example.com

Update the following fields:

  • Replace localhost. with your domain (e.g., ns1.example.com.).
  • Replace 127.0.0.1 with your VPS's public IP address.
  • Set the TTL (Time-to-Live) and serial number.

Example:

;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     ns1.example.com. admin.example.com. (
                      2         ; Serial
                 604800         ; Refresh
                  86400         ; Retry
                2419200         ; Expire
                 604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.example.com.
ns1     IN      A       192.0.2.1
www     IN      A       192.0.2.1

Save and exit the file.

3.3 Creating a Reverse Zone File

A reverse zone file maps IP addresses to domain names.

Edit named.conf.local to add a reverse zone:

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

Add the following block for reverse lookup:

zone "2.0.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.0.2";
};

Create the reverse zone file:

sudo cp /etc/bind/db.127 /etc/bind/db.192.0.2

Edit the reverse zone file:

sudo nano /etc/bind/db.192.0.2

Replace the contents with:

;
; BIND reverse data file for 192.0.2.0/24
;
$TTL    604800
@       IN      SOA     ns1.example.com. admin.example.com. (
                      1         ; Serial
                 604800         ; Refresh
                  86400         ; Retry
                2419200         ; Expire
                 604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.example.com.
1       IN      PTR     example.com.

Save and exit the file.

Step 4: Test Your Configuration

Before restarting BIND, it’s a good practice to test the configuration for syntax errors:

sudo named-checkconf
sudo named-checkzone example.com /etc/bind/db.example.com
sudo named-checkzone 2.0.192.in-addr.arpa /etc/bind/db.192.0.2

If no errors are reported, restart BIND to apply the changes:

sudo systemctl restart bind9

Step 5: Open DNS Port 53 on Your VPS

Ensure that port 53 (DNS) is open on your firewall:

sudo ufw allow 53/tcp
sudo ufw allow 53/udp

Reload the firewall:

sudo ufw reload

Step 6: Set Up Glue Records with Your Domain Registrar

To point your domain to your VPS DNS server, you need to configure glue records with your domain registrar. These glue records connect your domain with the nameservers you just set up.

In the registrar's DNS settings, add:

ns1.example.com pointing to 192.0.2.1 (VPS IP).
ns2.example.com (optional, but recommended) pointing to another IP, if available.

Step 7: Verify DNS Resolution

After setting up glue records, use a tool like dig to test your DNS setup:

dig @192.0.2.1 example.com

You should see your VPS's IP address in the response.

Conclusion

You've successfully set up a DNS server with BIND on your VPS. Your DNS server can now manage your domain, and you can configure additional records or zones as needed.