Configure DNS Server Using BIND (Debian)

Configure DNS Server Using BIND (Debian)

Configuring a reliable, internal Domain Name System (DNS) is a foundational step in establishing a stable network infrastructure. BIND9 (Berkeley Internet Name Domain) remains the industry-standard software component for this task on Linux platforms. This guide provides a comprehensive walkthrough for deploying, configuring, and testing BIND9 on a Debian-based server to operate as both a recursive resolver and an authoritative DNS server for your infrastructure.

Environment Overview

Before modifying configuration files, establish the parameters of your network topology. This deployment uses the following infrastructure values:

  • Domain: mylab.local, techncloud.xyz
  • Network: 172.20.0.0/16 (utilizing subnets 172.20.5.0/24 and 172.20.6.0/24)
  • DNS Server: ns1.mylab.local (172.20.6.184)
  • Purpose: Internal recursive and authoritative DNS server

Installation

Update your package index and install BIND9 along with its essential utilities and documentation packages:

# Update package list
sudo apt update

# Install BIND9 and utilities
sudo apt install bind9 bind9utils bind9-doc dnsutils -y

# Check installation
named -v

1. Main Configuration File: /etc/bind/named.conf.options

On Ubuntu and Debian systems, the primary configuration is modularized across multiple files. Define global operation parameters by modifying the options file:

sudo nano /etc/bind/named.conf.options
options {
    directory "/var/cache/bind";

    // Listen on all interfaces
    listen-on port 53 { any; };
    listen-on-v6 { any; };

    // Allow queries from any source
    allow-query { any; };
    
    // Enable recursion for internal queries
    recursion yes;
    allow-recursion { any; };

    // Forwarders (optional - use Google DNS or your ISP's DNS)
    forwarders {
        8.8.8.8;
        8.8.4.4;
    };

    // DNSSEC validation
    dnssec-validation auto;

    // Other settings
    auth-nxdomain no;    # conform to RFC1035
};

2. Zone Configuration: /etc/bind/named.conf.local

Declare the forward and reverse lookup zones for your domains inside the local configuration file:

sudo nano /etc/bind/named.conf.local
// Forward zone for local domain
zone "mylab.local" {
    type master;
    file "/etc/bind/zones/db.mylab.local";
    allow-update { none; };
};

// Forward zone for public domain
zone "techncloud.xyz" {
    type master;
    file "/etc/bind/zones/db.techncloud.xyz";
    allow-update { none; };
};

// Reverse zone for 172.20.5.0/24 subnet
zone "5.20.172.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.172.20.5";
    allow-update { none; };
};

// Reverse zone for 172.20.6.0/24 subnet
zone "6.20.172.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.172.20.6";
    allow-update { none; };
};

3. Create Zone Files Directory

To keep configurations organized, isolate the database files within a dedicated subdirectory and assign correct service permissions:

# Create directory for zone files
sudo mkdir -p /etc/bind/zones

# Set proper ownership
sudo chown bind:bind /etc/bind/zones

4. Forward Zone File (Local): /etc/bind/zones/db.mylab.local

Create the file responsible for translating local hostnames to IPv4 addresses:

sudo nano /etc/bind/zones/db.mylab.local
$TTL 86400
@   IN  SOA     ns1.mylab.local. admin.mylab.local. (
            2024102301  ; Serial (YYYYMMDDNN)
            3600        ; Refresh
            1800        ; Retry
            604800      ; Expire
            86400       ; Minimum TTL
)

; Name servers
@       IN  NS      ns1.mylab.local.

; A records
ns1             IN  A       172.20.6.184
server1         IN  A       172.20.6.187
server2         IN  A       172.20.6.120
workstation1    IN  A       172.20.6.103
printer         IN  A       172.20.5.160

; CNAME records
www             IN  CNAME   server1
mail            IN  CNAME   server2

; TXT Records
info            IN  TXT     "Contact: admin@mylab.local"

5. Forward Zone File (Public): /etc/bind/zones/db.techncloud.xyz

Configure the forward lookup parameters for your secondary domain space:

