IP based Virtual Hosting

IP based Virtual Hosting is used to serve same or different websites hosted on different IP addresses and/or TCP Ports. Here the server relies on the IP address or Port to determine which host to serve.

 

Suppose we want to create a new website example.org pointing to the IP address 192.168.0.101 on Port 800. While we still want to have the default website example.com pointing to the same IP address 192.168.0.100 on port 80 intact.

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

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

 

 

1) Configuring the server
Open Apache HTTP Server‘s main configuration file httpd.conf.
Let us define the IP address 192.168.0.101 and Port 800 to which Apache HTTP Server must bind. Look for the line containing Listen directive that defines the IP address and port number. Below this line, add the following line.

Listen 192.168.0.101:800

Save and close the file.

Restart the apache service.

# service apache restart

 

 

2) Setting up Virtualhost for the 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

 

 

3) 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

 

 

4) 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.101 with IP address and 800 with Port of your machine.
• Replace example.org with required domain name.

<VirtualHost 192.168.0.101:800>
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 second 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 and 800 with Port 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.101: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.101: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.
Name based Virtual Hosting

OR

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