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

Posted on

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

How to Setup and Configure 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’s the most widely used DNS software globally.

Setting up Bind as a private network DNS server offers several benefits:

  • Centralized Name Resolution: Manage hostnames and IP addresses in one central location.
  • Improved Speed and Performance: Reduce latency by caching DNS records locally.
  • Increased Security: Control DNS queries and prevent unauthorized access.
  • Internal Domain Management: Create and manage internal domain names without relying on external registrars.
  • Offline Functionality: Continue resolving internal names even without an internet connection.

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

Prerequisites

Before starting the Bind setup, ensure you have the following:

  • A Linux server (e.g., Ubuntu, Debian, CentOS, RHEL).
  • Root or sudo privileges on the server.
  • A basic understanding of networking concepts.
  • A static IP address assigned to the server.

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 installs Bind 9 and utilities like dig and nslookup.

CentOS/RHEL

On CentOS or RHEL, install Bind using yum:

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

This installs the 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.

Basic Bind Configuration

The main Bind configuration files are:

  • /etc/bind/named.conf.options: Global options and settings.
  • /etc/bind/named.conf.local: Local zone definitions.
  • /etc/bind/named.conf.default-zones: Default zone definitions (usually no changes needed).

Let’s look at some key options to configure in these files.

In /etc/bind/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 /etc/bind/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 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:

  • Firewall: Allow only necessary DNS traffic (port 53).
  • Regular Updates: Keep the Bind software updated to patch security vulnerabilities.
  • Restrict Access: Limit access to the server using strong passwords and SSH keys.
  • Chroot Environment: Run Bind in a chroot environment to isolate it from the rest of the system.
  • DNSSEC: Implement DNSSEC to protect against DNS spoofing and cache poisoning 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 dig, nslookup, 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. The second should show the A record for dns1.home.net. The 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:

  • web1: 192.168.1.101
  • db1: 192.168.1.102
  • files: 192.168.1.103

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 volume
  • Response times
  • Error rates
  • Resource utilization (CPU, memory)

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:

  • Forward Lookups: Verify that you can resolve internal and external hostnames.
  • Reverse Lookups: Verify that you can resolve IP addresses to hostnames.
  • Zone Transfers: Verify that zone transfers are working correctly (if applicable).
  • Performance Testing: Measure response times and identify any performance bottlenecks.
  • Security Audits: Conduct regular security audits to identify and address any 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.

Summary

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. This article shows how beneficial the Bind as a private network DNS server can be.

Of course, hardened security, robust monitoring, testing, redundancy, and proper maintenance are required to keep your DNS services running reliably. But with its flexible configurations, Bind as a private network DNS server can meet the local DNS requirements for even large private networks and custom deployments. This detailed tutorial illustrates how to implement Bind as a private network DNS server.

Alternative Solutions for Private Network DNS

While Bind is a robust and widely used solution, other options exist for setting up a private network DNS server. Here are two alternatives:

1. dnsmasq

Explanation: dnsmasq is a lightweight, easy-to-configure DNS forwarder and DHCP server. It is designed for small networks and provides DNS caching and forwarding capabilities. It’s simpler to configure than Bind, making it a good choice for less complex setups.

Advantages:

  • Easy Configuration: Configuration is simpler compared to Bind.
  • DHCP Integration: Can also act as a DHCP server, simplifying network management.
  • Lightweight: Uses fewer resources than Bind.

Disadvantages:

  • Limited Features: Less feature-rich than Bind, lacking advanced capabilities like DNSSEC (without extra configuration) and dynamic zone updates (although DDNS is supported).
  • Scalability: Not as scalable as Bind for larger networks.

Code Example (Configuration file – /etc/dnsmasq.conf):

# Listen on all interfaces
listen-address=0.0.0.0

# Specify upstream DNS servers
server=8.8.8.8
server=8.8.4.4

# Define a local domain
domain=home.net

# Local host definitions
address=/router.home.net/192.168.1.1
address=/web1.home.net/192.168.1.101
address=/db1.home.net/192.168.1.102

Installation (Ubuntu/Debian):

sudo apt update
sudo apt install dnsmasq

This configuration sets up dnsmasq to listen on all interfaces, forward unresolved queries to Google’s public DNS servers, defines the local domain home.net, and provides static IP addresses for router.home.net, web1.home.net, and db1.home.net.

2. Pi-hole

Explanation: Pi-hole is a network-wide ad blocker that also functions as a DNS server. It intercepts DNS queries and blocks requests to known ad-serving domains. While its primary purpose is ad blocking, it effectively serves as a caching DNS server for your private network.

Advantages:

  • Ad Blocking: Blocks ads network-wide.
  • Easy to Use Interface: Provides a web-based interface for managing DNS settings and viewing statistics.
  • Caching: Caches DNS queries for faster resolution.

Disadvantages:

  • Primary Focus on Ad Blocking: Configuration beyond ad blocking can be limited compared to Bind.
  • Security Considerations: Requires careful configuration to prevent unauthorized access and DNS hijacking.

Installation and Configuration:

Pi-hole provides a guided installation process. The basic steps involve:

  1. Downloading and running the Pi-hole installation script.
  2. Configuring the network interface and static IP address.
  3. Setting the upstream DNS servers.
  4. Accessing the web interface for management.

Configuration Example (after installation via web interface):

  1. Log in to the Pi-hole web interface (usually at http://<pi-hole-ip>/admin).
  2. Navigate to "Settings" -> "DNS".
  3. Specify upstream DNS servers (e.g., Google DNS, Cloudflare DNS).
  4. Configure the Pi-hole server as the DNS server on your network clients.

Pi-hole automatically creates the required DNS configuration and allows you to manage local DNS records and blacklists through its web interface. It also offers valuable insights into network activity and blocked domains. It is a good option for home networks looking for ad-blocking and simple DNS caching.