Published : 2011-10-03

Reverse proxy

Since Apache 2.2, a very interesting feature has been available: the reverse proxy module. It lets you set up an Apache server that forwards HTTP requests to another server, for instance local. This makes it possible to hide your sites behind one or several front-end web servers, which is useful from a security standpoint. This article explains how to configure the reverse proxy.

This setup also lets you switch servers on the fly, for example during maintenance or a site upgrade (with two different machines). In the event of a web attack, it also protects the traffic by shielding the content behind several gateways and firewalls (only the web server can reach the proxied site).

Prerequisites

You must first enable/install the modules mod_proxy, mod_proxy_http, mod_proxy_ftp (if you forward FTP traffic), mod_proxy_connect (for HTTPS traffic), mod_proxy_ajp (Tomcat servers), mod_proxy_balancer (server load balancing), mod_headers (to modify forwarded headers), mod_deflate (compression), and mod_proxy_html (rewriting).

Pick what you need. For now we will stick to HTTP and HTTPS.

Simple Configuration

A reverse proxy is configured in a VirtualHost. You can forward a single directory or your entire site to another server. Here is a basic VirtualHost template for a reverse proxy:

<Virtualhost *:80>
      ServerName publicserver.domain.tld
      ServerAlias publicserver.domain.tld
      ProxyRequests off
      ProxyPass / http://localserver.local/
      ProxyPassReverse / http://localserver.local/
</Virtualhost>

Note: do not forget the trailing / on the destination URL, otherwise you are likely to be vulnerable to a proxy bypass flaw.

When a client connects to publicserver.domain.tld, it is sent to the front-end Apache, which fetches the data from the backend server localserver.local. The localserver.local server can use a local DNS name unknown on the Internet or a non-routable IP (recommended for security).

Generic Configuration

Here is a small but very useful configuration that redirects every request to something.domain.tld toward something.local. You first need to enable Apache’s mod_rewrite. This makes it easy to hide all your sites behind a pool of local servers (site1.domain.tld to site1.local, site2.domain.tld to site2.local).

<VirtualHost *:80>
  ServerName server.domain.tld
  ServerAlias *.domain.tld
  Rewriteengine On
  ProxyRequests off
  RewriteCond %{HTTP_HOST} (.*).domain.tld
  RewriteRule (.*) $1 [E=WHERETO:%1.local]
  ProxyPassReverse / <a>http://%{ENV:WHERETO}/</a>
  RewriteRule ^/(.*) <a>http://%{ENV:WHERETO}/$1</a> [P]
</VirtualHost>

We recommend against this configuration, even though it makes it easy to manage a pool of local proxied servers.