Setting Up Custom Nameservers for Your Private Network
When managing a private network, relying on public DNS servers for internal hostname resolution introduces latency and security risks. Configuring custom nameservers centralizes control, accelerates local lookups, and safeguards sensitive domain data. This guide walks you through deploying a BIND9 DNS server on Ubuntu 22.04, securing it with TSIG keys, and binding it to your network interface.
Prerequisites
- Static IP address for the DNS server (e.g.,
192.168.1.10) - Dedicated machine or container with Ubuntu 22.04 LTS installed
- Sudo access for software installation and firewall configuration
- Internal domain name (e.g.,
priv.net) that will not conflict with public TLDs
Selecting a DNS Software and Securing It
BIND9 is the industry standard for authoritative DNS. Begin by updating the system and installing the package:
sudo apt update && sudo apt upgrade -y sudo apt install bind9 bind9utils bind9-doc
After installation, verify BIND9 is active:
sudo systemctl status bind9
Create a TSIG key for secure zone transfers between master and slave nameservers:
sudo tsig-keygen -a hmac-sha256 custom-key > /etc/bind/tsig.key
Set restrictive file permissions:
sudo chmod 640 /etc/bind/tsig.key sudo chown bind:bind /etc/bind/tsig.key
Configuring the Primary Nameserver
Edit the main configuration file to define the listening interface and zone for your private domain:
sudo nano /etc/bind/named.conf.local
Insert the following directives, replacing domain and IP values with your own:
include "/etc/bind/tsig.key";
zone "priv.net" {
type master;
file "/etc/bind/db.priv.net";
allow-transfer { key custom-key; };
};
Now create the forward zone file. Start by copying the default template:
sudo cp /etc/bind/db.local /etc/bind/db.priv.net
Edit the zone file to map internal hostnames to their private IP addresses:
$TTL 604800
@ IN SOA ns1.priv.net. admin.priv.net. (
2023100101 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.priv.net.
@ IN NS ns2.priv.net.
ns1 IN A 192.168.1.10
ns2 IN A 192.168.1.11
server1 IN A 192.168.1.20
Check the syntax and restart BIND9:
sudo named-checkzone priv.net /etc/bind/db.priv.net sudo systemctl restart bind9
Setting Up a Slave Nameserver for Redundancy
Repeat the installation on a second machine (e.g., IP 192.168.1.11). On the slave server, edit named.conf.local:
zone "priv.net" {
type slave;
file "/var/cache/bind/db.priv.net";
masters { 192.168.1.10; };
};
Restart BIND9 on the slave and verify zone transfer logs:
sudo systemctl restart bind9 sudo journalctl -u bind9 | grep "transfer"
Configuring Firewall Rules and Client DNS Settings
Allow DNS traffic (UDP/TCP port 53) on your server’s firewall:
sudo ufw allow 53/udp sudo ufw allow 53/tcp sudo ufw reload
For client machines running Linux, update /etc/resolv.conf by setting the nameserver line to your primary custom server:
nameserver 192.168.1.10
On Windows, navigate to Network Adapter Properties → Internet Protocol Version 4 (TCP/IPv4) → Properties → Use the following DNS server addresses. Enter the IP of your private nameserver as the Preferred DNS server.
Testing Resolution with nslookup
Verify the configuration by querying an internal hostname from any client on the network:
nslookup server1.priv.net 192.168.1.10
The output should display the corresponding IP address 192.168.1.20 from your zone file. Resolve the authoritative nameservers themselves:
nslookup -type=ns priv.net 192.168.1.10
Common Troubleshooting
If resolution fails, check the following: ensure the /etc/hosts file on the DNS server does not override custom entries; confirm no other process is occupying port 53 by running sudo netstat -tulpn | grep :53; verify the serial number in the zone file is incremented after every change to force slaves to refresh.