General Apache notes and tips.

Reverse proxies

A reverse proxy server sits in front of your web servers, proxying requests from outside users.

An Apache reverse proxy requires three configuration components:

  1. Proxy permissions, allowing clients to proxy to your backend servers
  2. ProxyPass rules, mapping frontend requests to backend urls
  3. Reverse rules, mapping redirections and headers set by your backend servers to proper frontend urls.

Proxy permissions

End users must be permitted to proxy via your Apache server to your backend servers. Use the <Proxy> directive:

<Proxy http://10.0.0.20:8080/*>
    Order allow,deny
    Allow from all
</Proxy>

This lets any ip address proxy to any path on the http server running on port 8080 or 10.0.0.20. Note that reverse proxies grant access to machines from the IP Address of the reverse proxy server. Incorrect permissions can allow users to access machines behind your firewall.

ProxyPass

<ProxyPass> directives specify which backends should handle which frontend URLs.

There are three ways to provide this mapping:

  • A RewriteRule with a [P] or [Proxy] command – any matched request will be proxied
  • A ProxyPass directive whose first argument is the frontend path and whose second argument is the backend url
  • A <Location> block containing a ProxyPass which takes only a single argument, the backend url – any requests which match the Location block will be sent to the backend

These three forms are equivalent:

RewriteRule ^/app/(.*)$ http://10.0.0.20:8080/app/$1 [P]
ProxyPass /app/ http://10.0.0.20:8080/app/
<Location /app/>
    ProxyPass http://10.0.0.20:8080/app/
</Location>

ProxyPassReverse and ProxyPassReverseCookiePath

The reverse proxy rules transform URLs in redirects and other headers to frontend URLs. This is necessary because backend servers will generally send private, backend URLs in headers, not the proper public URLs.

ProxyPassReverse and ProxyPassReverseCookiePath tell Apache how to mangle these headers as they pass from the backend to the client in order to form valid frontend URLs.

ProxyPassReverse will rewrite any Location headers sent using backend URLs to use the corresponding frontend URLs. For instance, a backend server which sends:

Location: http://10.0.0.10:8080/foo/bar

Could be rewritten to:

Location: http://frontend.example.com/prefix/foo/bar

ProxyPathReverseCookiePath does the same for Set-Cookie headers. This prevents a backend application that sets a cookie named sessionid on / from clobbering the sessionid cookies of other applications hosted from other folders.

PPR, like ProxyPass, can be used with two arguments in a Server or VirtualHost context, or with one argument in a Location context.

PPRCP must be given two arguments, and will rewrite any matching internal cookie path to the given external cookie path, without re-adding any suffixes from the internal path. Using a ProxyPassReverseCookiePath prevents backend apps from accidentally or maliciously interfering with one another.

Example

<Location /foobar>
  ProxyPass http://10.0.0.20:8080
  ProxyPassReverse http://10.0.0.20:8080
</Location>
ProxyPassReverseCookiePath / /foobar

Miscellaneous issues

HTTPS terminated in front of Apache

If https sessions are terminated before the Apache reverse proxy (or backend server), include the scheme in the ServerName directive:

ServerName https://my.server.example.com

An explicit scheme is needed because when terminating HTTPS sessions on a load balancer or accelerator in front of Apache, Apache's ServerName will default to the http: scheme. This will cause both redirections and ProxyPassReverse/ProxyPassReverseCookiePath header mangling to break.

See Apache Core/ServerName.