Configure Apache HTTP Server as Reverse Proxy for Hippo

Introduction

Goal

Configure the Apache HTTP Server ("httpd") as a reverse proxy for the CMS and delivery tier web applications.

Background

When deploying a Hippo project in an application container the CMS (authoring) and Site (delivery) web applications are typically made available on URLs that include the port the container is running on, and the context path the webapps are deployed under (e.g. http://127.0.0.1:8080/cms/ and http://127.0.0.1:8080/site/). Apache's HTTP Server ("httpd") is typically used to make the applications available on their proper URLs, hiding the port number and context path. This is done by configuring virtual hosts. In effect Apache HTTP Server then acts as a reverse proxy.
This page explains the requirements and provides an example configuration for the most common deployment scenario.

Configuration Requirements

Map Host Name to Application

Each web application (i.e. CMS and Site) requires a VirtualHost configuration that maps a host using the ServerName directive:

<VirtualHost *:80>
  ServerName HOSTNAME

  # additional configuration required as described in the next paragraphs

</VirtualHost>

Where HOSTNAME is the host name at which the webapp should be available (e.g. cms.example.com or www.example.com).

Strip Port and Context Path From URL

Each web application (i.e. CMS and Site) must have its port number and context path stripped from the URL by mapping it to the virtual host's root path / using a ProxyPass directive:

  ProxyPass / http://HOST:PORT/CONTEXTPATH/
  ProxyPassReverse / http://HOST:PORT/CONTEXTPATH/
  ProxyPassReverseCookiePath /CONTEXTPATH /

Where:

  • HOST is the host the container runs on (e.g. 127.0.0.1 if it's the same machine).
  • PORT is the port the container runs on (typically 8080).
  • CONTEXTPATH is the context path under which the webapp runs (typically cms or site).

Preserve Host Name From Site Requests

Hippo's delivery tier performs its own virtual host matching, and virtual host mappings are configured at application level. This requires the ProxyPreserveHost directive to be set to On in the VirtualHost configuration of the site so the host name from the request is passed on to the application:

  ProxyPreserveHost  On

The CMS application requires ProxyPreserveHost Off.

Preview Site in CMS Channel Manager

Sites can be previewed in the Channel Manager of the CMS application. The sites in the Channel Manager preview are requested over the host of the CMS but on the context path of the site. This requires an additional ProxyPass rule in the VirtualHost configuration for the CMS:

  ProxyPass /CONTEXTPATH/ http://HOST:PORT/CONTEXTPATH/

Where:

  • HOST is the host the container runs on (e.g. 127.0.0.1 if it's the same machine).
  • PORT is the port the container runs on (typically 8080).
  • CONTEXTPATH is the context path under which the site webapp runs (typically site).

Forward HTTPS Protocol

Typically, the CMS is accessed over https, and in certain use cases a site (or parts of a site) also needs to be accessed over https. This is supported by Hippo's delivery tier

If CMS or the site (or part of the site) needs to be accessed over a secure SSL connection, the X-Forwarded-Proto request header must be set by the proxy that does the SSL offloading (https --> http). If httpd does the offloading, then in the VirtualHost configuration of the secure site the following needs to be added, so the site webapp is aware of the secure connection:

  RequestHeader set X-Forwarded-Proto https

If not httpd but say, haproxy does the SSL offloading, then haproxy needs to set the X-Forwarded-Proto header.

Configuration Example

This example reflects the most common deployment scenario: the CMS web application and a single Site web application are deployed in the same container.

Let's assume that:

  1. The Site application is deployed as site.war.

  2. The CMS is deployed as cms.war.

  3. The application container runs on port 8080 on the same machine as the Apache HTTP Server.

  4. The site will be accessed through http://*.example.com.

  5. The CMS will be accessed through https://cms.example.com.

  6. httpd is doing the SSL offloading

The Apache HTTP Server configuration will then be as follows:

<VirtualHost *:443>
  ServerName cms.example.com

  # SSL Engine
  SSLEngine on

  SSLCertificateFile /etc/apache2/ssl/server.crt
  SSLCertificateKeyFile /etc/apache2/ssl/server.key

  SSLHonorCipherOrder On
  SSLCipherSuite
     ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
  BrowserMatch "MSIE [6-9]" ssl-unclean-shutdown

  <Location />
    Order deny,allow
    Allow from all
  </Location>

  RequestHeader set X-Forwarded-Proto https

  ProxyPreserveHost Off

  #INCLUDE THE EXTRA PROXYPASS RULE FOR /site HERE
  ProxyPass /site/ http://127.0.0.1:8080/site/
  ProxyPass / http://127.0.0.1:8080/cms/
  ProxyPassReverse / http://127.0.0.1:8080/cms/
  ProxyPassReverseCookiePath /cms /
</VirtualHost>

<VirtualHost *:80>
  ServerName www.example.com
  # everthing that does not match cms.example.com also goes to the site application
  ServerAlias *.example.com

  ProxyPreserveHost  On
  ProxyPass  / http://127.0.0.1:8080/site/
  ProxyPassReverse  / http://127.0.0.1:8080/site/
  ProxyPassReverseCookiePath  /site /
</VirtualHost>
<VirtualHost *:443>
  ServerName www.example.com
  ServerAlias *.example.com
  # SSL Engine
  SSLEngine on

  SSLCertificateFile /etc/apache2/ssl/server.crt
  SSLCertificateKeyFile /etc/apache2/ssl/server.key

  SSLHonorCipherOrder On
  SSLCipherSuite
     ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH
  BrowserMatch "MSIE [6-9]" ssl-unclean-shutdown

  <Location />
    Order deny,allow
    Allow from all
  </Location>

  RequestHeader set X-Forwarded-Proto https

  ProxyPreserveHost On

  ProxyPass / http://127.0.0.1:8080/site/
  ProxyPassReverse / http://127.0.0.1:8080/site/
  ProxyPassReverseCookiePath /site /
</VirtualHost>