Setup a DNS Nameserver Using NSD (Linux)
#1
The little 128MB VPSes you can get free here at freevps.us or for $10-$15/year are perfect for serving DNS. A nameserver does not take much memory or CPU. Indeed, once it's setup, you'll probably find your nameserver isn't doing much at all, because so much is cached with other DNS servers. It just serves as the authority.

This tutorial is geared towards a super-simple DNS setup. We'll be using NSD, a very lightweight DNS server. While the most-widely used package is BIND, BIND supports every possible option and feature, which is overkill for most people. If you just want to setup DNS for your servers and act as the authority for your domain, NSD is a much simpler solution. I'm also going to give you the basics and defaults, without getting into explaining every single option. DNS can be complex! But this will get you going on a basic setup.

Things I won't be covering:
  • reverse DNS
  • zone transfers
  • MX records
    • Here is how we'll configure NSD:
      • Two servers, each of which listen for DNS on their public interfaces.
      • /etc/nsd/nsd.conf will contain the NSD configuration specific to that server
      • /etc/nsd/zones will contain all the zone files (the DNS records for your domain(s))
      • we'll use rsync to keep both servers in sync. NSD supports zone transfers, but it complicates the setup and is unnecessary if all you're doing is DNS for a few domains and it doesn't change much. If you have a lot of DNS changes and a complex setup, then this tutorial isn't for you :-)
        • In this example, we're setting up DNS for this configuration:

          Code:
          Nameserver #1: ns1.example.com at 1.23.45.67
          Nameserver #2: ns2.example.com at 1.23.45.68
          bigvps.example.com is a web server at 1.23.45.100
          www.example.com is an alias for bigvps

          Of course, you can't host DNS for example.com - only the owner of example.com can. So replace 'example.com' with your own domain.

          I'm using CentOS but the procedure is very similar for other distros.

          Step One: Install nsd

          We'll start on ns1. I recommend using your distro's package manager. For CentOS, you will need to use the EPEL repo.

          Code:
          CentOS 6: rpm -Uvh http://download.fedora.redhat.com/pub/epel/6/i386/epel-release-6-5.noarch.rpm
          CentOS 5: rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
          and then

          Code:
          yum install nsd
          chkconfig nsd on
          Step Two: Open fireall ports

          If you're not using a firewall, you can skip this. If you're using iptables, then you'll need to open port 53 for udp. The exact configuration will depend on how you've setup your firewall, but it'll be something that looks like this:

          Code:
          iptables -A INPUT -p udp --dport 53 -j ACCEPT
          Of course, if you're firewalling outgoing as well, you'd need to open a port on OUTPUT, too.

          Step Three: Configure nsd.conf

          The main config file is in /etc/nsd/nsd.conf. Here is an example. You should probably save the file that comes with nsd for future reference:

          Code:
          cp /etc/nsd/nsd.conf /etc/nsd/nsd.conf.dist
          Now edit /etc/nsd/nsd.conf as follows:

          Code:
          # The 'server:' section is the configuration for the DNS server
          server:
              # this is the IP address it will listen on for DNS requests
              # change this to the public-facing IP address of your VPS
              ip-address: 1.23.45.67
              
              # no need to tell people what version we're running
              hide-version: yes

              # the database to use
              database: "/var/lib/nsd/nsd.db"

              # log file
              logfile: "/var/log/nsd.log"

              # Number of NSD servers to fork.
              server-count: 1

          # we'll use a separate "zone list" file to make rsync easier
          include: "/etc/nsd/zones/zone_list.conf"
          Very simple!

          Step Four: Configure zone_list.conf

          This file is simply a list of all the zones. You could put this info in the main nsd.conf file, but our goal is to use rsync to keep the two nameservers in sync. We don't want to rsync nsd.conf itself, because the ip-address field is unique to each server. We only want to rsync what changes, which is the zone files. So we'll be rsyncing the zone files and the zone_list.conf, which is a list of the zone files.

          The zone files can be owned by nsd or root. I have mine owned by root, so nsd can read them but not change them (in case that account is ever compromised).

          Code:
          mkdir /etc/nsd/zones
          vi /etc/nsd/zones/zone_list.conf
          zone_list.conf should look like this:

          Code:
          zone:
              name: example.com
              zonefile: /etc/nsd/zones/example.com
          This means "there will be a zone named example.com, and you can find its records in /etc/nsd/zones/example.com". You can define as many zones here as you want.

          Step Four: Lather, Rinse, Repeat

          Do steps 1-3 for ns2.example.com. The only thing you need to change is the ip-address line in /etc/nsd/nsd.conf

          Step Five: Configure zone_list.conf

          This is probably the most complicated part. The format of the zone file is the same one BIND uses.

          Back on ns1, edit /etc/nsd/zones/example.com:

          Code:
          $ORIGIN example.com.  
          $TTL 3600

          @    IN     SOA     ns1.example.com. admin.example.com. (
                     2011102301  ; serial number
                     28800       ; Refresh
                     7200        ; Retry
                     864000      ; Expire
                     86400       ; Min TTL
                     )

                          IN    NS      ns1.example.com.
                          IN    NS      ns2.example.com.

          ns1           IN     A        1.23.45.67
          ns2           IN     A        1.23.45.68
          bigvps       IN     A        1.23.45.100
          www         IN     CNAME bigvps
          Well, what a lot of arcane syntax! Let's take it line by line, but first, let me point out something very important: the dots at the end of domain names as shown here are very important. When you say "ns1.example.com." (with the trailing dot) it means "treat that as the FQDN). If you just typed "ns1.example.com" you'd actually mean "ns1.example.com.example.com" which is not what you want :-)

          Now let's look through the file:

          Code:
          $ORIGIN example.com.
          "This is the origin of all DNS information on example.com". This line must be first. Again, note the trailing dot.

          Code:
          $TTL 3600
          TTL means "time to live" which means "other DNS servers, you should cache this for 3600 seconds (one hour)". That is a good setting.

          Code:
          @    IN     SOA     ns1.example.com. admin.example.com. (
          "SOA" is "Start of Authority". @ is shorthand for "example.com." The two names that follow it are the primary DNS server and then an email contact, rewritten in a dot notation format. In this case, admin.example.com. means "admin@example.com".

          Code:
          2011102301  ; serial number
                     28800       ; Refresh
                     7200        ; Retry
                     864000      ; Expire
                     86400       ; Min TTL
                     )
          Since we're not doing zone transfers, only the 'serial number' really matters. But it's important! Every time you change this file, you need to increment the serial number.

          An old trick is to use a YYYYMMDDXX format, so the first change on October 23, 2011 is 2011102301, the second change on that day would be 2011102302, etc. You could of course just use 1, 2, 3, etc., but the date format is commonly done.

          The point of the serial number increment is that this tells other DNS resolvers (and yours) if the file has changed. Otherwise, they don't bother reparsing it.

          I'm not going to go into the other records (refresh, retry, etc.) If you want to read up on them, try this link:

          http://www.zytrax.com/books/dns/ch8/soa.html

          Code:
                  IN    NS      ns1.example.com.
                  IN    NS      ns2.example.com.
          These define what nameservers are valid for this domain. You need to have at least two (at least, you really should :-)

          Code:
          ns1           IN     A        1.23.45.67
          ns2           IN     A        1.23.45.68
          bigvps       IN     A        1.23.45.100
          www         IN     CNAME bigvps
          Finally, we get into the actual records. Here we've defined three "A" records and one "CNAME" record. There are other types, but these are the most common. MX (for mail exchange) is the next most common type.

          An A record is a forward DNS record. In this case, if you ask the nameserver "what is the IP address for bigvps.example.com" it will tell you "1.23.45.100". We've defined three such records here.

          A CNAME record is an alias. You can have as many aliases as you want. For example, you might have Apache/NGINX setup to host forum.example.com, http://www.example.com, and gallery.example.com on the same host:

          Code:
          bigvps    IN    A    1.23.45.100
          www        IN CNAME bigvps
          forum     IN CNAME bigvps
          gallery    IN CNAME bigvps
          Step Six: rsync

          Now you've finished the zone list setup on ns1. You should have an entry for example.com in your /etc/nsd/zones/zone_list.conf file, and the above DNS record in /etc/nsd/zones/example.com file. You want to get these files to ns2. From ns1:

          Code:
          cd /etc/nsd
          rsync -avz zones ns2:/etc/nsd
          You could also use scp if you wished.

          Step Seven: start nsd

          On ns1, we first need to "compile" the zones and then we can start:

          Code:
          nsdc rebuild
          /etc/init.d/nsd start

          Do the same thing on ns2.

          Later when you add more records, you can do this:
          • Modify on ns1. Don't forget to increment serial numbers :-) If you add a new domain (zone), put the corresponding zone: entry in /etc/nsd/zones/zone_list.conf
          • rsync to ns2 to keep it in sync
          • On both ns1 and ns2, execute "nsdc rebuild" and "nsdc reload". This will load the changes without having to stop/start nsd.
            • Step Eight: Your Registrar

              You'll need to use your registrar's web site to set the nameservers for your domain. For example.com, you need to define both the nameserver (ns1.example.com) and the IP address. For other domains you want to use ns1.example.com/ns2.example.com as DNS authorities, you just specify the DNS servers. So, for example, if you bought yahoo.com and wanted to use ns1.example.com and ns2.example.com to do the DNS, you'd set the DNS nameservers for yahoo.com to ns1.example.com and ns2.example.com (and of course create the zone file/zone list entry).

              I hope you've found this tutorial useful! If you did, please give me some reputation points.

