Skip to main content

How to Set Up Virtual Hosts on Apache2 and Create a DNS Zone Using Bind9

  • Author:
  • Updated date:

Apache, Bind and Debian

For the duration of this tutorial, I will be describing configuration required for a Debian or Ubuntu server. Configuration is slightly different in other distributions, but the basics hold true.

Apache2 is an application that runs on a PC, enabling you to host websites from the computer. The web server can be configured for windows, but I would personally recommend using IIS on a windows web server. Apache2 is the web server of choice, when hosting websites on a Linux server.

Bind9 is an application that enables your computer to function as a DNS server. DNS enables other computers to convert a domain name into the IP address for the server. Like Apache2, Bind can be installed on Windows, but again, I would recommend that you configure Microsoft own DNS option, if you are running a Windows DNS server.

Debian is a distribution of the Linux kernel. It is one of the better choices of distribution when setting up a web server. Ubuntu is another distribution, that branched away from Debian. Ubuntu is generally used as a desktop OS, but server versions are available. With regards to installation and configuration of web and DNS, both work in the same way.

Installation of Apache2 and Bind9, and a note on Firewalls.

In order to have a functioning Web and DNS server, you first need to install the binaries. To do this, use your distributions method of application installs (e.g. apt-get on Debian and Ubuntu), or download the package from the Internet, and - if required - compile the application.

As root on a Debian server, enter the following commands, and when prompted, install the required dependencies.

# apt-get update
# apt-get install apache2
# apt-get install bind9

Now that you have a DNS server, you will need to update your /etc/resolv.conf file, and add the IP address for the server.

If your web server is running a firewall, you will also need to make sure that the HTTP (80 and 443) and DNS (53) ports are open.

You should now have a web server running Bind9 and Apache2. You can check the web server by opening an Internet browser, and typing the IP address for your server. You should see a web page saying

"It Works"

You may also want to install and configure PHP and MySQL if you wish to create dynamic, database driven websites for your server.

Configuring a domain using Bind9

While still logged in as root, navigate to the bind directory inside /etc and list the contents

# cd /etc/bind
# ls

You should see several files prefixed db. These are the default DNS zones that are created when you install Bind9. This tutorial is aimed at configuring an Internet domain, so we will leave these zones, and create new ones. You should also see a file called named.conf.local. This is a Debian configuration file that is included by the named.conf file. It is best to edit this file, rather than named.conf. If you are not using Debian or Ubuntu, you will need to edit named.conf

Before we edit that file, we first need to create our DNS zone. First create a directory to place your zone files, and then copy one of the existing db files into the your directory, with a name appropriate to your website. Once copied, navigate to the new directory and open the file using your text editor of choice (eg nano).

# mkdir hostedzones
# cp ./db.local hostedzones/db.mywebsite
# cd hostedzones
# nano db.mywebsite

You should see something like this.

; BIND data file for local loopback interface ; $TTL 604800 @ IN SOA localhost. root.localhost. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS localhost. @ IN A @ IN AAAA ::1

First off, you will want to edit the zone data file so that it is appropriate for your website

