Uncannier Software

It's not enough to just be uncanny

Tomcat in AWS – Part 2 – Apache Web Server

In this article I cover how to install Apache HTTP Server into Ubuntu 18.04 LTS.

This article is part 2 of a series on how to create a Tomcat server in AWS. In part 1 we created an Ubuntu 18.04 LTS server in AWS EC2. We now add Apache HTTP Server as a front-end for Tomcat.

Motivations

When discussing reasons why you should have an Apache Web Server as a front-end to Tomcat, people usually talk about load balancing, fast serving of static content, enhanced security and so forth. These are all good reasons. My main reason though is that I want to serve custom-branded pages even when Tomcat is down.

Installation

Apache is a very mature software. You can make life marginally more difficult for yourself by trying to install a specific version. Or you can just take the easy option and install the version packaged with the Ubuntu. I choose to embrace the lazy pragmatist within, so I’ve gone for the latter.

sudo apt install apache2

This installs Apache to the /etc/apache2 directory. You can check what version is installed using:

apachectl -v

With Apache installed, you can immediately test it by confirming that its default page is accessible at the Public IP or domain name of your server.

Configuration

Remove Default Virtual Host

OK, we’ve seen the default Apache web page for long enough. Time to get rid of it. If you actually took the time to read the default page, the following command will make sense.

sudo a2dissite 000-default.conf

Static Content

We need to create a directory to hold the static content for our site. It seems the Apache convention is to make a sub-directory in /var/www

sudo mkdir -p /var/www/foobar.com

What you will want to put in here is entirely up to you. For the purposes of my example, I’m going to put just one HTML file.

sudo nano /var/www/foobar.com/error.html

With trivial contents.

<!DOCTYPE html>
<html lang="en">
 
<head>
<title>Server Error</title>
</head>
 
<body>
<h1>Down For Maintenance</h1>
<p>The Foobar website is currently down for maintenance. We apologize for any inconvenience.</p>
</body>
 
</html>

For a real site, you would build a rather more impressive page.

Proxy AJP

Although Tomcat isn’t installed yet, let’s jump right in and enable Apache’s Proxy AJP module. We will use it to forward requests to Tomcat in the next article.

sudo a2enmod proxy_ajp

Virtual Host

Now we need to create a so-called virtual host for our website. For the purposes of this post, we’ll cover just a HTTP (port 80) virtual host file. HTTPS (port 443) is covered later in the series.

I elect to create a common file that can be shared, eventually, by both the HTTP and HTTPS virtual host configurations.

sudo nano /etc/apache2/sites-available/foobar.com.common.conf

With contents:

    ServerName foobar.com
    ServerAlias www.foobar.com
    DocumentRoot "/var/www/foobar.com"
    ErrorLog ${APACHE_LOG_DIR}/foobar.com.error.log
    CustomLog ${APACHE_LOG_DIR}/foobar.com.access.log combined
 
    # Direct 503 errors (Tomcat down) to our custom error document
    ErrorDocument 503 /error.html
 
    # Directives for our static website (when Tomcat is down)
    ProxyPass /error.html !
 
    # Directives to pass all other requests through to Tomcat
    ProxyPass / ajp://localhost:8009/
    ProxyPassReverse / ajp://localhost:8009/

The DocumentRoot element sets the root to the static content directory we created earlier.

The ErrorLog and CustomLog elements can be almost anything you want. What I have done is quite conventional.

I have told Apache to pass all requests through to Tomcat, except for requests to /error.html. All requests to Tomcat, and responses from it, are handled by the Proxy AJP module we enabled earlier.

If Tomcat is down (or not installed), we expect the AJP request to return a 503 (Service Unavailable). In that case, Apache will serve /error.html.

With the common file in place, we can now create the HTTP (port 80) virtual host file.

sudo nano /etc/apache2/sites-available/foobar.com.conf

With contents:

<VirtualHost *:80>
    Include sites-available/foobar.com.common.conf
</VirtualHost>

The virtual host can then be enabled.

sudo a2ensite foobar.com.conf

Instruct Apache to reload its settings.

sudo systemctl reload apache2

And if we surf now to the Public IP or domain name, voila, we see the error page. This is because Tomcat is not yet installed, so all the Proxy AJP forwards fail. Therefore we will get this error page served for any URI.

Please remember, you can make your custom error document look a lot better than my trivial example.

Hardening

In the references, I include links to guides on how to harden an Apache installation. Most of the advice is already incorporated in a default installation of Apache Web Server in Ubuntu. What follows is a couple of steps I recommend.

Server Signature

If we didn’t have a custom error document, Apache would serve the following page when Tomcat was down (or not installed). This would reveal details, such as server version, that can give an attacker a head start.

To get rid of this signature from default pages, we need to edit the security configuration.

sudo nano /etc/apache2/conf-available/security.conf

And disable the the ServerSignature.

ServerSignature Off

Server Tokens

Even with the ServerSignature off, responses from Apache still report the server version in the HTTP response header. This can be viewed using Firefox or Chrome web development tools.

To remove this, again edit the security configuration.

sudo nano /etc/apache2/conf-available/security.conf

And set ServerTokens to the least revealing setting.

ServerTokens Prod

References

Tagged ,

Leave a Reply

Your email address will not be published. Required fields are marked *