DNS for Web Hosting (Or: What the heck is a glue record?)

Has there ever been a service that is more fraught with confusion, misconfiguration, and hair-pulling all-nighters than DNS? Maybe, but that was a rhetorical question. DNS confuses a lot of new system administrators (and, if you find yourself thinking about DNS, it means you’ve become a system administrator…but, don’t worry, I’m here to help you through your transition from normal person to keeper of UNIX wisdom).

In this article, I’m going to show you how to do some interesting things with DNS, which are all the steps you need to take for springing a brand new domain name into existence so you can put your awesome website on it! Here’s what this article will teach you how to do:

  • Search for and register a new domain at Namecheap.com (steps will be very similar at any registrar, but Namecheap is quite good and low-cost)
  • Configure initial records using the registrars name servers
  • Setup a new name server using BIND
  • Setup a new zone with address and name server (NS) records
  • Setup glue records at the registrar
  • Test your new DNS zone using command line tools

What I won’t cover in this article is setting up BIND using Webmin. I’ve written about that on a few occasions over the years, and the most recent writings are in the Webmin wiki in the BIND DNS Server module documentation , as well as the BIND tutorials section. Jamie also wrote an introduction to the Domain Name System. This post is somewhat more geared toward beginners than most of those, and also covers things that aren’t really within the scope of Webmin, like registering a name and setting up glue records at the registrar. But, once you’ve wrapped your head around the basics of DNS, you may find that Webmin (and the related documentation) can make your job administering DNS servers a little easier and faster, particularly if you have a lot of zones to manage.

Search and Register a Domain Name

While picking the perfect domain name is out of the scope of this article, there are many domain-picker tools on the web to help you out. I tend to prefer to just brainstorm for an hour or two on the theme of my business or project, and come up with a half dozen or more good enough names.

Names should be as short as you can find (but don’t worry about getting a <5 letter domain, because a lot of those are already taken, even the nonsense words). Names should probably not use special characters, though the dash, “-“, is legal in domain names and is sometimes used, even for business sites, but it makes your domain harder to type on mobile devices. Making it difficult to type on a mobile device is a big negative, because more people today browse the web on mobile devices than on traditional computers. Numbers should also be avoided if possible for the same reason. Unicode characters can be used, but you shouldn’t use them unless you are serving a market that regularly uses Unicode domain names, such as China. Setting up Unicode domain names using the International Domain Name (IDN) standard won’t be covered here, but I may address it in a future post.

Once you’ve settled on some possible names or used a domain finding tool to find the name you want and that you know is available, create an account at Namecheap, or your preferred registrar. Once logged in, click on Domains->Registration.

Namecheap registration form

Enter the first part of the domain name you want. I want linuxfortheweb.com, because I’m working on a new book about system administration for web servers and Linux For The Web is a pretty snappy working title. You can leave off the .com, and Namecheap will list all of the popular Top Level Domains (like .com, .org, .net, .io, .biz, .co, etc.), and you can see whether they’re available. In my case, linuxfortheweb.com was available, so I grabbed it!

If the name you want isn’t available in your preferred TLD, don’t despair. Other TLDs are quite commonly used these days, and users aren’t terribly confused by an odd TLD. It’s true that a .com is preferred for businesses and such, and if it’s important to you to have a .com, you’ll need to try some of the other names you brainstormed earlier, or find one you can buy from its current owner.

Once you select the domain you want, you can go through the rest of the checkout process. Make sure all of your contact information is the information you want to have on your public whois record (or choose to use the privacy features provided by most registrars including Namecheap). The whois record is normally public and visible to anyone on the Internet; we will talk about how to query whois records using command line tools later in this article. Most registrars will act as a proxy on your behalf and provide their contact information instead of yours, and they will forward email to you when they receive any intended for the owner of the domain. This is usually a low cost service, but I rarely bother with it, as my information is all over the Internet already.

After completing the registration process, and paying for the domain, you can configure some initial records. You have a couple of options when setting up DNS: Many registrars will host your DNS zones for you, which is simple and requires very little back end knowledge; or, you can delegate the zone to your hosting provider DNS servers; or, and this is my eventual goal in this article, you can host them on your own DNS server running BIND. We’ll talk about the advantages and disadvantages of each approach as we go along.