VPSadvice.com - discuss VPS providers, read reviews, get help, share opinions
Reply
#2
Nice tutorial, but can this be done in a single VPS with two IPs?
Because $10 x 2(at least) I think is not quite cheap for your own DNS only service.
Thanks FreeVPS.us! for the free VPS and for all the knowledge that I've learned here at the forum.
Reply
#3
(10-25-2011, 01:28 PM)carlo Wrote:  Nice tutorial, but can this be done in a single VPS with two IPs?
Because $10 x 2(at least) I think is not quite cheap for your own DNS only service.

Sure. Just have two IPs and set them as ip-address in your nsd.conf. Then create each as ns1 and ns2 and register with your registrar.

Of course, the idea of having two nameservers with the registrar is to have redundancy, but if you only have one VPS serving your web site, it probably doesn't matter much if DNS is also offline Big Grin One exception would be if you're using Google Mail for your domain, because senders need to look at the MX records.
VPSadvice.com - discuss VPS providers, read reviews, get help, share opinions
Reply
#4
Thanks for the share, i was searching for something like this! Going to Try it out later.
Reply
#5
I've done this on a two 32MB VPS's, i think i might start using it instead of ClouDNS.net...
Reply
#6
Thanks, this was a great tutorial. I got to bookmark this. Smile

Repped.
Reply
#7
(10-29-2011, 07:11 PM)linuxthefish Wrote:  I've done this on a two 32MB VPS's, i think i might start using it instead of ClouDNS.net...

32MB VPS's? WTF lol. Btw nice tutorial Raindog. That really helped me out.
Reply
#8
Signed up just to say THANKS for the great explanation.
I was trying to set this up on a Linode ubuntu server, and this helped.
I do have a question though: How would you set up individual hosted sites?
Do they need the SOA record too or just an A record?

For instance, let's say the domain I want to use for the nameservers is ourdomain.com
so I would have ns1.ourdomain.com and ns2.ourdomain.com as nameservers.
But we are also hosting clientsite.com which will use these two nameservers.
What is the pattern for setting that up?
Reply
#9
You can only have 1 SOA record per zone. Create a new zone conf, i.e. something like /etc/nsd/zones/clientsite.com
Just set the nameservers to ns1.ourdomain.com and ns2.ourdomain.com
Then create the necessary A records that you require.
Reply
#10
i'm sorry, but what is the point of setting up a dns server on your vps?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)