RHCE – How To Set Up Apache Virtual Hosts on CentOS/RHEL 7

Virtual Hosts is one of Apache’s most powerful and commonly used feature. Virtual Hosts (aka vhosts) let’s allows you to host multiple websites on a single machine. There are 2 big advantages to this:


You can find all my latest posts on medium.
  • Rather than needing one ip address per website, you know just need one ip address for the machine.
  • A lot of machines capacity might not get used if it just hosts a single website. So having multiple websites on a single machine will make better use of your machine’s computing capacity

There are a few ways to setup vhosts, but we’ll walk through one of typical most common ways to create vhosts. In our example we have 2 websites that we want to host on our box, they are:


To start with we first need to create a content directory of each website, we’ll choose:

$ mkdir  /var/www/example_com
$ mkdir  /var/www/example_net

$ chown apache:apache /var/www/example_com
$ chown apache:apache /var/www/example_net

$ ll -Z /var/www/ | grep example
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 example_com
drwxr-xr-x. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 example_net

Now let’s create a dummy home page for each website:

$ echo 'hello' > /var/www/example_com/index.html
$ chown apache:apache /var/www/example_com/index.html

$ echo 'hello' > /var/www/example_net/index.html
$ chown apache:apache /var/www/example_net/index.html

$ ls -lZ /var/www/example_com/index.html
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/example_com/index.html
$ ls -lZ /var/www/example_net/index.html
-rw-r--r--. apache apache unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/example_net/index.html

Now we create the vhost config files, they are:

$ ll /etc/httpd/conf.d | grep example
-rw-r--r--. 1 apache apache  243 Mar  5 19:11 example_com.conf
-rw-r--r--. 1 apache apache  242 Mar  5 19:10 example_net.conf

$ ll -Z /etc/httpd/conf.d | grep example
-rw-r--r--. apache apache unconfined_u:object_r:httpd_config_t:s0 example_com.conf
-rw-r--r--. apache apache unconfined_u:object_r:httpd_config_t:s0 example_net.conf

$ cat /etc/httpd/conf.d/example_com.conf

    DocumentRoot /var/www/example_com
    ErrorLog /var/log/httpd/example_com_error.log
    CustomLog /var/log/httpd/example_com_access.log combined

$ cat /etc/httpd/conf.d/example_net.conf

    DocumentRoot /var/www/example_net
    ErrorLog /var/log/httpd/example_net_error.log
    CustomLog /var/log/httpd/example_net_access.log combined

We can test the syntax of these new config files using apachectl like this:

$ apachectl configtest
Syntax OK

We can also check whether httpd is aware of our new vhosts like this:

$ httpd -D DUMP_VHOSTS
VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server (/etc/httpd/conf.d/example_com.conf:1)
         port 80 namevhost (/etc/httpd/conf.d/example_com.conf:1)
         port 80 namevhost (/etc/httpd/conf.d/example_net.conf:1)
*:443                  webserver.local (/etc/httpd/conf.d/ssl.conf:56)

Since these are dummy websites for testing purposes, we don’t have public dns entries for and So we need to do the dns resolution locally using /etc/hosts file. In our example, our box’s IP address is ‘’, so we add in the following lines:

$ cat /etc/hosts	webserver.local	webserver   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

Now we reload the configurations:

$ systemctl restart httpd

Finally we can test to see if this has worked:

[root@webserver conf.d]# curl
[root@webserver conf.d]# curl


In case you want to use a non-standard port to listen on. Then you need to tell SELinux about this. First you need to check what ports SELinux allows web traffic on:

$ semanage port -l | grep http
http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

Now if we want to use a non-stanard port, e.g. 3030, then first check it’s not being used elsewhere according to selinux:

$ semanage port -l | grep 3030
$ ss -atn | grep 3030

Now add this port to our SELinux rules, like this:

$ semanage port -at http_port_t -p tcp 3030

[post-content post_name=rhsca-quiz]

Where are vhost files usually stored?


By convention, what kind of filenames do you give your vhost files?


this is now a question. Instead it's a challenge

Create a website called with the following settings:
– documentroot: /var/vhosts/cb
– listens of port 5900
– index.html contains ‘hello’
– not encrypted.
– ensure both selinux and firewalld is running

What is the command to check what ports SELinux allows web traffic through?

$ semanage port -l | grep http

What is the command to update SELinux to allow web traffic through port 3030?

$ semanage port -at http_port_t -p tcp 3030

What are the main settings to specify in your vhost file?

– ServerName
– ServerAlias
– DocumentRoot
– ErrorLog
– CustomLog