Creating Host Records At The Registrar

The simplest way to get a domain name functioning is often to let your registrar handle DNS. This can be sub-optimal for a number of reasons, but it’ll get you started without having to install and configure your own DNS server. I will talk more about why this might be limiting, and I will show you how to setup your own name server later in this article.

At Namecheap, it is not immediately obvious where to go, as the label for the option may be confusing if you don’t know the terminology. To edit DNS records at Namecheap, click on the domain in the list of domains. This will take you to the dashboard for that domain name.

Look in the left menu for the item labeled All Host Records and click it.

All Host Records image

Clicking All Host Records at Namecheap

This will take you to a simple UI for creating new host records in your zone. To start with, it will only have a couple of records, plus the default mail forwarding option selected. I’ve edited my zone to look like the following, and I’ll explain below what each field and value means.

Domain records configuration at Namecheap

Domain records at Namecheap.com

These two items, @ and www, are default records that are pre-configured to point to the Namecheap parking service page. We want to change this immediately, if not sooner, to something we own and get value from, even if it’s just our own landing page that says “Coming Soon!”.

The @ symbol simply means, “the domain name itself”, in this case linuxfortheweb.com. I have filled in the IP of my web server in the IP Address/URL field. Setting up a web server to listen on this address won’t be covered here, but a later article will walk you through how to do it, and there’s a lot of resources on the web to help as well (or you could install the Open Source Virtualmin control panel and it would do most of the work for you).

The Record Type field indicates the type of record this will be. The DNS standard has defined a number of record types to help clients and other DNS servers find specific information about a zone, such as addresses, mail server names, name server names, etc. I will talk more about some of the types of records in a moment, but for now we only care about A records, or Address records.

An Address Record is a record type that maps a name, like “www.linuxfortheweb.com”, to an address, like

You may also see an automatically-generated SPF record that is created by Namecheap when you choose to use their mail forwarding service. We won’t be keeping this for long, but it doesn’t hurt anything to leave it alone.

For now, you can save your new records.

Now, we’d like to be able to test this, but it can take as long as a couple of hours for name registrars DNS servers to update, so we probably can’t actually test immediately. But, if you take a coffee/tea break, or have a walk around the block, you might be able to come back and see it working. Just for fun, here’s the basic testing tools for DNS:

On Linux systems, you would use the host command (which is provided by the bind-utils package on CentOS):

[joe@alice ~]$ host linuxfortheweb.com
linuxfortheweb.com has address
linuxfortheweb.com mail is handled by 20 eforward5.registrar-servers.com.
linuxfortheweb.com mail is handled by 10 eforward1.registrar-servers.com.

The host command automatically includes MX records, by default. We can ignore that information for the time being. What’s important is that we’re getting back the address I put into the A record for @ earlier.

On a Windows system, you would use the nslookup command:

C:\>nslookup linuxfortheweb.com
Default server: dns1.registrar-servers.com

Cool, it looks like everything is working as expected. If you really wanted to keep things simple, you could stop here. This is already providing basic name service for your domain, and it will point users to your address when they browse to your domain name. That was pretty easy, huh? But, most people with serious aspirations to build awesome things on the web will want to have more complete control of their DNS information. Or, if you’re somewhere in the middle, and just want to add a mail server, so you can send and receive mail, the Namecheap interface makes that pretty easy. But, for this article, I’d like to skip that and move right on to setting up our own name servers.

Delegation Is Delectable!

Since you continued reading, I’ll assume you want all the power and responsibility that running your own DNS server provides. So, we have to do something pretty tricky: Tell the world how to find addresses in our domain.

Does that seem simple? If so, that probably means I haven’t explained enough about how DNS works.

In its simplest form, DNS is provided by a hierarchy of name servers on the Internet, with the root name servers at the top of the hierarchy. The root name servers delegate requests for zones (a zone is a collection of records under one domain name) to the authoritative name server for that zone. The root name server information is distributed as a list (technically, modern systems have a hints file, which just tells the DNS resolver client how to find the full list of root name servers and the zones they are authoritative for). The root name servers very rarely change IP addresses, and are known to clients because the lists are distributed with operating systems. You can see what the hint file looks like at the IANA website. You don’t need to understand the contents of this file yet.

