Seven Easy Steps To Setting Up An Interal DNS Server On Ubuntu
Bind9 is used all across the internet for DNS. A survey shows that over 70% of DNS servers on the internet use Bind. In this tutorial we will setup a Bind9 DNS server for your home network with caching.
By running a caching DNS server it will cache DNS locally so sites you visit often will not have to make a DNS query until the DNS record has expired. This will help improve your internet speed as well as reduce bandwidth. I have noticed a huge improvement with my satellite internet connection just by running a local DNS caching server.
Below you can see the first time I make a DNS request for distrowatch.com the query time is 1698 milliseconds. The second time I make the request after it has been cached, it only takes 4 milliseconds.
Now milliseconds doesn't seem like a lot of time. However most website have content that is pulled from multiple locations. A webpage could have a youtube video embed, some ads, a news feed, images and much more being pulled from other domains. When that page loads, a DNS requests is made for all objects. The more stuff on the site from multiple locations the more DNS request need to be made.
Another great benefit to running a internal DNS server is you can just type the name of a device like server, firewall, printer, basement-pc, or whatever you want to call your network devices. There is no need to remember the IP addresses of the devices when you can just type the defined name.
Before we begin I am assuming you have an Ubuntu server running and configured with a static IP address. If you need help with that take a look at some of the following articles.
Let's dive in and start setting up an internal DNS server with caching!
Installing Bind9 on Ubuntu
Installing Bind9 (DNS Server) is a breeze on Ubuntu. Three packages will need to be installed: bind9, dnsutils, and bind9-doc.
- bind9: The DNS service.
- dnsutils: A set of tools such as dig which can be helpful for testing and trouble shooting.
- bind9-doc: Local info pages with information about bind and its configuration options. This is optional but recommended.
sudo apt-get install bind9 dnsutils bind9-doc
Enter your password
Enter Y to confirm installing
Basic Bind Configuration
The next step is to configure the forwards addresses for bind. This tell bind where to look if it doesn't know the IP address of a domain. In this example we will use Google's Public DNS servers for the forward DNS servers. Google's DNS servers are fast, free, and have easy to remember IP addresses. If you want you can use your local internet provider's DNS servers. Another option is to use OpenDNS which gives you the ability to filter content. This can be nice if you have young children on the internet.
Let's edit /etc/bind/named.conf.options and define the forward addresses. To keep things simple we will use the nano text editor in this tutorial. If you want to use Vim or Emacs instead, feel free to do so.
sudo nano /etc/bind/named.conf.options
Delete the // in front of:
Exit it out of nano by hitting CTRL + X.
Enter Y to confirm saving changes.
Hit Enter to overwrite the file.
The next step is to edit /etc/bind/named.conf.local. This file holds information on what zones to load when Bind9 is started. We will setup two zones files to load, the Forward and Reverse zones.
In this example we will setup an internal domain with tne name linux.rocks. If you want to use something else just make sure you replace linux.rocks in the following steps with your internal domain name. The internal domain can be whatever you want.
The reason I am using linux.rocks instead of something like linux.com, linux.net, linux.org..etc is a real domain on the internet could have this address. If this was the case I would not be able to access the real domain on the internet. Instead I would be directed to a device on my internal network.
At this time .rocks is not a top level domain on the internet, but it does not mean it won't be tommorow. If you want to be sure there is no way your domain could be used externally, use a reserved top level domain like .test, .example, .invalid or .localhost. So in this example we could use linux.test and not have to worry about that domain every being a real domain on the internet. To learn more about reserved domains check out http://tools.ietf.org/html/
We will need to figure out our IP address range of our internal network so we can build the correct reverse zone lookup file.
When looking at our IP address the part we care about is the first three sets of octets (numbers). Then we just reverse them. So If my IP address is 192.168.1.100 my reverse lookup zone would be 1.168.192.in-addr.arpa. If my IP address is 172.20.16.120 my reverse zone would be 16.20.172.in-addr.arpa .
Most home networks will have a 192.168.1.X or 192.168.0.X type of IP address. In my case I have a 192.168.96.X IP address network.
If you need help on how to find what your IP address, check out some of the following tutorials.
Let's open up /etc/bind/named.conf.local and define the locations of the forward and reverse zone files.
sudo nano /etc/bind/named.conf.local
Add The following.
Note: Replace linux.rocks with the internal domain name you picked and replace 96.168.192 with your IP address scheme. Adjust the zone file names to fit your setup and make note of the names (db.linux.rocks and db.192) because we will need to build these files in the next few steps.
Here is what my named.conf.local file looks like:
Hit CTRL + X to exit out of nano
Enter Y to confirm saving changes
Confirm the name has not changed and hit Enter to save changes.
Building Your DNS Forward Zone
Now that we have defined what zone files to load when Bind starts, we need to create these files. The first file we need to build is the forward zone file (db.linux.rocks). We can use a template to help speed things and prevent mistakes. Let's copy /etc/bind/db.local and name the file to the name we defined above in /etc/bind/named.conf.local . (Example: db.linux.rocks)
sudo cp /etc/bind/db.local /etc/bind/db.linux.rocks
Let's now edit the new forward zone file and make changes to fit the network.
sudo nano /etc/bind/db.linux.rocks
We will need to change a few basic setting in this file and then add our forward lookups. Below you will find a screenshot with a break down of what these settings do and how to set them to fit your network.
A.) localhost. - This is the fully qualified domain name of the server in charge of the domain we are creating. Change this to your hostname followed by the domain name. Since my server hostname is ubuntu-server, I will set this to ubuntu-server.linux.rocks. Make sure it ends with the "." . If you need help on how to find or change your hostname take a look at http://mixeduperic.com/ubuntu/how-to-find-and-change-your-hostname-on-an-ubuntu-system.html.
B.) root.localhost. - This is the email address of the person responsible for managing the DNS server. Here you do not use the @ sign but use a "." This is really more for human consumption. Note: Make sure you have a "." at the end.
C.) localhost. - This is defining the Name server for the domain (NS). You will want to change this to the fully qualified domain name again. So I would set this to ubuntu-server.linux.rocks. Note: Make sure you have a "." at the end.
This is what my forward zone file looks like so far. (/etc/bind/db.linux.rocks)
Now for the fun part. we can now start defining our devices on the network.
Let's take a quick look at DNS record types.
The three most common types of DNS records are Address (A Record), Canonical Name (CNAME), and Mail Exchanger (MX). We will focus on A and CNAME records in this tutorial.
Address (A Record): Defines a mapping of a hostname to an IP address. This is the most common
Canonical Name (CNAME): Defines that the domain name is an alias of another name. It basically allows you to point a domain name to another.
Mail exchanger (MX): Defines mail server responsible for accepting email messages.
Below you will see a the basic network layout that we will be defining. All the devices have a static IP address assigned to them. In a later tutorial we will look at setting up DHCP to update our DNS records but for now we will just setup a basic DNS server. If you need help on setting a static IP address on an ubuntu system check out http://mixeduperic.com/ubuntu/how-to-set-a-static-ip-address-on-a-ubuntu-server.html .
So in the example network we will want to be able to connect to all the devices using the name of the device instead of the IP address. We will also use CNAME records to map the name server01 to ubuntu-server and server02 to ubuntu-server2. This will allow us to type in server01 or ubuntu-server and connect to the same machine.
Now let's break this down and look at what some of these settings mean. The image below highlights each area by letter to help clear somethings up.
A.) This is the name that we want to link to an ip address.
B.) IN Stands for internet. This is one class of data; other classes exist, but none of them is currently in widespread use.
C.) This is defining it as an A record type (Address).
D.) This is defining the IP address of the device we want to call firewall.
E.) This is defining it as a CNAME record type instead of an A, or MX.
F.) This is defining the fully qualified domain name the CNAME record (Alias) points to.
Note: When using CNAME records make sure you use the fully qualified domain name followed by a ".".
Now we just need to save our changes.
Hit CTRL + X to exit nano.
Enter "Y" to save the file.
Hit Enter to overwrite the file.
Building Your Reverse Lookup
Reverse DNS is not a must have but it is very good practice and some services need it. Often times things can act a little goofy if it's not setup. It does the opposite of the forward zone file and maps IP addresses to names.
You can use nslookup to look up a name by IP address.
Here is an example of me doing an nslookup on up address 192.168.96.1
Note: This was done after the reverse zone was setup and running.
When we setup named.conf.local we defined the name of the reverse zone file. If you are following along it was defined as /etc/bind/db.192. We will create this file by making a copy of another file.
sudo cp /etc/bind/db.127 /etc/bind/db.192
Now lets edit that file.
sudo nano /etc/bind/db.192
Just like the forward zone file we will need to edit a few basic settings first before adding our addresses.
A.) This should be the fully quilifed name of the server (hostname.domain.name)
B.) This is the email address of the person responsible for the managing the domain. Remember to use a "." instead of the @ sign.
C.) Change this to the fully quilified name of your DNS server. Example: (server-ubuntu.linux.rocks.)
D.) We can delete this line. Since we copied the local host file this was included in it and we don't need it.
Reminder: Make sure you have a "." at the end of the names.
This is what my reverse zone file looks like so far.
Let's start adding the reverse DNS records.
Let's Break this down
A.) This is the last octet (Set up Numers on the IP address of the device. (Example: 192.168.96.01)
Note: Leave the 0 off the front, so on numbers under ten like 01 would be 1 instead of 01 . Otherwise things may not work correctly.
B.) IN is defining it as an Internet address.
C.) PTR is a pointer record. This defines what name will be called when an IP address is looked up.
D.) This is the fully qualified domain name that will return when doing a nslookup.
Now lets save our reverse zone file by hitting CTRL + X
Enter "Y" to confirm saving the file.
Hit Enter to overwrite the file.
Starting Your DNS Server
We should have most of our configuration done and can now fire up the bind9 service.
sudo /etc/init.d/bind9 start
Other Useful Commands:
Restart bind9 service: sudo /etc/init.d/bind9 restart
Stop bind9 service: sudo /etc/init.d/bind9 stop
Testing Your DNS Server
Let's configure the server to use the Bind9 service that is running locally as its own DNS server.
sudo nano /etc/resolv.conf
Add name server, domain, and search option to your resolve.conf file.
nameserver: This is the IP address of the DNS server to use. You can use the IP address or the loopback address 127.0.0.1
domain: This will be the domain we just created.
search: This will be the domain we just created.
Now that we have DNS setup we can use ping to test that everything is working.
Both dig and ping are great tools for troubleshooting and testing. dig is great for checking the time it takes to returen a DNS request as well as see what DNS server filled that request.
You can see that the DNS server that responded was 192.168.96.2 and it took 1579 msec to get a reply. Now 1579 is a really long time but since I have a satalite connection that is the norm. Most networks should be 500 msec or less.
Let's dig distrowatch.com one more time and see what kind of performance increase we get now that the DNS request for distrowatch.com is cached.
You can see a big performance increase. It went from 1579 msec to 3 msec. We now know that the server can query google's DNS server on entries is does not know. Let's now try and ping one of the internal DNS enties we added. Since I setup the name firewall to IP address 192.168.96.1, I wil try pinging that address and use the -c 4 option at the end of the command to ping it only 4 times. If you leave the -c 4 option off it will keep pinging until you hit CTRL + C to cancel it.
ping firewall -c 4
You can see that I am getting replies. Looks like everything is up and working!
Configuring Your PC To Use Your New DNS Server
All that is left is to setup your machines to use your new DNS server. You have a couple options here. You can manually set it on each machine or edit your DHCP server to hand this out with the IP addresses.
How To Manually Set DNS Server(s) On A windows 7 : http://mixeduperic.com/windows/how-to-manually-set-dns-servers-on-a-windows-7.html
If you are looking for some more details on DNS and Bind O'Reilly has a really great book that I recommend. It covers anything from running a internet DNS server to all the details on options and settings.
If you enjoyed this post, please share it on your favorite social network by clicking on the “Share / Save” bar below.