; BIND data file for ; $ORIGIN $TTL 604800 @ IN SOA ( 2009120101 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; IN NS IN NS IN MX 10 localhost IN A IN A ns1 IN A ns2 IN A www IN A ftp IN A mail IN A boards IN CNAME www

Scroll to Continue

So, what did I add and why?

First, I edited the comment, this has no functionality other than making it easier to know which DNS zone file you are looking at.

Next, I added the $ORIGIN for the domain. This should be your domain name (without the www prefix) and should be terminated with a period. If you forget this the zone will not work.

SOA stands for Start of Authority, it should contain the name you have chosen for the primary nameserver and the administration email for this zone. Both of these must be followed by a period. The format of the email address should replace the @ symbol with a dot (.)

When you register a domain name you would normally point it to existing nameservers. However, you must configure - at least - one domain with what is know as a glue or sticky record. You should be able to set this through the control panel for your registrar. The sticky record will store the IP addresses for the primary and secondary nameservers. If you are going to be hosting multiple domains, you do not - need - to set the glue records for each domain. You will be able to use your original primary nameserver when configuring other domains.

I also changed the serial from 1 to 2009120101. Every time you change a DNS zone file, this number needs to be incrimented. This is critical, as, without it DNS servers including your own, will not know that you have changed the zone file. Changing the serial to YYYYMMDD## makes it a little easier to know when the file was last updated.

Before moving on to the records, I just wanted to mention the $TTL value which I did not change. TTL stands for Time To Live, and the number after is the number of seconds a domain server on the Internet will cache your information for. If you are about to migrate a domain between servers, you could change this value to a smaller number to speed up the time it takes for the new DNS info to propagate around the Internet. If you are not in the process of migrating a domain between servers, leave this as default.

Nameserver (NS) Records
The first two records tell DNS server on the Internet the computer names for the primary and secondary DNS servers that have authority for the domain. These nameservers do not have to be part of the domain itself.

Mail (MX) Records
The next record tells the Internet where to send email for the domain. You can list multiple mail servers, the number after the MX indicating priority. A lower number, means a higher priority.

Anchor (A) Records
These are the primary anchors that point to your domain.

  • The first, localhost, has been pointed at That means that the address can only be accessed by the server itself.
  • Next, comes the domain name followed by a period. The number after, should be the public IP address for the webserver. This record will be used when people ping or browse to
  • If the domain requires nameservers, then they should be included as A records. In the example, sending a ping request to will return the IP address of the nameserver, in this case, that would be
  • Finally come the main sub-domains: www, ftp and mail. These should be pointed at the appropriate IP address for the web and email servers.

Canonical Name (CNAME) Records
These are sub-domains that are aliases of other servers within the domain. In the example, the boards sub-domain is an alias of the www sub-domain. This means, that a web browser will send to the same www webserver. However, a ping request to will return a response from

Once you have saved the zone file for the domain, you will need to tell bind where to find it. Navigate back up to the bind directory, and open named.conf.local (or named.conf if other distro)

# cd ../
# nano named.conf.local

Add the following configuration entry into the file. Change the content marked in bold, to appropriate values for the DNS zone you have added.

zone "" {
type master;
file "/etc/bind/hostedzones/db.mywebsite";

Once you have created the zone and updated the configuration, you will need to restart DNS on the server.

# /etc/init.d/bind9 reload

Once you have configured a zone for the domain in DNS and restarted bind9, you can test by performing an nslookup from the server itself, the rest of the internet may take a few days to catch up (depending on your TTL settings).

Configuring a VirtualHost using Apache2 Web Server

Once you have installed and configured the DNS zone file, you will need to create a VirtualHost for the domain in your Apache2 configuration. When configuring Apache2, the Debian and Ubuntu distributions are slightly more complicated than other distributions.

As root, navigate to the apache2 directory in /etc and list the contents.

# cd /etc/apache2/
# ls

There should be 2 configuration files called apache2.conf and httpd.conf. The first, contains basic configuration for the web server, the second your configuration for sites on the server. There may also be a directory called conf.d and, on Debian / Ubuntu a directory called sites-available.

Firstly, you need to tell the web server that you will be running multiple domains from the same port, on the same IP address. To do this, you will need to add a NameVirtualServer directive. This has probably been done for you by the Debian setup, but if not add the following to the top of the httpd.conf file, or the bottom of apache2.conf

NameVirtualHost *

You can add the VirtualHosts for your domains directly into the httpd.conf file, but I would recommend using individual files for each domain.

On other distributions you should create these files in the conf.d directory. In you don't have a conf.d directory, create one, and then add an entry into httpd.conf. This entry should occur after the NameVirtualHost directive.

Include conf.d/*.conf

Navigate to the sites-available/ directory, and, using your text editor of choice, open a file for your website.

# cd sites-available/
# nano mywebsite.conf

The next step is to write the VirtualHost entry itself.

<VirtualHost *> ServerAdmin ServerName ServerAlias DirectoryIndex index.php index.htm DocumentRoot /var/websites/ <Directory "/var/websites/"> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all </Directory> ErrorLog logs/ </VirtualHost>

So what exactly have we added?

Firstly, you need to include the opening and closing tags for the VirtualHost. The host used (in this case *) needs to have been set using a NameVirtualHost directive. If you wish to specify a specific IP address and port, replace the * with the appropriate info.

For example, if you want your website to respond to port 12345 on IP your opening tag will look like this <VirtualHost>

  • ServerAdmin - This directive should contain the email address for the domain administrator
  • ServerName - This is the main domain name used by the website. I would recommend using the domain without the www prefix, and include www as an alias. This means that if people browse to they will get to the webpage expected.
  • ServerAlias - This should include any other domain names used by the website. This is where you tell the web server to respond to the url.
  • DirectoryIndex - When you do not specify the name of the webpage, the web server will serve up your default index file. The order in which you list your index(es) will be the order Apache2 uses when trying to find the unspecified page.
  • DocumentRoot - This is the location on the web server where the HTML files for your website are located. In this example we have pointed to a folder created for this site /var/websites/
  • ErrorLog - This points to the error file for this website. When an HTTP error occurs, Apache2 will update this file. Including this directive is useful when trying to resolve problems with the web server.

The example also contains a <Directory> section. The configuration options included inside a Directory tag, will only be used when serving web pages in the directory listed. By default, you should at least include the root directory. You will notice, that unlike the DocumentRoot setting, the path to the directory should be surrounded by quotation marks.

  • Options - This directive contains the options appropriate to the directory. If an option is not listed, then it will not be available to the directory. Valid options include: Indexes, MultiViews and FollowSymlinks as well as a selection of others. Refer to the Apache2 documentation for a complete list of options.
  • AllowOverride - This directive tells the server if you wish to use .htaccess files or not. .htaccess files can contain directives that override the defaults set in the VirtualHost. This can be useful when setting up url rewriting as you will not need to restart the web server. If you do not wish to use this functionality, set the directive to None instead of All.
  • Order - This tells the web server whether to allow or deny access to the website. You would normally set this to allow,deny although if you wish to limit access to a directory to a particular IP address you may wish to set this directive to deny,allow
  • Allow from - This directive lets the web server know who can access the web site. Assuming you want everyone on the Internet to access the site, you will set this to all. If you have chosen to lock the directory down, you will include an IP address for the allowed users.

The Options that you chose for the directory are also important. There are many options available to an apache2 web server. The following are some of the more common ones.

  • Indexes - This option tells the web server that, in the absence of an index file, it should display the directory tree of the contents. If this directive is not set, users navigating to the directory without the index file, will get a Forbidden HTTP error. In my opinion, it is best to not set this for the main directory unless you need it. I have only included it in the example so that I can refer to it in here in the summary.
  • FollowSymLinks - Linux allows for symbolic links, these are shortcuts to files or directories located elsewhere on the server. This directive tell apache2 whether or not it should treat a symbolic link as content for the website.
  • MultiViews - This can be useful for SEO, or, if you don't not wish to make it obvious which server languages you are using. When this is set, Apache2 will allow you to remove the file extension. For example, I have a file called mywebpage.php. Using the MultiViews directive, a user could navigate to, and be served the file mywebpage.php. However, if there is also a directory called mywebpage/ apache2 will serve the content from that directory.

Once you have configured your VirtualHost, you will need to reload the apache2 configuration. But first, if you are using Debian / Ubuntu and have created your virtualhost as suggested, in the sites-available/ directory. You will want to enable the web page by creating a symbolic link to the sites-available/ config file in the sites-enabled/ directory.

# a2ensite mywebsite.conf

There are a selection of ways to restart apache2 or reload the config. On Debian / Ubuntu you will restart using the /etc/init.d/ directory. Other distributions may require you to use the apachectl binary to reload the config. If this is the case, google restarting apache2 on your distribution.

# /etc/init.d/apache2 reload

© 2009 01i


Ryan on February 28, 2018:

How to do this with Microsoft Server DNS?

Nick on May 09, 2015:

Thank you so much for this post. I have searched high and low for an explanation as to how to add a site to bind9 using apache on ubuntu and had almost given up when I stumbled upon this article. I now have my website running internally and all my devices can connect. YES ! :)

01i (author) from Eastbourne, East SUssex, England on July 18, 2012:

André. That error message doesn't have enough information to fully troubleshoot. I assume that you've resolved the issue by now, but if not, I'd check out /var/log/messages to look for any additional messages that occur at a similar time that will point you in the right direction.

Seth, the SOA record tells DNS servers where the ultimate authority for the DNS zone lives. The first part relates to the DNS server on which you are creating the record, it doesn't have to be the same 'domain' as the zone file you are creating. The email address is the contact email for the administrator of DNS, it also does not 'have' to be part of the domain you are configuring. I'd also like to point out that I've edited the hub to remove the @ symbol in the email address and change it to a dot. Although @ works (I've had several domain files using it) the symbol has additional use and the dot is safer (and correct according to RFC). On the other error, you've typed "NameVirtualHost*" there should be a space between the values "NameVirtualHost *"

Timon, you will need to open up ports on your firewall. That's generally 80 for web (443 for https) and 53 for DNS. Otherwise other computers cannot connect to your web or DNS services

timon on June 05, 2012:

only i'm getting access to my site on the computer with apache no one else is seeing it why

seth on June 02, 2012:

Hello i just have two questions that aren't clear.

In the zone file is line:


the name of the dns server or the domain you want and how do i set up an email account ending with my website.

second question when i add NameVirtualHost* it doesn't reload?

help anyone?

André on May 08, 2012:

with restart bind9..

"NDC command failed : rndc: connect failed: connection refused"

Mohammed Galal on April 10, 2012:

Thanks great work

mabong on February 22, 2012:

thanks very helpful info indeed.

Fax Features on December 08, 2010:

Concise and step by step. Great help for me.

tpe on November 30, 2010:

Thanks for the help, i used it with a friend for our server.

robin on September 30, 2010:

This is very helpful for bringing up a new leased server.

It may seem trivial, but you might consider adding the details on installing WordPress 3 in multisite mode - bind needs a wildcard domain record and the existing docs make way too many assumptions about using control panels, etc. and nothing on editing the actual bind files.

bytecoders from Spain on May 28, 2010:

Hi! o1i, this one is very useful! I liked it a lot, now it's on my bookmarks.

I don't think you should split this into 2 different hubs because all information is related an usually is spread into 2 or three posts.

Brian on February 22, 2010:

What a huge help. I was stumbling on a couple of points getting my subdomain running. You've saved me a ton of trouble, thanks!

01i (author) from Eastbourne, East SUssex, England on December 03, 2009:

Should I split this into 2 different hubs?

Related Articles