Lab 04 - Apache2 HTTP Server

In this lab, you will set up the Apache2 HTTP Server and configure virtual servers. You will practice incorporating modules and test your web service. The Apache2 official documentation is located at Apache HTTP Server Version 2.4 Documentation.

Software Install

ali@pc20059995:~$ sudo apachectl graceful
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message.
ali@pc20059995:~$ sudo apachectl graceful
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message.

Apache Configuration

Enabling the userdir Module

The userdir module allows http access to user-specific directories. This effectively allows each user to have their own personal website on the host. User document root directories are usually located under /home/<user>/public_html. This directory should already exist if you have followed the previous lab instructions correctly.

Tip: If you are receiving a 403 forbidden error instead of seeing a directory listing, check your user's home directory permissions. The execute permission for others is required for files and directories to be enumerated by other users, such as internet visitors. Change your /home/firstname permissions from --- to --x using chmod o+x . from your home directory or using other methods. Refresh your page, and you should be able to see the directory listing.

Configuring userdir Module Security

We don't want directory listings to be available by default. The mods-available/userdir.conf file should be modified to not include Indexes in the Directory permissions' Options line. Use the AllowOverride directive to permit the users to override the missing Indexes directive using .htaccess files at their discretion (i.e. add Options=Indexes to an AllowOverride line in the Directory stanza of mods-available/userdir.conf).

<IfModule mod_userdir.c>
    UserDir public_html
    UserDir disabled root
    <Directory /home/*/public_html>
        AllowOverride FileInfo AuthConfig Limit Indexes Options=Indexes
        Options MultiViews SymLinksIfOwnerMatch IncludesNoExec
        <Limit GET POST OPTIONS>
            Require all granted
        </Limit>
        <LimitExcept GET POST OPTIONS>
            Require all denied
        </LimitExcept>
    </Directory>
</IfModule>
<IfModule mod_userdir.c>
    UserDir public_html
    UserDir disabled root
    <Directory /home/*/public_html>
        AllowOverride FileInfo AuthConfig Limit Indexes Options=Indexes
        Options MultiViews SymLinksIfOwnerMatch IncludesNoExec
        <Limit GET POST OPTIONS>
            Require all granted
        </Limit>
        <LimitExcept GET POST OPTIONS>
            Require all denied
        </LimitExcept>
    </Directory>
</IfModule>

Reload your configuration for apache using apachectl graceful and verify your browser can no longer get directory listings for your personal public_html pages. You should be getting a 403 forbidden error since you still do not have an index file.

Ordinary User web page publishing

Note: The commands in this paragraph should be run as your ordinary user, not root.

