This guide will cover setting up the Bind9 DNS Server for Ubuntu/Debian systems, we will setup a Forward Lookup Zone as well as a Reverse Lookup Zone. In other distributions like Centos, the package will be named but the configuration is mostly the same. Here we will work on creating a Master DNS Server, this is your primary DNS Server for the organization. The domain that i will be using is linuxman.local and my DNS server will be 172.16.32.5 with a Windows 7 machine as a client.
- Static IP
- Domain name in mind
- Server setup with an FQDN
- PC used for testing
If you need to setup your FQDN on your machine, go to my page Set Hostname in Linux.
1. First lets install the package bind9
using apt
.
sudo apt install bind9 -y
2. After Bind9 has finished installing lets go ahead and cd into our bind directory and list its contents.
debian@debian:/etc/bind$ cd /etc/bind/
debian@debian:/etc/bind$ ls -l
total 56
-rw-r--r-- 1 root root 3923 May 3 15:34 bind.keys
-rw-r--r-- 1 root root 237 May 3 15:34 db.0
-rw-r--r-- 1 root root 271 May 3 15:34 db.127
-rw-r--r-- 1 root root 237 May 3 15:34 db.255
-rw-r--r-- 1 root root 353 May 3 15:34 db.empty
-rw-r--r-- 1 root root 270 May 3 15:34 db.local
-rw-r--r-- 1 root root 3171 May 3 15:34 db.root
-rw-r--r-- 1 root bind 463 May 3 15:34 named.conf
-rw-r--r-- 1 root bind 490 May 3 15:34 named.conf.default-zones
-rw-r--r-- 1 root bind 239 May 11 10:07 named.conf.local
-rw-r--r-- 1 root bind 881 May 11 10:04 named.conf.options
-rw-r----- 1 bind bind 77 May 11 00:06 rndc.key
-rw-r--r-- 1 root root 1317 May 3 15:34 zones.rfc1918
The files we are going to be working with are:
- named.conf.local: Will be the one responsible for specifying custom zones that we will be adding.
- named.conf.options: Will be the one responsible for configuring extra options we want to add to our server such as Forwarders*(see note).
- db.local: This is the template we are going to use to build up our own zone.
A forwarder is used to forward DNS Queries to an external/remote DNS server if the query does not exist in the zone. Example if I query Google.com from my Windows machine. The query will go to the Windows machine's DNS server, the server will check its zones for Google.com, if it does not find it then it will Forward the query to whatever DNS server is setup as a Forwarder.
Forward Lookup Zone
1. Lets make a copy of the db.root
file and give it the name of our zone. Lets call it db.linuxman.local
.
sudo cp db.root db.linuxman.local
2. Using your favorite text editor, lets edit our zone.
sudo vim db.linuxman.local
This is what the zone currently contains so we will change some values to match our domain:
;
; BIND data file for local loopback interface
;
$TTL 604800
@ IN SOA localhost. root.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
@ IN A 127.0.0.1
@ IN AAAA ::1
We are going to change the bolded values to the following:
;
; BIND data file for linuxman.local domain
;
$TTL 604800
@ IN SOA linuxman.local. root.linuxman.local. (
20190511 ;Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.linuxman.local.
@ IN A 172.16.32.5
ns1 IN A 172.16.32.5
- NAME: Name of the zone which should be left as @, that will default to the name of our root domain which is linuxman.local.
- IN: Zone class, IN for Internet
- SOA: Abbreviation of Start of Authority
- MNAME: This is the Primary Master name server for the zone, ideally your root domain which would be
linuxman.local
. - RNAME: This is the email address of the person responsible for the zone but encoded as a name. So if i want to use the email
root@linuxman.local
, it would beroot.linuxman.local
. - SERIAL: This is usually used for slave/secondary DNS servers. When an update has been made to a master server, the serial number will increase indicating to the slave servers that an update has been made which will then start a zone transfer. Most of the time the date of initial creation of the zone is used but can start at any number, just be sure to increase this after every change so your slave servers are aware.
- REFRESH: This is the rate at which slave servers will check for updates.
- RETRY: This is the number of seconds after which secondary name servers should retry to request the serial number from the master if the master does not respond. It must be less than Refresh.
- EXPIRE: This is the number of seconds after which secondary name servers should stop answering request for this zone if the master does not respond. This value must be bigger than the sum of Refresh and Retry.
- TTL: This is the Time to Live for negative caching.
3. Lets continue by adding some DNS Records. I will go over some common records you would see in a business.
A (Address) Record
This A record will point to the www
host which will be a webserver. The FQDN would be www.linuxman.local
.
www IN A 172.16.32.2
Using @ as the host will resolve to the root domain, linuxman.local
. These records point a hostname/FQDN to an IP Address.
CNAME/Alias Record
tech IN CNAME www
CNAME records will point to an existing record of your choosing. I will alias www
with tech
. Be aware that the CNAME Record must be defined BEFORE the A Record that the CNAME is pointing to.
MX Record
The MX record will define where email should be sent to and what priority. Requires an A record for the mail server itself, it is not considered an Alias.
IN MX 10 mail.linuxman.local
mail IN A 172.16.32.3
NS (Name Server) Record
NS Records define which servers serve copies of the zone, must point to an A Record and not a CNAME/Alias.
IN NS ns
ns IN A 172.16.32.5
SPF Record
@ IN TXT "v=spf1 ip4:172.16.32.3 -all"
DKIM Record
selector._domainkey IN TXT "v=DKIM1; k=rsa; p="
DMARC Record
_dmarc IN TXT "v=DMARC1; p=reject; fo=1; rua=mailto:test@test.com; ruf=mailto:test@test.com"
SPF, DKIM and DMARC are a set of TXT Records used for verifying outgoing email addresses.
Result
# default
;
; BIND data file for linuxman.local domain
;
$TTL 604800
@ IN SOA linuxman.local. root.linuxman.local. (
20190511 ;Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; NS Records
IN NS ns.linuxman.local.
; CNAME/Alias Records
tech IN CNAME www.linuxman.local.
; A Records
@ IN A 172.16.32.5
ns IN A 172.16.32.5
www IN A 172.16.32.2
mail IN A 172.16.32.3
; MX Records
IN MX 10 mail.linuxman.local.
; TXT Records
; SPF Records
@ IN TXT "v=spf1 ip4:172.16.32.3 -all"
; DKIM Records
selector._domainkey IN TXT "v=DKIM1; k=rsa; p="
; DMARC Records
_dmarc IN TXT "v=DMARC1; p=reject; fo=1; rua=mailto:test@test.com; ruf=mailto:test@test.com"
4. Now we will add the new zone to the named.conf.local
that way the new zone is loaded with Bind9.
sudo vim named.conf.local
5. Add the new zone as below making sure your file is the absolute path of the zone file.
zone "linuxman.local" {
type master;
file "/etc/bind/db.linuxman.local";
};
Reverse Lookup Zone
1. Lets make a copy of our db.linuxman.local
file and modify it to use it for our reverse lookup zone. You can name the new file using db.<first octet>
.
sudo cp db.linuxman.local db.172
Remember that Reverse Lookup Zones resolve IP Addresses to Domain Names, so we’re going to remove about half of the records we created.
2. Using your favorite text editor, delete all SPF, DKIM, DMARC, CNAME, and MX Records leaving only the NS and A Records.
;
; BIND data file for linuxman.local domain
;
$TTL 604800
@ IN SOA linuxman.local. root.linuxman.local. (
20190511 ;Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; NS Records
IN NS ns.linuxman.local.
; A Records
@ IN A 172.16.32.5
ns IN A 172.16.32.5
www IN A 172.16.32.2
mail IN A 172.16.32.3
3. Now that we have a base to work off of, you are going to reverse the records where the last octet of the IP Address will be on the left and the hostname will be in the right followed by a dot. The NS Record will use an @
on the left and the hostname on the right. Last, instead of A records, they will be Pointer Records (PTR).
;
; BIND data file for linuxman.local domain
;
$TTL 604800
@ IN SOA linuxman.local. root.linuxman.local. (
20190511 ;Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; NS Records
@ IN NS ns.
; A Records
5 IN PTR @
5 IN PTR ns.
2 IN PTR www.
3 IN PTR mail.
4. Next lets modify the named.conf.local
to add our Reverse Lookup Zone.
sudo vim named.conf.local
Add the reverse lookup zone using the first 3 octets of the subnet reversed as shown:
zone "32.16.172.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/db.172";
};
Named Options
1. Lets add a Forwarder into the options file by editing named.conf.options
. Uncomment the Forwarders option and add your preferred DNS server to forward queries to.
forwarders {
1.1.1.1;
};
Testing
1. Lets apply changes and start testing DNS Queries with our Windows client.
sudo systemctl reload bind9.service
Check for any errors on reload
sudo systemctl status bind9.service
2. Set the client’s DNS server to our new DNS server and pull up a command prompt.
3. Lets start by running nslookup
on all records in the Forward Lookup Zone.
NS Records
For NS Records you need to use the -q=NS
as an argument in nslookup
.
CNAME Records
For CNAME Records you need to use the -q=CNAM
E as an argument in nslookup
. We will check for CNAME Records on tech.linuxman.local
.
A Records
NOTE: For TXT records you need to use the -q=TXT
argument in nslookup
.
SPF Records
DKIM Records
DMARC Records
SOA Records
For SOA Records you need to use the -q=SOA
as an argument in nslookup
.
MX Records
For MX Records you need to use the -q=MX
as an argument in nslookup
.
4. Now we will check our PTR Records for the IP Addresses that have one.
- 172.16.32.5
- 172.16.32.2
- 172.16.32.3
PTR Records
5. Lastly we will test to see if unknown queries are forwarding to our DNS server of choice.
This concludes a pretty basic but working DNS Server for your network. For more information on Bind9 you can reference the man pages or visit Ubuntu’s Documentation -> BIND9ServerHowTo