This article covers a version of CentOS that is no longer supported. If you are currently operating a server running CentOS 6, we highly recommend upgrading or migrating to a supported version of CentOS.
Reason: CentOS 6 reached end of life (EOL) on November 30th, 2020 and no longer receives security patches or updates. For this reason, this guide is no longer maintained.
See Instead:
This guide might still be useful as a reference, but may not work on other CentOS releases. If available, we strongly recommend using a guide written for the version of CentOS you are using.
This article will show you how to setup and configure the BIND DNS Server. If you are looking for a guide on how to use DigitalOcean's integrated DNS service, you may want to review the "How to Set Up a Host Name with DigitalOcean" article instead.
Before we begin, it is recommended you have at least two cloud servers to run your nameservers. Two nameservers are suggested to assure your primary and secondary servers are redundant in case of failure. You may want to consider using two different POP's as well. For example, we've used San Francisco 1 and New York 1. For the purpose of this guide, it will be assumed you are configuring both a primary and secondary name server.
It is worth noting that if you are managing a large number of domains this may not be the most viable solution, as you will need to manually add domains on both the master and slave nameservers. With that said, running your own nameservers is a great way to have more direct control over your hosting infrastructure, and assert full control over your DNS records.
As with any new server, it's always important to ensure your system is up to date. You can verify this by checking for updates using yum as follows:
yum update -y
(Note: In DigitalOcean, we call our cloud servers as "droplets". We will use both terms throughout this tutorial)
To begin, we will need to install the BIND and BIND Utilities packages using yum.
yum install bind bind-utils -y
Next, we'll open the BIND (named) configuration file and make several modifications.
nano -w /etc/named.conf
Your "options" section should appear as follows, replacing 2.2.2.2 with the IP of your second droplet.
options { #listen-on port 53 { 127.0.0.1; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; allow-transfer { localhost; 2.2.2.2; }; recursion no; dnssec-enable yes; dnssec-validation yes; dnssec-lookaside auto; /* Path to ISC DLV key */ bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; };
Above, listen-on must be commented to listen on all available interfaces. Recursion should be turned off to prevent your server from being abused in "reflection" DDoS attacks. The allow-transfer directive whitelists transfers to your secondary droplet's IP. Furthermore, we have changed the allow-query directive to "any" in order to allow users proper access to hosted zones.
Next, we'll want to add a new zone for our first domain, you should add the following to your named.conf below the existing zones.
zone "mydomain.com" IN { type master; file "mydomain.com.zone"; allow-update { none; }; };
After saving named.conf with the changes above, we're ready to create our first zone file.
Firstly, we'll need to open the zone file, using the name you specified in the configuration above. (Ex: mydomain.com.zone)
nano -w /var/named/mydomain.com.zone
We'll add the following contents to our newly created file. You should replace the applicable information with your own, where 1.1.1.1 is the IP of your first droplet, 2.2.2.2 is the IP of your second droplet and 3.3.3.3 is the IP you wish to point the domain itself to, such as a droplet running a webserver. You are free to add additional entries in the same format.
$TTL 86400 @ IN SOA ns1.mydomain.com. root.mydomain.com. ( 2013042201 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) ; Specify our two nameservers IN NS ns1.mydomain.com. IN NS ns2.mydomain.com. ; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses. ns1 IN A 1.1.1.1 ns2 IN A 2.2.2.2 ; Define hostname -> IP pairs which you wish to resolve @ IN A 3.3.3.3 www IN A 3.3.3.3
We can now start named for the first time. This may take several minutes while named generates the rndc.key file, which only occurs on first execution.
service named restart
Once named has started successfully, we'll want to ensure that it is enabled as a startup service, by running the following:
chkconfig named on
By now, we should have a fully operational primary nameserver. You can verify that BIND is working correctly by running the following command, replacing 1.1.1.1 with the IP of your first droplet.
dig @1.1.1.1 mydomain.com
If you recieve a response which includes an answer and authority section, your nameserver has been configured correctly.
With our primary nameserver configured, we'll now setup a slave nameserver on our second cloud server.
As always, please assure your system is up to date by checking for updates with yum as follows:
yum update -y
We can start by installing BIND (and related utilities) on the second droplet, in the same manner as the first:
yum install bind bind-utils -y
We'll proceed by opening named.conf and making the same changes we made previously, ommitting the "allow transfer" line. This directive is unnecessary as we will only be transfering records from our primary name server.
nano -w /etc/named.conf
options { #listen-on port 53 { 127.0.0.1; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; recursion no; dnssec-enable yes; dnssec-validation yes; dnssec-lookaside auto; /* Path to ISC DLV key */ bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; };
We will add the zone we configured on the first droplet, this time changing the "type" directive to slave, instead of master. You should replace "1.1.1.1" with your first droplet's IP address.
zone "mydomain.com" IN { type slave; masters { 1.1.1.1; }; file "mydomain.com.zone"; };
After configuring our slave zone, we'll start named. Again this may take several minutes while our rndc.key file is initially generated.
service named start
As with the first cloud server, we want to assure named is set to run at startup with the following:
chkconfig named on
Your slave nameserver should now be up and running. You can verify that it is fully operational by using dig again, replacing 2.2.2.2 with the IP of your second droplet.
dig @2.2.2.2 mydomain.com
After any changes you make to the master zone files, you will need to instruct BIND to reload. Remember, you must also increment the "serial" directive to ensure synchronicity between the master and slave.
To reload the zone files, we need to run the following command on the master nameserver, followed by the slave:
rndc reload
It is generally advised to install the additional package "bind-chroot" which will drop the privileges of BIND into a chroot environment.
Luckily, the CentOS package makes this extremely simple. The only aspect worth noting is that active paths for BIND will change to their chrooted equivalents, for example /var/named becomes /var/named/chroot/var/named With CentOS 6, you will not need to move any files as the package automatically creates hard symlinks to the non-chrooted directories.
If you'd like to enable this feature for the added security which it provides, you can do the following:
yum install bind-chroot -y service named restart
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
I’m bit confuse here. I follow this tutorial and setup 3 servers. Please help me.
I’m using LEMP for mainserver and do I have to setup dns1 and dns2 with LEMP too? I’m planning to use cPanel but didn’t successful to do this.
Thank you for the tutorial/overview. This is helpful to get you running, there is always some fine tuning and things that can be adjusted per environment/situation depending on your needs, but well done, concise and straightforward.
-Arty Caiado My Photo Blog hosted on DO
Hello, I followed all the steps. I have a vps with 4 static ip addresses, and the host is also on the same machine. now when I run the following command: dig @127.0.0.1 mydomain.com it works but when I use the real ip (ie dig @vps_ip_1 mydomain.com) it can’t find it. Note that I have not installed the firewall yet. What is wrong then?
Hey, Thanks for the tutorial. In this tutorial, you made use of more than one IP address. But I have only but one IP address. How can I accomplish this with one IP address?
I want to enable wildcard subdomain to work with my wordpress multi user site, how can I enable it using this BIND?
I am new in centOs and I have successfully install bind to configure my internal dns server. As now, when I dig the domain it give me another IP different from my server Ip. Can you please help me Thanks
I use exactly this example of zone file for my website. However, I’ve a question. It’s necessary put a CNAME, like this: www.mywebsite.com CNAME mywebsite.com
? (remember, I use exactly the example of zone file from this tutorial)
Hi, I think you have a typo in “you will not need to move any files as the package automatically creates hard symlinks to the non-chrooted directories”. Do you mean hard or symbolic links? Thanks.
I am experiencing the problem below at the first steps: When I edit the /var/named/mydomain.com.zone file with ns1.myowndomain.com and ns2.myowndomain.com i can restart the service but when I enter the real names (name.myowndomain.com & othername.myowndomain.com I can NOT restart named service.
; Specify our two nameservers IN NS ns1.myowndomain.com. IN NS ns2.myowndomain.com.
WORKS,
; Specify our two nameservers IN NS name.myowndomain.com. IN NS othername.myowndomain.com. DOESNT WORK
any clues?
when i use the second way, named restart fails.
This is what I get with "systemctl status named.service ":
systemctl status named.service named.service - Berkeley Internet Name Domain (DNS) Loaded: loaded (/usr/lib/systemd/system/named.service; enabled) Active: failed (Result: exit-code) since Fri 2015-02-13 01:49:49 EET; 7s ago Process: 3557 ExecStop=/bin/sh -c /usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID (code=exited, status=0/SUCCESS) Process: 3479 ExecStart=/usr/sbin/named -u named $OPTIONS (code=exited, status=0/SUCCESS) Process: 3587 ExecStartPre=/usr/sbin/named-checkconf -z /etc/named.conf (code=exited, status=1/FAILURE) Main PID: 3481 (code=exited, status=0/SUCCESS)
Feb 13 01:49:49 name.myowndomain.com systemd[1]: Starting Berkeley Internet Name Domain (DNS)… Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone myowndomain.com/IN: NS 'othername.myowndomain.com…A) Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone myowndomain.com/IN: NS 'name.myowndomain.com…A) Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone myowndomain.com/IN: not loaded due to errors. Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: _default/myowndomain.com/IN: bad zone Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone localhost.localdomain/IN: loaded serial 0 Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone localhost/IN: loaded serial 0 Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0… 0 Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0 Feb 13 01:49:49 name.myowndomain.com named-checkconf[3587]: zone 0.in-addr.arpa/IN: loaded serial 0 Feb 13 01:49:49 name.myowndomain.com systemd[1]: named.service: control process exited, code=exited status=1 Feb 13 01:49:49 name.myowndomain.com systemd[1]: Failed to start Berkeley Internet Name Domain (DNS). Feb 13 01:49:49 name.myowndomain.com systemd[1]: Unit named.service entered failed state. Hint: Some lines were ellipsized, use -l to show in full.
Hello,
I setup dns server on my server and create entry in /etc/named/name.conf and mention zone file information , then i edit zone file and added rest of the information, yes i will show my configuration below , but problem is i did not getting result when i try to run dig . plz see the dig result –
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 20546 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: ;mydomain.net.in. IN A
below i mention my configuration /etc/named.conf
options { listen-on port 53 { 127.0.0.1; }; listen-on-v6 port 53 { ::1; }; directory “/var/named”; dump-file “/var/named/data/cache_dump.db”; statistics-file “/var/named/data/named_stats.txt”; memstatistics-file “/var/named/data/named_mem_stats.txt”; allow-query { any; }; allow-transfer { localhost; }; recursion no;
dnssec-enable yes; dnssec-validation yes; dnssec-lookaside auto;
/* Path to ISC DLV key */ bindkeys-file “/etc/named.iscdlv.key”;
managed-keys-directory “/var/named/dynamic”; };
zone “mydomain.net.in” IN { type master; file “/var/named/mydomain.net.in.zone”; allow-update { none; }; }; zone “ns1.mydomain.net.in” { type master; file “/var/named/ns1.mydomain.net.in.zone”; }; zone “ns2.mydomain.net.in” { type master; file “/var/named/ns2.mydomain.net.in.zone”; };
/var/named/mydomain.net.in $TTL 14400 $ORIGIN mydomain.net.in.
; SOA Record ; Specify Primary nameserver ns1.mydomain.net.in ; Serial should increment every update @ 14400 IN SOA ns1.mydomain.net.in. webmaster.technozone.net.in. ( 2015012902 ; Serial in YYYYMMDDXX (XX is increment) 10800; refresh seconds 3600; retry 604800; expire 38400; minimum ); ; Website IP Address specified in A record
IN A 90.1.1.90
; Minimum 2 DNS nameserver names
IN NS ns1.mydomain.net.in. IN NS ns2.mydomain.net.in.
; Mapping all Nameservers and their corresponding IPs (GLUE)
ns1 IN A 90.1.1.90 ns2 IN A 90.1.1.90
; Specify any subdomains and www entry here using CNAME record
www IN CNAME mydomain.net.in. ftp IN CNAME mydomain.net.in. server IN CNAME mydomain.net.in. webmail IN CNAME mydomain.net.in.
; Setup MX record (mail exchanger with priority) mydomain.in. IN MX 10 mail.mydomain.net.in.
; set A record for mail mail IN A 90.1.1.90;====================================
For ns1 $TTL 14400 @ 86400 IN SOA ns1.mydomain.net.in. wemaster.mydomain.net.in. ( 3013040200 ; serial, todays date+todays 86400 ; refresh, seconds 7200 ; retry, seconds 3600000 ; expire, seconds 86400 ) ; minimum, seconds
ns1.mydomain.net.in. 86400 IN NS ns1.mydomain.net.in. ns1.mydomain.net.in. 86400 IN NS ns2.mydomain.net.in. ns1.mydomain.net.in. IN A 90.1.1.90 ns2.mydomain.net.in. IN A 90.1.1.90 ;localhost.ns1.mydomain.net.in. IN A 127.0.0.1 ;ns1.mydomain.net.in. IN MX 0 ns1.mydomain.net.in. ;mail IN CNAME ns1.mydomain.net.in. ;www IN CNAME ns1.mydomain.net.in. ;ftp IN CNAME ns1.mydomain.net.in.
NS2
$TTL 14400 @ 86400 IN SOA ns2.mydomain.net.in. wemaster.mydomain.net.in. ( 2014013001 ; serial, todays date+todays 86400 ; refresh, seconds 7200 ; retry, seconds 3600000 ; expire, seconds 86400 ) ; minimum, seconds
ns2.mydomain.net.in. 86400 IN NS ns2.mydomain.net.in. ns2.mydomain.net.in. 86400 IN NS ns1.mydomain.net.in. ns2.mydomain.net.in. IN A 90.1.1.90 ns1.mydomain.net.in. IN A 90.1.1.90 ;localhost.ns2.mydomain.net.in. IN A 127.0.0.1 ;ns2.mydomain.net.in. IN MX 0 ns1.mydomain.net.in. ;mail IN CNAME ns2.mydomain.net.in. ;www IN CNAME ns2.mydomain.net.in. ;ftp IN CNAME ns2.mydomain.net.in.
Thanks for this guide…
but one question is arise
where we set website path in DNS configurations files… for example- my web site located in server (/var/www/html/example.com) and now my web site open (http://server-ip/example.com)