Name based Virtual Hosting

Name based Virtual Hosting is the most commonly used form of Virtual Hosting. Name based Virtual Hosting is used to serve different websites hosted on the same IP address or Port. Here the server relies on the client to report the hostname as a part of the HTTP headers. Thus it uses the hostname to determine which host to serve. We only need to configure our DNS server to map each hostname to the correct IP address.

The first step in Name-based virtual host resolution is IP-based resolution. When a request arrives, the server will find the best (most specific) matching <VirtualHost> argument based on the IP address and port used by the request. If there is more than one virtual host containing this best-match address and port combination, Apache HTTP Server will further compare the ServerName and ServerAlias directives to the server name present in the request.
If no matching ServerName or ServerAlias is found in the set of virtual hosts containing the most specific matching IP address and port combination, then the first listed virtual host that matches it will be used.
NOTE: Using a wildcard (*) for the IP address in all of the VirtualHost directives makes this IP-based mapping irrelevant.

 

Suppose we want to create a new website example.org pointing to the IP address 192.168.0.100. While we still want to have the default website example.com pointing to the same IP address 192.168.0.100 intact.

WARNING: Make sure DNS or /etc/hosts entries are properly configured, so that the domain name example.org resolves to the IP address 192.168.0.100.

Implementing Name based Virtual Hosting involves the following steps.
1) Setting up Virtualhost for the main website
2) Creating a DocumentRoot for the new website
3) Setting up Virtualhost for the new website

 

 

1) Setting up Virtualhost for main website
Open Apache HTTP Server‘s main configuration file httpd.conf.
Look for the line containing httpd-vhosts.conf. Uncomment the line so that it looks as shown below.

Include conf/extra/httpd-vhosts.conf

Save and close the file.

Open Apache HTTP Server‘s Virtualhost configuration file httpd-vhosts.conf.
Look for the sample Virtualhost entries at the end of file. Comment out these entries. Now it must look like as shown below.

#<VirtualHost *:80>
#    ServerAdmin [email protected]
#    DocumentRoot "/usr/local/apache2/docs/dummy-host.example.com"
#    ServerName dummy-host.example.com
#    ServerAlias www.dummy-host.example.com
#    ErrorLog "logs/dummy-host.example.com-error_log"
#    CustomLog "logs/dummy-host.example.com-access_log" common
#</VirtualHost>
#
#<VirtualHost *:80>
#    ServerAdmin [email protected]
#    DocumentRoot "/usr/local/apache2/docs/dummy-host2.example.com"
#    ServerName dummy-host2.example.com
#    ErrorLog "logs/dummy-host2.example.com-error_log"
#    CustomLog "logs/dummy-host2.example.com-access_log" common
#</VirtualHost>


Let us create a Virtualhost entry for the main website example.com. Add the below content to the end of file.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.com with hostname of your machine.

<VirtualHost 192.168.0.100:80>
ServerAdmin root@localhost
DocumentRoot "/usr/local/apache2/htdocs"
ServerName example.com
ServerAlias www.example.com
ErrorLog "logs/example.com-error_log"
CustomLog "logs/example.com-access_log" common
<Directory "/usr/local/apache2/htdocs">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

Save and close the file.

 

If SSL support is enabled for the main website example.com based on the instructions provided at Enabling SSL support, a few changes must be made.

Open Apache HTTP Server‘s SSL configuration file httpd-ssl.conf.
Look for the line starting with <VirtualHost. Just a few lines below, there will be a line starting with TransferLog directive. Replace these lines and everything between them with the below content.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.com with hostname of your machine.

<VirtualHost 192.168.0.100:443>

#   General setup for the virtual host
DocumentRoot "/usr/local/apache2/htdocs"
ServerName example.com
ServerAdmin root@localhost
ErrorLog "/usr/local/apache2/logs/example.com_error_log"
TransferLog "/usr/local/apache2/logs/example.com_access_log"
<Directory "/usr/local/apache2/htdocs">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>