In your public_html directory, create a file named index.html. Put some text in your index.html file to identify it as your personal web page (e.g. This is my personal page). Verify that the page shows up correctly when accessing your server with a browser (e.g. http://pcNNNNNNNNN/~firstname).

# As the normal user, not sudo:
echo "<h1>This is the site for $USER</h1>" > ~/public_html/index.html

# Check to see if this is correct and is working
wget -O - http://pcNNNNNNNNNN/~firstname
curl http://pcNNNNNNNNNN/~firstname/
# As the normal user, not sudo:
echo "<h1>This is the site for $USER</h1>" > ~/public_html/index.html

# Check to see if this is correct and is working
wget -O - http://pcNNNNNNNNNN/~firstname
curl http://pcNNNNNNNNNN/~firstname/

For the next steps, we will be hosting some pictures on our personal site and will allow the files to be indexed by overriding the settings in that directory using .htaccess, so visitors can see and download the files.

# Create a directory to host our pictures
mkdir ~/public_html/pics

# change path into the new directory
cd ~/public_html/pics
# Download the sample images
curl https://gorbehnare.github.io/COMP1071/pics.tgz | tar xzf -

# set permissions for this directory so others have access
# the `pics` Directory needs execute permission so others can navigate the directory
chmod 755 .
# Files inside `pics` should NOT have execute permissions
chmod 644 *

# Test to see if this works yet
wget -O - http://pcNNNNNNNNNN/~firstname/pics

# Add the override to allow the Indexes of files in this directory
echo "Options +Indexes" > ~/public_html/pics/.htaccess

# Test again to see if this works now
wget -O - http://pcNNNNNNNNNN/~firstname/pics
# Create a directory to host our pictures
mkdir ~/public_html/pics

# change path into the new directory
cd ~/public_html/pics
# Download the sample images
curl https://gorbehnare.github.io/COMP1071/pics.tgz | tar xzf -

# set permissions for this directory so others have access
# the `pics` Directory needs execute permission so others can navigate the directory
chmod 755 .
# Files inside `pics` should NOT have execute permissions
chmod 644 *

# Test to see if this works yet
wget -O - http://pcNNNNNNNNNN/~firstname/pics

# Add the override to allow the Indexes of files in this directory
echo "Options +Indexes" > ~/public_html/pics/.htaccess

# Test again to see if this works now
wget -O - http://pcNNNNNNNNNN/~firstname/pics

Create a virtual Host for www.lastname45678.mytld

Apache defines the term Virtual Host as the practice of running multiple websites from a single server. Hosting many websites from a single host is a common practice to conserve IPv4 addresses and to save server costs. In practice, each website's domain name hosted on a shared server resolves to the single IP address of a single server. The web server will receive the IP packet destined to the server, and forward the payload segment coming to standard TCP ports 80 (for HTTP) or 443 (HTTPS) to the web server application. The web server application examines the URL in the HTTP/S request to determine which website is being requested, usually based on the name or the domain name of the website.

From the previous lab, you already have a domain ready to use. We will be creating a new website for www.lastname45678.mytld. To start creating the new site, copy the existing 000-default.conf under /etc/apache2/sites-available:

# Make sure to set your filename to your domain name
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/www.lastname45678.mytld.conf

# Now, you can modify this file instead of creating one from scratch
nano /etc/apache2/sites-available/www.lastname45678.mytld.conf
# Make sure to set your filename to your domain name
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/www.lastname45678.mytld.conf

# Now, you can modify this file instead of creating one from scratch
nano /etc/apache2/sites-available/www.lastname45678.mytld.conf

You will need to modify the following information to configure your virtual host to match your system domain:

VirtualHost: www.lastname45678.mytld:80
ServerName: www.lastname45678.mytld
ServerAdmin: webmaster@lastname45678.mytld
DocumentRoot: /sites/www.lastname45678.mytld
<Directory> stanza to include `Require all granted`
VirtualHost: www.lastname45678.mytld:80
ServerName: www.lastname45678.mytld
ServerAdmin: webmaster@lastname45678.mytld
DocumentRoot: /sites/www.lastname45678.mytld
<Directory> stanza to include `Require all granted`

An example of a full file might look like this:

<VirtualHost www.lastname45678.mytld:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerAdmin webmaster@www.lastname45678.mytld
        ServerName www.lastname45678.mytld
        DocumentRoot /sites/www.lastname45678.mytld
        <Directory /sites/www.lastname45678.mytld/>
                Require all granted
        </Directory>

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>
<VirtualHost www.lastname45678.mytld:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerAdmin webmaster@www.lastname45678.mytld
        ServerName www.lastname45678.mytld
        DocumentRoot /sites/www.lastname45678.mytld
        <Directory /sites/www.lastname45678.mytld/>
                Require all granted
        </Directory>

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

Here are the example commands that accomplish these tasks:

mkdir -p /sites/www.lastname45678.mytld
echo "<h1>This is the www.lastname45678.mytld website</h1>" > /sites/www.lastname45678.mytld/index.html
a2ensite www.lastname45678.mytld
apachectl graceful
curl http://www.lastname45678.mytld
curl http://www.lastname45678.mytld/~firstname/
mkdir -p /sites/www.lastname45678.mytld
echo "<h1>This is the www.lastname45678.mytld website</h1>" > /sites/www.lastname45678.mytld/index.html
a2ensite www.lastname45678.mytld
apachectl graceful
curl http://www.lastname45678.mytld
curl http://www.lastname45678.mytld/~firstname/

Review log files

Examine the content of access.log and error.log in /var/log/apache2 to see what is being logged for your activity on your web server.

tail /var/log/apache2/access.log /var/log/apche2/error.log
tail /var/log/apache2/access.log /var/log/apche2/error.log

Evaluate your server

Additional Resources to get more out of the web server software

Using a browser, go to the Apache HTTP Server Version 2.4 Documentation site and review the list of modules and directives to see what sort of things can be done with Apache2 HTTP Server.