A name lookup request begins with the DNS resolver on your computer or device breaking up the name into its components, beginning with the top-level domain. It will then request the authoritative server for the next level of the domain from the root name server for the top-level domain, and each level of the name will be queried until a server that is authoritative for that name is found. In my case, with the domain linuxfortheweb.com, the top-level domain is com, and so a client would ask the servers for the com domain about the name linuxfortheweb within the com zone. The root name server for the com zone would then delegate the request to the name servers that are authoritative for my name, which based on the steps we took above are currently the name servers at Namecheap. How does it know what servers to delegate that request to? This the job of the domain registrar. They provide the delegation information to the root name servers.

At this point, the request path is pretty simple. The client checks the root name server, the request is delegated to the Namecheap servers, the client asks one of the registrar servers (and trying a different one if the first doesn’t respond in a timely fashion), and the registrar server replies by sending back the requested record (since we’re trying to keep this simple, we’re talking about an address record mapping the name linuxfortheweb.com to the IP address

Now we want to delegate that one step further, and have the client resolver contact our server. For that we need the so-called glue record to point to our name servers. “But, but, but I don’t have any name servers!” I hear you cry. And, to that I say, “Not yet. But, you will.”

Go Forth And Install BIND

Now, you’re gonna get serious about being system administrators by setting up your own name server. You’ll need a server, or, rather, two servers (though you can fake it with just one as long as you have two IP addresses for it). Nearly any Linux or BSD server will do, as BIND is not a very resource intensive service, as long as it is only answering requests for your own zones. You could use a virtual machine or a physical server. As long as it has a reliable always-on connection to the Internet and a fixed IP address, you can use it as a name server. I have three virtual machines specifically for DNS service, and two are configured to automatically be slave servers to the first one. I will show you how to do that in a later article.

Start by installing the BIND package for your OS.

On CentOS/RHEL or other yum-based operating systems:

# yum install bind

Or, on Debian/Ubuntu:

# apt-get install bind9

Or, on FreeBSD (assuming you are using pkgng, the new binary package manager):

# pkg install bind9

Or, on Solaris (assuming you have setup to use OpenCSW):

# pkgutil -i bind9

Now, edit the named.conf using your favorite text editor (I like vim!). This file may be in a variety of places, depending on your OS; on CentOS it is in /etc/named.conf. There will be a lot of stuff in the configuration file that is beyond the scope of this article, but at the bottom add the following (modified to suit your domain and other name server IP addresses, of course):

zone "linuxfortheweb.com" {
  type master;
  file "/var/named/linuxfortheweb.com.hosts";
  also-notify {;
  allow-transfer {;
  notify yes;
Be careful to adjust the file paths to suit your OS. My example is on a CentOS 7 system. I believe Debian and Ubuntu will also put the BIND hosts files into /var/named, but it’s also possible to run BIND in a chroot, and some operating systems may use different standard locations. It’s nice to do things in the way that is common for your OS so that other administrators will know where to look for things.

This snippet of code instantiates a new zone called linuxfortheweb.com.

It is a master zone, which means it will be the source from which any other slaves configured later get their information.

The file directive instructs BIND where to find the host records file for this zone.

The also-notify directive indicates that this server will notify another DNS server at the provided IP address of changes to the zone.

The allow-transfer directive indicates that this server should allow the server at the provided IP address to request a transfer of this zone. The combination of this option and the previous are necessary steps to permit another DNS server to act as a slave for this zone.

The notify directive instructs BIND to notify the servers indicated in the also-notify section when changes to the zone have been made.

Next, edit the zone file (/var/named/linuxfortheweb.com.hosts in my example), and insert the following:

$ttl 38400
linuxfortheweb.com. IN SOA ns0.linuxfortheweb.com. joe.linuxfortheweb.com. (
38400 )

This is the first part of the zone file, sort of a preamble. It includes information that applies to the zone itself. Line-by-line, this snippet contains the following:

$ttl– The default time-to-live for this zone. If not specified in an individual record, this will be the time-to-live for that record. Other name servers may cache records from this zone for this length of time (in seconds in this case), or as long as the individual record TTL, whichever is longer.

SOA– The SOA, or Start Of Authority, recourse record is actually a special record type (like A records we already discussed some). Because it starts with linuxfortheweb.com., this SOA record applies to the linuxfortheweb.com zone. If other subdomains within this zone were to be delegated to other servers, or other zone files on this system, they would have their own SOA. The IN simply stands for Internet and can generally be ignored, as the vast majority of records you deal with (maybe ever) will be IN records.

The next two fields within the SOA record are the primary name server (generally the master name server), and the email address of the administrator of the zone, with the @ symbol converted to a . (period), since @ has special significance in a zone file.

Then the series of numbers are, in the order in which they appear:

  1. Serial number – A unique identifying number for this zone. It must always increment (get higher) every time the zone is updated. A popular convention is to use a year:month:day:number of modifications that day format.
  2. Time-to-refresh – How often a secondary, or slave server checks its zone database files against a master server.
  3. Time-to-retry – How long a secondary server waits before trying to contact a master server, after a failed transfer.
  4. Time-to-expire – When the secondary server will discard all zone data, if the master cannot be reached.
  5. Minimum-TTL – In BIND 9 the minimum time is used to define how long a negative answer is cached. Old BIND versions used this value differently, but you shouldn’t be using a BIND version that old.

These can generally simply be ignored, as long as they are something reasonably sane, and serial number always increases. But, I wanted you to know what they mean, so they aren’t intimidating. They are all necessary, even if we don’t have to think hard about them.

The next part of the zone hosts file is:

@                        IN A
www.linuxfortheweb.com.  IN A
mail.linuxfortheweb.com. IN A
@                        IN MX 5 mail.linuxfortheweb.com.
ns1.linuxfortheweb.com.  IN A
ns2.linuxfortheweb.com.  IN A
@                        IN NS   ns0.linuxfortheweb.com.
@                        IN NS   ns1.linuxfortheweb.com.

These are the various mandatory records for this zone. This is pretty much the minimum set of records you’ll need for a full-featured web hosting server and for a domain that you accept email for.

Breaking it down, the A records are, as previously mentioned, Address records. They indicate the IP address of the hostname in question (remember that @ is merely shorthand for the zone name itself, or linuxfortheweb.com. in this case).

The MX record indicates that mail for @ (linuxfortheweb.com.) will be accepted by a host named mail.linuxfortheweb.com.(which coincidentally shares an IP with the web server, but doesn’t need to). The number 5 is a priority. If we had multiple MX records, we could indicate the order in which they will be attempted. The lower the number, the higher its priority; i.e. an MX record with a priority of 10 would act as a backup to the one with a 5, and would only be contacted if the priority 5 server does not respond.

The final type of record in this snippet is the NS, or name server, record. This is used to notify clients of which servers to contact to resolve name within this zone (@), but it could also be used to delegate subdomains into other zones served by other name servers. This information should match the glue records at your registrar, which we will cover in more detail in the next section.

One other useful thing to know about BIND hosts files: A name without a . (period) at the end will have the zone name appended to it. So, mail would become mail.linuxfortheweb.com. There is no real reason to prefer one form or the other, but I personally like to use the full name. Whatever you do, you should do it consistently, so it is easier to read and easier for future administrators (including yourself!) to make sense of it quickly.

There are several other types of record, and several other components that could be included in this file, but I will save them for a later article. The purpose of this article is to get your name server up and running with a minimum configuration for web hosting. And, just the lines in the two snippets I’ve provided above (adjusted appropriately for your domain and your IP address(es)) will do the job.

You can, at this point, save your work, and start up your name server.

On CentOS 7 and new versions of Debian and Ubuntu (whenever they begin shipping systemd), you can do that with:

# systemctl start named

On CentOS 6 and below, you would use:

# service named start

On current and older Debian/Ubuntu versions:

# /etc/init.d/bind9 restart

On FreeBSD:

# /usr/local/etc/rc.d/named.sh start

On Solaris:

# srvadm enable bind

A Little More Testing

Let’s return to our basic testing tools, and see if our new DNS server is actually answering queries for this zone. We’ll use one extra option to the host command to force it to query the local server rather than going out and checking with the root name server and the registrar (since we haven’t told them about our new server yet).

$ host linuxfortheweb.com localhost
Using domain server:
Name: localhost

linuxfortheweb.com has address
linuxfortheweb.com mail is handled by 5 mail.linuxfortheweb.com.

Excellent! That’s exactly what we want to see. Only one more step to bring our first name server online. (And a few more steps to setup a slave DNS server, but that will be for another day and another post.)

This Is Where The Glue Records Come In

OK, now that you’ve configured a name server, you can tell the world how to use it by configuring the glue records at your registrar. I’ll also finally explain why I created those two extra A records for ns0.linuxfortheweb.com and ns1.linuxfortheweb.com very early in this article.

First, what is a glue record? It is a record that allows your name servers for your domain to be within the zone itself, because it is a record stored at your domain registry and contains the IP addresses of the name servers. For example, if I wanted my domain names within linuxfortheweb.com to be hosted on ns0.linuxfortheweb.com and ns1.linuxfortheweb.com I would need glue records at Namecheap to tell clients what the IP addresses were for those names. Otherwise, there would be a loop when the client wants to look up the name, that would go something like this:

Client to root name servers: What’s the name server for the linuxfortheweb.com zone?

Root Name Server: ns1.linuxfortheweb.com

Client to root name servers: That’s a name in the zone I was asking about! Now what?

Glue records allow the registrar to provide the IP information to the client, breaking this loop and allowing the client to know how to contact the name servers for this domain.

Some registrars will allow you to simply create these records by telling them what the IP address for each of your name servers is. But, some will only allow you to enter a name…so, you’re in the tricky situation of needing DNS service before you can set up DNS service! Luckily, Namecheap allows you to enter names and their IP addresses when creating glue records, and then allows you to assign those as the name servers authoritative for your domain. This makes the process pretty painless, if still a little confusing for newbies.

Creating Glue Records At Namecheap


In the Namecheap dashboard, click on the domain name to open the dashboard for that domain, and click the menu item labeled Nameserver Registration in the left menu.

This will open a simple form, where you can associated name server names within your domain to IP addresses.

Namecheap glue record editing form

Editing glue records at namecheap

Here, you’ll fill in the form IP addresses of your name servers. You’ll need at least two name servers. You can “fake” it by having two names on the same DNS server, but if you’re resorting to that, it may be recommended to stick with letting your registrar or a third party DNS server provide your DNS service until your needs have grown to support two DNS servers.

After you’ve saved this, and given it a little time to propagate, your DNS servers should be live. Take a break for a little while and come back for the final section where we’ll go through some tools to test our new DNS server(s).

Test Time!

Check the Glue Records

First, check to be sure the world now knows about your DNS servers. You can use a variety of tools for this, but I usually just use the whois command.

$ whois linuxfortheweb.com

This will produce a long list of information, including contact details for your zone, the registrar information, and registration and expiration date. For our purposes, we just want the field labeled Name Server:.


Success! I now see that the glue records are active. You can also use the dig command with the NS option to query any of the root name servers for your TLD to find out name server information. In a later post I’ll talk more about DNS troubleshooting tools and tactics, as well as other DNS-related topics.

Check the NS Records

The host command used earlier has a number of options for easily testing a variety of aspects of DNS. To check name server records, the -t ns option can be used:

$ host -t ns linuxfortheweb.com
linuxfortheweb.com name server ns1.linuxfortheweb.com.
linuxfortheweb.com name server ns2.linuxfortheweb.com.

Once again, we have the results we were expecting. Cool!

So, let’s make sure those servers are responding as they should be:

$ host linuxfortheweb.com ns1.linuxfortheweb.com
Using domain server:
Name: ns1.linuxfortheweb.com

linuxfortheweb.com has address

Pow! Just what we wanted to see.

Alright, this has been quite a long article, but hopefully you’ll find setting up a new name server a little less intimidating. In the next installment on DNS, I’ll cover setting up slave servers, and touch on some other record types. I’ll also talk about some of the more advanced DNS management features of Webmin, including automatic slave server configuration.