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 forhome.net
and any sub-domains under it likeserver1.home.net
,printers.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 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
. 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 itselfdns1.home.net
192.168.1.101
– A web server namedweb1.home.net
192.168.1.102
– A database serverdb1.home.net
192.168.1.103
– A file serverfiles.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
dig
,nslookup
andhost
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
andnamebench
- 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.