sudo nano /etc/bind/zones/db.techncloud.xyz
$TTL 3600
@   IN  SOA     ns1.techncloud.xyz. admin.techncloud.xyz. (
            2024102301  ; Serial
            7200        ; Refresh
            3600        ; Retry
            1209600     ; Expire
            3600        ; Minimum TTL
)

; Name servers
@       IN  NS      ns1.techncloud.xyz.

; A records for nameservers
ns1     IN  A       139.185.54.150

; Main Records
@       IN  A       203.0.113.10
www     IN  A       203.0.113.10
web     IN  A       203.0.113.10

6. Reverse Zone File: /etc/bind/zones/db.172.20.5

Establish pointer (PTR) resource records to resolve the 172.20.5.0/24 subnet IP addresses back to canonical hostnames:

sudo nano /etc/bind/zones/db.172.20.5
$TTL 86400
@   IN  SOA     ns1.mylab.local. admin.mylab.local. (
            2024102301  ; Serial
            3600        ; Refresh
            1800        ; Retry
            604800      ; Expire
            86400       ; Minimum TTL
)

; Name server
@       IN  NS      ns1.mylab.local.

; PTR records
160     IN  PTR     printer.mylab.local.

7. Reverse Zone File: /etc/bind/zones/db.172.20.6

Configure the pointer entries for network devices operating inside the 172.20.6.0/24 block:

sudo nano /etc/bind/zones/db.172.20.6
$TTL 86400
@   IN  SOA     ns1.mylab.local. admin.mylab.local. (
            2024102301  ; Serial
            3600        ; Refresh
            1800        ; Retry
            604800      ; Expire
            86400       ; Minimum TTL
)

; Name server
@       IN  NS      ns1.mylab.local.

; PTR records
184     IN  PTR     ns1.mylab.local.
187     IN  PTR     server1.mylab.local.
120     IN  PTR     server2.mylab.local.
103     IN  PTR     workstation1.mylab.local.

8. File Permissions

Secure the newly created database files by adjusting system ownership patterns and restrictive read/write execution permissions:

# Set ownership for zone files
sudo chown bind:bind /etc/bind/zones/db.mylab.local
sudo chown bind:bind /etc/bind/zones/db.techncloud.xyz
sudo chown bind:bind /etc/bind/zones/db.172.20.5
sudo chown bind:bind /etc/bind/zones/db.172.20.6

# Set permissions (read-write for owner, read for group)
sudo chmod 640 /etc/bind/zones/db.mylab.local
sudo chmod 640 /etc/bind/zones/db.techncloud.xyz
sudo chmod 640 /etc/bind/zones/db.172.20.5
sudo chmod 640 /etc/bind/zones/db.172.20.6

9. Verification Commands

To avoid runtime service failures, explicitly check the structural validity of both your primary options file and your target zone records before initialization:

Check Configuration Syntax

# Check main configuration
sudo named-checkconf

# Check forward zones
sudo named-checkzone mylab.local /etc/bind/zones/db.mylab.local
sudo named-checkzone techncloud.xyz /etc/bind/zones/db.techncloud.xyz

# Check reverse zones
sudo named-checkzone 5.20.172.in-addr.arpa /etc/bind/zones/db.172.20.5
sudo named-checkzone 6.20.172.in-addr.arpa /etc/bind/zones/db.172.20.6

Expected output for valid zones:

zone mylab.local/IN: loaded serial 2024102301
OK

10. Service Management

Once syntax validation passes, restart the underlying system service and ensure execution persistency across system boot sequences:

# Restart BIND after configuration
sudo systemctl restart bind9

# Check service status
sudo systemctl status bind9

# Enable BIND to start on boot
sudo systemctl enable bind9

# View logs
sudo journalctl -u bind9 -f

# Reload zones without restart
sudo rndc reload

11. Firewall Configuration (UFW)

Ensure network firewalls permit active communication through the standardized transport ports allocated for DNS requests:

# Allow DNS traffic
sudo ufw allow 53/tcp
sudo ufw allow 53/udp

# Check firewall status
sudo ufw status

# If firewall is inactive, enable it
sudo ufw enable

12. Configure System to Use Local DNS

Modify the local resolving agent to prioritize the newly created instance for handling system-wide resolution loops:

Edit the system’s DNS configuration:

sudo nano /etc/systemd/resolved.conf

Add or modify:

[Resolve]
DNS=127.0.0.1
FallbackDNS=8.8.8.8

Restart systemd-resolved:

sudo systemctl restart systemd-resolved

13. Testing DNS Resolution

Execute functional end-to-end lookups against the localized service loop to prove functionality across both vector planes:

Forward Lookups (hostname → IP)

dig @localhost ns1.mylab.local
dig @localhost server1.mylab.local
dig @localhost printer.mylab.local
dig @localhost www.techncloud.xyz

# Or using nslookup
nslookup server1.mylab.local localhost

# Using host command
host server1.mylab.local localhost

Reverse Lookups (IP → hostname)

dig @localhost -x 172.20.6.184
dig @localhost -x 172.20.5.160

# Or using nslookup
nslookup 172.20.6.187 localhost

# Using host command
host 172.20.6.187 localhost

Test from External Host

# Replace with your DNS server's IP
dig @172.20.6.184 server1.mylab.local
nslookup www.techncloud.xyz 172.20.6.184

14. Adding New Hosts

When extending network boundaries, maintain structural accuracy by following a sequence-based change process across zone sets:

Step 1: Add Forward DNS Entry

Edit /etc/bind/zones/db.mylab.local:

sudo nano /etc/bind/zones/db.mylab.local

Add:

newserver     IN  A       172.20.6.200

Step 2: Add Reverse DNS Entry

Edit /etc/bind/zones/db.172.20.6:

sudo nano /etc/bind/zones/db.172.20.6

Add:

200     IN  PTR     newserver.mylab.local.

Step 3: Increment Serial Number

In both zone files, update:

2024102301  →  2024102302

Step 4: Verify and Reload

sudo named-checkzone mylab.local /etc/bind/zones/db.mylab.local
sudo named-checkzone 6.20.172.in-addr.arpa /etc/bind/zones/db.172.20.6
sudo rndc reload

15. Common Issues and Solutions

Review these operational isolation measures to resolve frequent deployment errors:

Issue: BIND won’t start

# Check configuration
sudo named-checkconf

# Check zone files
sudo named-checkzone mylab.local /etc/bind/zones/db.mylab.local

# View detailed errors
sudo journalctl -u bind9 -n 50 --no-pager

# Check for syntax errors in logs
sudo tail -f /var/log/syslog | grep named

Issue: DNS not accessible from outside

# Check if listening on all interfaces
sudo ss -tulpn | grep :53
# Should show: 0.0.0.0:53

# Check firewall
sudo ufw status

# Verify listening addresses in config
sudo named-checkconf -p | grep listen-on

Issue: Permission denied errors

# Fix ownership
sudo chown -R bind:bind /etc/bind/zones/

# Fix permissions
sudo chmod 755 /etc/bind/zones/
sudo chmod 640 /etc/bind/zones/db.*

Issue: Changes not taking effect

# Increment serial number in zone file
# Then reload
sudo rndc reload

# Or restart service
sudo systemctl restart bind9

# Clear local DNS cache
sudo systemd-resolve --flush-caches

Issue: SELinux/AppArmor blocking BIND

# Check AppArmor status (Ubuntu uses AppArmor, not SELinux)
sudo aa-status | grep named

# If issues persist, check AppArmor logs
sudo journalctl -xe | grep apparmor

# Temporarily disable AppArmor for bind (not recommended for production)
sudo aa-complain /usr/sbin/named

17. Monitoring and Maintenance

To preserve long-term operational health, implement structured diagnostic oversight strategies:

View Query Statistics

# View query statistics
sudo rndc stats
sudo cat /var/cache/bind/named.stats

Monitor DNS Queries in Real-time

# Enable query logging
sudo rndc querylog on

# View queries
sudo tail -f /var/log/syslog | grep named

Backup Configuration

# Backup all BIND configuration
sudo tar -czf bind-backup-$(date +%Y%m%d).tar.gz /etc/bind/

Deploying a local BIND9 infrastructure provides full administrative control over your network resolution path, improving internal latency and scaling capacity. By following proper zone file documentation habits, updating serial tokens linearly, and integrating systematic maintenance processes, your DNS system will remain highly resilient and performant.

Leave a Reply

Your email address will not be published. Required fields are marked *