How to Setup and configure Bind as a Private Network DNS Server

install and Config Bind as a Private Network DNS Server

Introduction

Bind (Berkeley Internet Name Domain) is an open source software that implements the Domain Name System (DNS) protocols for the Internet. It is the most widely used DNS software on the Internet.

Setting up Bind as a private network DNS server provides a number of benefits:

  • Allows you to resolve hostnames to IP addresses for machines on your private network without relying on an external DNS server
  • Gives you greater control and customization over your private DNS namespace
  • Improves security and privacy by avoiding DNS queries going to external servers
  • Enhances reliability by reducing dependence on external DNS servers

In this guide, we will cover the steps required to install, configure and set up Bind as a caching and authoritative DNS server on a private network.

Prerequisites

Before starting with the Bind setup, we need to ensure we have the following:

  • A Linux server with a fresh install of Linux distribution like Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8 etc.
  • The Linux machine should have a static IP address and network connectivity on the private network.
  • A domain name you want to use for your private network. This will act as the root domain in your Bind configuration. For example, if you choose home.net as your domain, your DNS server will be responsible for home.net and any sub-domains under it like server1.home.netprinters.home.net etc.

Installing Bind

Bind is available in the default repositories for most Linux distributions.

Ubuntu/Debian

On Ubuntu or Debian, install Bind using apt:

$ sudo apt update
$ sudo apt install bind9 bind9utils

This will install Bind 9 and some utilities like dig, nslookup etc.

CentOS/RHEL

On CentOS or RHEL, install Bind using yum:

$ sudo yum update
$ sudo yum install bind bind-utils

Again this will install bind9 packages and utilities.

Verifying Installation

To verify that Bind is installed:

$ dig -v

This should display the Bind version that is now installed:

;; BIND version: 9.11.3-1ubuntu1.2-Ubuntu

This confirms that Bind is installed and ready to be configured.

The rest of the guide can then dive into the configuration as outlined. Let me know if you would like any other details added to the installation section!

Basic Bind Configuration

The main Bind configuration files are:

  • /etc/bind/named.conf – The main Bind config file which includes all other config files
  • /etc/bind/named.conf.options – Global options for Bind
  • /etc/bind/named.conf.local – Configuration for local DNS server itself
  • /etc/bind/db.root – Root hints file pointing to DNS root servers
  • /var/cache/bind – Working directory for Bind with cache and other data

Let’s take a look at some key options we need to configure in these files.

In named.conf.options:

options {
        directory "/var/cache/bind";
        
        forwarders {
                8.8.8.8; 
                8.8.4.4;
        };
        allow-query { any; };
        
        dnssec-validation auto;
        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
};

This sets the Bind working directory, configures Google’s public DNS servers as forwarders for external domain resolution, allows queries from any IP address, enables DNSSEC validation and listens on both IPv4 and IPv6 addresses.

In named.conf.local, configure your private root zone and local DNS server details:

// Define root zone 
zone "home.net" IN {
        type master;
        file "/etc/bind/db.home.net";
};
// Declare local DNS server itself
zone "dns1.home.net" {
        type master;
        file "/etc/bind/db.dns1.home.net";
};

This defines home.net as the root zone configured as a master zone, meaning our DNS server will be the authoritative server for this domain. The zone details will be loaded from the file db.home.net.

We also add a zone declaration for our local DNS server name dns1.home.net with its details in db.dns1.home.net file.

Configuring the Root Zone

Next, we need to define our root zone home.net details in the db.home.net file:

