On This Page
In short: DNS translates domain names into IP addresses. Running your own DNS server with BIND gives you faster lookups on your network, full control of your zones and private names for internal systems. This guide installs BIND on Ubuntu or Debian, configures it as a resolver, creates a zone and tests it.
Why run your own DNS server
- Performance: a local resolver caches answers, so repeated lookups on your network are answered in milliseconds.
- Security: you decide which clients may query the server and which upstream resolvers it trusts, instead of depending on a third party.
- Control: your domains and subdomains are managed in your own zone files, with no waiting for a provider's panel.
- Private names: internal hosts (printer.office, db.internal) get names that never leave your network.
Step 1: prepare the server
Use a server with a static IP address; dynamic addresses are unsuitable for DNS. Update it and install BIND:
sudo apt update && sudo apt upgrade -y
sudo apt install bind9 bind9utils bind9-doc
Step 2: configure BIND as a resolver
The main options live in /etc/bind/named.conf.options:
options {
directory "/var/cache/bind";
recursion yes;
allow-query { 192.168.1.0/24; localhost; };
forwarders { 1.1.1.1; 8.8.8.8; };
dnssec-validation auto;
listen-on-v6 { any; };
};
allow-query limits who may use the resolver; never leave it as any on a public server, or it becomes an open resolver used in amplification attacks. forwarders are the upstream resolvers asked for names the server does not know.
Step 3: define a zone
Add the zone to /etc/bind/named.conf.local:
zone "example.com" {
type master;
file "/etc/bind/zones/db.example.com";
};
Create the zone file:
sudo mkdir -p /etc/bind/zones
sudo nano /etc/bind/zones/db.example.com
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2026102901 ; serial, increase on every change
604800 ; refresh
86400 ; retry
2419200 ; expire
604800 ) ; negative cache TTL
@ IN NS ns1.example.com.
@ IN A 192.0.2.10
ns1 IN A 192.0.2.10
www IN A 192.0.2.10
@ IN MX 10 mail.example.com.
mail IN A 192.0.2.20
SOA starts the zone and names the primary server and admin contact; NS lists the name servers; A maps names to IPv4 addresses; MX routes mail. Names that end with a dot are absolute. For what each record type does, see the DNS records guide.
Step 4: check and restart
sudo named-checkconf
sudo named-checkzone example.com /etc/bind/zones/db.example.com
sudo systemctl restart bind9
No output from named-checkconf means the configuration is valid. Test a lookup against the server:
dig @127.0.0.1 www.example.com
Step 5: make it authoritative on the internet
For the world to use your server for example.com, register ns1.example.com (and a second server, ns2) as glue records at your domain registrar and set them as the domain's name servers. Run at least two servers in different locations; a single DNS server down means the whole domain is down. A secondary BIND server with type slave and masters { 192.0.2.10; }; copies the zone automatically.
Maintenance
- Increase the serial every time you edit a zone, or secondaries will not update.
- Open UDP and TCP port 53 in the firewall only for the clients and secondaries that need it.
- Watch
/var/log/syslogfor query errors and keep BIND updated.
If you only need to host a few domains, the DNS management in the Fiberserver client area or cPanel's Zone Editor does this without running a server; BIND is worth it when you need private zones or full control.
Thanks for your feedback!