Look for the line containing CustomLog directive. For the value of this directive, change ssl_request_log to ssl_example.com_request_log. Now it must look as shown below.
NOTE: Replace example.com with the hostname of your machine.

CustomLog "/usr/local/apache2/htdocs/logs/ssl_example.com_request_log" 
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x "%r" %b"


The directive ServerAlias does not work with SSL configuration in Apache HTTP Server. So let us add a separate VirtualHost www.example.com. Add the following content to the end of file.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.com with hostname of your machine.

<VirtualHost 192.168.0.100:443>

DocumentRoot "/usr/local/apache2/htdocs"
ServerName www.example.com
ServerAdmin root@localhost
ErrorLog "/usr/local/apache2/logs/example.com_error_log"
TransferLog "/usr/local/apache2/logs/example.com_access_log"

<Directory "/usr/local/apache2/htdocs">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

SSLEngine on

SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"

<FilesMatch ".(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>

<Directory "/usr/local/apache2/cgi-bin">
SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" 
nokeepalive ssl-unclean-shutdown 
downgrade-1.0 force-response-1.0

CustomLog "/usr/local/apache2/logs/ssl_example.com_request_log" 
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x "%r" %b"

</VirtualHost>

Save and close the file.


Now, let us comment out the entries for example.com in Apache HTTP Server‘s main configuration file httpd.conf. This is done because of the following reason.
When httpd-vhosts.conf is enabled and configured, the host configuration in httpd.conf is ignored. But only to lie there silently and come into action if the corresponding host configuration in httpd-vhosts.conf ever goes wrong. The result; we will be left wondering why our configuration changes does not work as intended. Commenting out the host configuration in httpd.conf will avoid such a situation.


Open Apache HTTP Server‘s main configuration file httpd.conf.
Look for the line containing DocumentRoot “. Comment out the line. Now it must look as shown below.

#DocumentRoot "/usr/local/apache2/htdocs"


Look for the line containing <Directory “. Comment out the line. Now it must look as shown below.

#<Directory "/usr/local/apache2/htdocs">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
#    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   AllowOverride FileInfo AuthConfig Limit
    #
#    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
#    Require all granted
#</Directory>

Save and close the file.


Restart the apache service gracefully.

# service apache graceful

 

 

2) Creating a DocumentRoot for the new website
Let us create a DocumentRoot htdocs2 for the new website. Execute the below command in terminal.

# mkdir /usr/local/apache2/htdocs2


Set proper permissions for the newly created DocumentRoot. See Post Installation procedure for additional information. Change the Owner and Group of htdocs2 directory to apache.

# chown -R apache:apache /usr/local/apache2/htdocs2
OPTIONS EXPLAINED

-R
operate on files and directories recursively


Now there is a problem. /usr/local/apache2/htdocs2 is the system DocumentRoot directory. The contents of this directory are usually modified by the standard user from a local machine. But the standard user does not have access to this directory. So everytime we have to modify the contents of this directory, we will have to do it as root user and set proper permissions afterwards. This is an inconvenience. Performing the following steps will solve this issue.

We have already added the group apache as a supplementary group to the standard user’s group during the Post Installation procedure.

Provide write permission to members of apache group, so that the standard user will have write access to the DocumentRoot directory.

# chmod -R g+w /usr/local/apache2/htdocs2
OPTIONS EXPLAINED

-R
operate on files and directories recursively

g+w
Set write permission for users who are members of the file's group

 

Still, there is a problem. If the standard user creates a file/directory inside the htdocs2 directory, the owner will be set to standard user and group will be set to primary group of standard user. As a result, Apache HTTP Server will not have write access to those files/directories unless we set proper permissions as root.

This can be overcome by setting SGID bit on the htdocs2 directory. This makes the created file/directory to retain the group ownership of directory with SGID under which it was created. Thus Apache HTTP Server will have read&write access to these file/directories. For this, execute the below command in terminal.

# find /usr/local/apache2/htdocs2 -type d -exec chmod g+s {} ;
OPTIONS EXPLAINED