$TTL    604800
@       IN      SOA     dns1.home.net. admin.home.net. (
                              3         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      dns1.home.net.
@       IN      A       192.168.1.100

This sets the default TTL, SOA record defining properties for the zone, our DNS server as the Name Server for home.net and its IP address.

For the local DNS server, the db.dns1.home.net file:

$TTL    604800
@       IN      SOA     dns1.home.net. admin.home.net. (
                              3         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      dns1
@       IN      A       192.168.1.100

This configures the SOA and A record for our local DNS server.

Configuring Recursive Forwarding

In a private network, the local DNS server may not be able to resolve all hostnames to IP addresses by itself. In that case, we need to configure recursive forwarding to send external DNS queries to public DNS resolvers.

This is defined in named.conf.options earlier using the forwarders statement. Here we configure Google’s public DNS servers 8.8.8.8 and 8.8.4.4 to handle external queries.

With this, if our DNS server receives a query it cannot resolve from its local zones, it will forward it recursively to the external DNS servers to find the answer.

Securing the DNS Server

Since the DNS server provides critical network services, we need to secure it just like any other server machine. Some key steps include:

  • Use a dedicated non-root user account for Bind process
  • Restrict access to Bind config files and folders
  • Configure firewall rules to allow only DNS traffic on port 53 for both UDP and TCP
  • Enable SElinux or AppArmor for additional security
  • Use TLS for encrypting DNS traffic if needed
  • Setup secure dynamic updates using TSIG if clients need to dynamically update DNS records
  • Enable DNSSEC validation for enhanced security of DNS data
  • Configure rate-limiting in named.conf.options to prevent DNS amplification attacks

Here are some firewall rules to allow only DNS traffic:

# Allow DNS queries 
$ iptables -A INPUT -p udp --dport 53 -j ACCEPT
$ iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# Allow zone transfers
$ iptables -A INPUT -p tcp --dport 53 -m state --state ESTABLISHED -j ACCEPT
# Allow responses 
$ iptables -A OUTPUT -p udp --sport 53 -j ACCEPT
$ iptables -A OUTPUT -p tcp --sport 53 -j ACCEPT 

Testing the Setup

Once Bind is installed and base configuration is done, we can start the service and verify it is working properly.

On Systemd systems, run:

# systemctl start bind9
# systemctl enable bind9

On init.d systems, run:

# service bind9 start
# chkconfig bind9 on

Check status using:

# systemctl status bind9 
# service bind9 status

The Bind service should be active and running.

Now we can test lookups using dignslookup or host commands:

# dig @192.168.1.100 home.net
# nslookup dns1.home.net 192.168.1.100
# host google.com 192.168.1.100

The first query should return SOA and NS records for home.net. Second one should show the A record for dns1.home.net. Last one is a recursive query for google.com which should return the external IP address after forwarding to Google DNS.

If all of these work fine, your Bind DNS server is configured properly for basic DNS resolution and forwarding!

Configuring Zones for Local Networks

At this point, our DNS server only knows about the root home.net zone with the local DNS server details. We need to add more zones to provide naming resolution for our private network.

Let’s assume we have the network 192.168.1.0/24 with some hosts defined:

  • 192.168.1.100 – Our DNS server itself dns1.home.net
  • 192.168.1.101 – A web server named web1.home.net
  • 192.168.1.102 – A database server db1.home.net
  • 192.168.1.103 – A file server files.home.net

We can add each of these servers as an A record within the home.net zone itself in db.home.net:

web1     IN  A 192.168.1.101
db1      IN  A 192.168.1.102 
files    IN  A 192.168.1.103

After reloading the Bind service, we can now lookup these hosts and get back the IP address:

# dig @192.168.1.100 web1.home.net
# nslookup db1.home.net 192.168.1.100
# host files.home.net 192.168.1.100

Instead of adding all hosts in the root zone, we can also configure a new separate zone for our internal network.

Add this zone definition to named.conf.local:

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

Here we define a reverse lookup zone for IP addresses under 192.168.1.0/24 mapped to the .arpa domain.

The zone file /etc/bind/db.192:

$TTL    604800
@       IN      SOA     home.net. admin.home.net. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                          86400 )       ; Negative Cache TTL
;
@       IN      NS      dns1.
100     IN      PTR     dns1.home.net.  
101     IN      PTR     web1.home.net.
102     IN      PTR     db1.home.net.
103     IN      PTR     files.home.net.

This defines the reverse mapping from IP addresses to names for hosts in 192.168.1.0/24 network.

After reloading Bind, reverse lookups will work:

# dig -x 192.168.1.101 @192.168.1.100
# nslookup -query=PTR 192.168.1.102 192.168.1.100
# host 192.168.1.103 192.168.1.100

Similar additional zone files can be added for any other private subnets and hosts configured on the network.

This provides an authoritative local DNS service without relying on any external DNS servers.

Dynamic Zone Updates

In larger environments, maintaining DNS records for a changing infrastructure can be challenging. Bind provides two ways of dynamically updating DNS zones – Dynamic DNS (DDNS) and DNSSEC signed updates.

With DDNS, clients can directly update their DNS records within a zone by sending special UPDATE requests to the DNS server. This is simpler to setup but not secure.

DNSSEC signed updates use Transaction Signatures (TSIG) to cryptographically sign the update requests. The DNS server only accepts updates with a valid signature.

Here is an example of enabling DDNS updates for clients in subnet 192.168.1.0/24:

In named.conf.local:

zone "home.net" {
     type master;
     allow-update { 192.168.1/24; };
     file "/etc/bind/db.home.net";
}; 

The allow-update option enables updates from the subnet.

Client machines can use nsupdate command to add/modify/delete records. For example:

# nsupdate
> update add web2.home.net 3600 A 192.168.1.105
> send

This will add an A record for web2.home.net. Records can be deleted by specifying their name and ttl value only.

For TSIG signed updates, both server and clients share a common TSIG key. The key can be generated using dnssec-keygen. Clients sign the UPDATE packet with the TSIG signature.

On the server, the named.conf specifies the TSIG key and enabled signed updates:

key "tsig-key" {
     algorithm hmac-sha256;
     secret "b3BlbnNlc2FtZTAwMA=="; 
};
  
zone "home.net" {
    type master;
    allow-update { key tsig-key; };
    ...
}

Clients can use the same key for signing update requests. This ensures only authorized hosts can dynamically update their DNS records.

Split-Horizon DNS

Sometimes private internal DNS servers may return different results than external public DNS to provide split DNS configuration. This is known as split-horizon DNS.

For example, webserver.company.com internally could resolve to the private IP 192.168.1.101 whereas externally it resolves to the public IP 1.2.3.4.

We can achieve this with Bind by defining company.com zone both as a forward zone for public IPs and as a separate reverse zone for internal IPs.

In named.conf.local:

// Forward Zone
zone "company.com" {
    type master;
    file "/etc/bind/db.company.com.public";
}
// Reverse Zone 
zone "1.168.192.in-addr.arpa"{ 
   type master;
   file "/etc/bind/db.company.com.private";
}

This allows defining different A records for webserver.company.com in the public and private zone files. The BIND server can be configured to listen on different network interfaces to serve the correct data.

Split DNS is useful for security, isolation and policy control between public vs private DNS data.

Caching and Prefetching

Enabling caching and prefetching on the DNS server can improve performance. By default, Bind caches query results for better resolution speed.

We can tune the cache TTL values in named.conf.options:

dnssec-validation auto;
recursion yes; 
cache-size 500m;
cache-file "/var/cache/bind/db.cache"; 
prefetch 2;
prefetch-key no-edns;
dnssec-accept-expired yes;
max-cache-ttl 600;        # 10 minutes 
max-ncache-ttl 90;        # 1.5 minutes

This enables caching of up to 500MB data to disk, sets prefetch level, cache TTL limits and allows using expired records while refreshing DNSSEC data.

Prefetching improves resolution for sibling domains by proactively querying dependent records.

Logging and Monitoring

Like any server, the DNS server should be monitored closely. Bind provides good logging capabilities which can be sent to a central log server.

In named.conf.options:

logging {
        channel query_log {
                file "/var/log/query.log" versions 3 size 20m;
                severity info;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        category queries { query_log; };
};

Key metrics to monitor are:

  • Query rates and response times
  • Cache utilization and hit ratios
  • DNSSEC validation errors
  • Failed updates or zone transfers
  • Rate-limiting events or access violations
  • Network errors and timeouts

Integrating the DNS server with a monitoring system provides important visibility into DNS operations and performance.

Testing and Validation

Once the DNS server is configured and deployed, we should thoroughly test it to detect any issues:

  • Use DNS lookup tools like dignslookup and host to test different record lookups
  • Perform reverse lookups to confirm PTR records are defined properly
  • Verify zone transfers are working securely for secondary servers
  • Test dynamic updates by adding/deleting records using nsupdate
  • Check split-horizon configurations are returning correct internal and external results
  • Confirm DNSSEC validation is working for signed zones
  • Load test the DNS server using tools like dnsperf and namebench
  • Check logs and monitors during testing to catch any errors
  • Scan for security issues like vulnerable software versions, encryption strength
  • Perform a penetration test to identify and fix vulnerabilities

Thorough testing and validation of the DNS server reduces risk and provides confidence in the availability, performance, security and correctness of the DNS infrastructure.

Conclusion

In this detailed guide, we covered how to install, configure and set up Bind 9 as a local DNS server for private networks.

We installed the Bind packages, configured the base named.conf files, set up forwarding, access control lists and other options. We added primary and reverse lookup zones for the internal network domains and hosts. Dynamic updates, split-horizon DNS, caching, logging and monitoring were also configured.

Deploying Bind as a local DNS server provides centralized naming services for your private environment. It offers greater control, customization, privacy, security and autonomy over your private DNS infrastructure vs relying solely on external providers.

Of course, hardened security, robust monitoring, testing, redundancy and proper maintenance is required to keep your DNS services running reliably. But with its flexible configurations, Bind can meet the local DNS requirements for even large private networks and custom deployments.

LEAVE A COMMENT