Setting Up Your Own Linux DNS Server
Many teams want to control the domain name resolution for their application by setting up their own DNS server. This blog will show you how to do so using the BIND software package. If you need to understand more about DNS and how it works, this post is a great place to get started.
A Quick Intro to BIND
From the Udemy course on BIND1:
BIND is open source software that enables you to publish your Domain Name System (DNS) information on the Internet, and to resolve DNS queries for your users. The name BIND stands for “Berkeley Internet Name Domain”.
BIND is open source, it is one of the oldest, most widely used DNS servers, and it is super easy to set up.
Let's get started!
Installation
You can download the software through the BIND website or just use you native package installer like yum
. It is also installed for you in the script in a later section.
yum install -y bind*
We use the *
because we want all BIND packages, especially bind-chroot
and bind-utils
. The service BIND uses is called "named", so you can check that the installation was successful by issuing the following command:
systemctl status named
If everything went well your system should find the named
service and we can move on to the configuration.
Configuring the OS and the 'named' Service Files
In this section, we will create and update the configuration files needed to ensure named
is running properly. We will also make a few minor OS changes that are necessary if using CentOS 7 on AWS.
Rather than explain it all file by file, I have put the steps into a script. It should be pretty straightforward if you have a basic understanding of bash scripting. Just copy and paste the text below into a .sh
file on your system and make sure it is executable by running chmod +x myscript.sh
.
The script will configure the OS, install bind
, and configure all the appropriate files to get you up and running. I have left comments that explain each step (they have a #
in front) and also summarized the steps below. You just need to change the $HOSTNAME
and $DOMAIN
variables.
- Set the hostname of your server
- Update the
/etc/hosts
file - Remove any cloud configs that revert hostname changes
- Reboot the server
- Install
bind
- Edit the
/etc/named.conf
file - Create forward and reverse domain configs under
/var/named
- Start the service
- Update IPtables or firewall rules as well as the AWS security group(s) to allow UDP on 53
- Test!
#!/bin/bash
#Set variables to be used in the configuration of the OS and named service
#Hostname of the DNS machine
HOSTNAME=dnstrial.test.com
DOMAIN=test.com
#IP of the DNS machine
MY_IP=$(ifconfig -a | grep inet | awk '{print $2}' | sed -n '1p')
#IP of the DNS machine reversed
REV_IP= $(echo $MY_IP | rev)
#Last octet of the DNS machine IP
FINAL_OCTET=$(awk -F. '{print $NF}' <<< $MY_IP)
#Set the hostname of the server in all the appropriate places
hostnamectl set-hostname $HOSTNAME
hostname $HOSTNAME
sed -ie "s|^HOSTNAME=.*|HOSTNAME=$HOSTNAME|" /etc/sysconfig/network
#Add the hostname to the /etc/hosts file, overwriting what was there
echo "$MY_IP $HOSTNAME" >> /etc/hosts
#Remove unwanted cloud configs that overwrite the hostname upon machine reboot (if using AWS)
touch /etc/cloud/cloud.cfg.d/90_unmanage.cfg
echo "preserve_hostname: true" > /etc/cloud/cloud.cfg.d/90_unmanage.cfg
echo "manage_etc_hosts: false" >> /etc/cloud/cloud.cfg.d/90_unmanage.cfg
#Reboot to ensure all changes take effect
reboot
#Install the software
yum install bind* -y
#TODO
#vim /etc/named.conf
# - add IP to "listen-on" and "allow-query"
#Add appropriate zones to /etc/named.conf
echo "zone “$HOSTNAME” IN {" >> /etc/named.conf
echo "type master;" >> /etc/named.conf
echo "file “fwd.$DOMAIN”;" >> /etc/named.conf
echo "allow-update { none; };" >> /etc/named.conf
echo "};" >> /etc/named.conf
echo " " >> /etc/named.conf
echo "zone “$REV_IP.in-addr.arpa” IN {" >> /etc/named.conf
echo "type master;" >> /etc/named.conf
echo "file “rev.$DOMAIN”" >> /etc/named.conf
echo "allow-update { none; };" >> /etc/named.conf
echo "};" >> /etc/named.conf
#Create and populate the config files for forward and reverse domain lookup under /var/named
cd /var/named
touch fwd.$DOMAIN
echo "$TTL 86400" >> fwd.$DOMAIN
echo "@ IN SOA ns.$HOSTNAME. root.$HOSTNAME. (" >> fwd.$DOMAIN
echo " 2019041801 ;Serial" >> fwd.$DOMAIN
echo " 3600 ;Refresh" >> fwd.$DOMAIN
echo " 1800 ;Retry" >> fwd.$DOMAIN
echo " 604800 ;Expire" >> fwd.$DOMAIN
echo " 86400 ;Minimum TTL" >> fwd.$DOMAIN
echo ")" >> fwd.$DOMAIN
echo "@ IN NS ns.$HOSTNAME." >> fwd.$DOMAIN
echo "@ IN A $MY_IP" >> fwd.$DOMAIN
echo "ns IN A $MY_IP" >> fwd.$DOMAIN
touch rev.$DOMAIN
echo "$TTL 86400" >>rev.$DOMAIN
echo "@ IN SOA ns.$HOSTNAME. root.$HOSTNAME. (" >> rev.$DOMAIN
echo " 2019041801 ;Serial" >> rev.$DOMAIN
echo " 3600 ;Refresh" >> rev.$DOMAIN
echo " 1800 ;Retry" >> rev.$DOMAIN
echo " 604800 ;Expire" >> rev.$DOMAIN
echo " 86400 ;Minimum TTL" >> rev.$DOMAIN
echo ")" >> rev.$DOMAIN
echo "@ IN NS ns.$HOSTNAME." >> rev.$DOMAIN
echo "@ IN A $MY_IP" >> rev.$DOMAIN
echo "$FINAL_OCTET IN PTR ns.$HOSTNAME." >> rev.$DOMAIN
#Start the service with the new configs (or use restart if it was already running)
systemctl start named
#IPtables or firewall - enable tcp 53 and udp 53
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p udp -m udp --sport 53 -j ACCEPT
#Test that the named service is working properly
named-checkconf /etc/named.conf
named-checkzone $HOSTNAME /var/named/fwd.$DOMAIN
named-checkzone $HOSTNAME /var/named/rev.$DOMAIN
nslookup google.com
There are a million reasons to set up your own DNS server, so I hope you found this information useful. Let me know if you have any questions!
[email protected]
For More
This page has a lot of really good, comprehensive information and examples of DNS.