find
search for files in a directory hierarchy

-type
File is of type:
b      block (buffered) special
c      character (unbuffered) special
d      directory
p      named pipe (FIFO)
f      regular file
l      symbolic link; this is never true if the -L option or the -follow option is in effect, unless the symbolic link is broken. If you want to search for symbolic links when -L is in effect, use -xtype.
s      socket
D      door (Solaris)

-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ‘;’ is encountered. The string ‘{}’ is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a ‘’) or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.



chmod
change file mode bits

g+s
Set SetGID bit for users who are members of the file's group

 

 

3) Setting up Virtualhost for the new website
Now let us create a Virtualhost for our second website example.org. Open Apache HTTP Server‘s Virtualhost configuration file httpd-vhosts.conf. Add the below content to the end of file.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.org with required domain name.

<VirtualHost 192.168.0.100:80>
ServerAdmin root@localhost
DocumentRoot "/usr/local/apache2/htdocs2"
ServerName example.org
ServerAlias www.example.org
ErrorLog "logs/example.org_error_log"
CustomLog "logs/example.org_access_log" common
<Directory "/usr/local/apache2/htdocs2">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

Save and close the file.

 

If we want to enable SSL support for example.org, we must follow the procedure explained at Enabling SSL support. After that we must tweak the SSL Virtualhost configuration for main website example.com, as explained in the first step Setting up Virtualhost for the main website in this topic.
If all this is done, we can proceed with the below steps.

Open Apache HTTP Server‘s SSL configuration file httpd-ssl.conf.
Add the following content to the end of file.
NOTE:
• Replace 192.168.0.100 with IP address of your machine.
• Replace example.org with hostname of your machine.
• The directive ServerAlias does not work with SSL configuration in Apache HTTP Server. Because of this, we have added a separate VirtualHost www.example.org.

<VirtualHost 192.168.0.100:443>

DocumentRoot "/usr/local/apache2/htdocs2"
ServerName example.org
ServerAdmin root@localhost
ErrorLog "/usr/local/apache2/logs/example.org-error_log"
TransferLog "/usr/local/apache2/logs/example.org-access_log"

<Directory "/usr/local/apache2/htdocs2">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

SSLEngine on

SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"

<FilesMatch ".(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>

<Directory "/usr/local/apache2/cgi-bin">
SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" 
nokeepalive ssl-unclean-shutdown 
downgrade-1.0 force-response-1.0

CustomLog "/usr/local/apache2/logs/ssl_example.org_request_log" 
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x "%r" %b"

</VirtualHost>

<VirtualHost 192.168.0.100:443>

DocumentRoot "/usr/local/apache2/htdocs2"
ServerName www.example.org
ServerAdmin root@localhost
ErrorLog "/usr/local/apache2/logs/example.org_error_log"
TransferLog "/usr/local/apache2/logs/example.org_access_log"

<Directory "/usr/local/apache2/htdocs2">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

SSLEngine on

SSLCertificateFile "/usr/local/apache2/conf/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/server.key"

<FilesMatch ".(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>

<Directory "/usr/local/apache2/cgi-bin">
SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" 
nokeepalive ssl-unclean-shutdown 
downgrade-1.0 force-response-1.0

CustomLog "/usr/local/apache2/logs/ssl_example.org_request_log" 
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x "%r" %b"

</VirtualHost>

Save and close the file.


Restart the apache service gracefully.

# service apache graceful

 

Let us create a webpage for our new website. In the directory /usr/local/apache2/htdocs2, create a file index.html with the below content.

<html>
<h1> Hello </h1>
<body> This is my second website </body>
</html>


Now, we can goto the below URLs and check if everything is working fine.

http://example.com

http://www.example.com

http://example.org

http://www.example.org

https://example.com

https://www.example.com

https://example.org

https://www.example.org

 

 

 

It is recommended to view the following section.
IP based Virtual Hosting

OR

You may go back to the following section.
Customizing Apache HTTP Server