Apache webserver is a widely deployed modular web server. One of its modules is called mod_proxy. It aims to turn the web server into a proxy / reverse proxy server with load-balancing capabilities.

And during some deployments, customers ask us to migrate the Apache mod_proxy configuration into HAProxy. The present article explains how to translate ProxyPass-related rules.

ProxyPass, ProxyPassReverse, etc…

Apache mod_proxy defines a few directives which let it forward traffic to a remote server.
They are listed below with a short description.

ProxyPass

ProxyPass maps local server URLs to remote servers + URL. It applies on traffic from client to server.

For example:

ProxyPass /mirror/foo/ http://backend.example.com/

This makes the external URL http://example.com/mirror/foo/bar to be translated and forwarded to a remote server this way: http://backend.example.com/bar

This directive makes apache to update URL and headers to match both external traffic to internal needs.

ProxyPassReverse

ProxyPassReverse Adjusts the URL in HTTP response headers sent from a reverse proxied server. It only updates Location, Content-Location and URL. It applies to traffic from server to client.

For example:

ProxyPassReverse /mirror/foo/ http://backend.example.com/

This directive makes apache to adapt responses generated by servers following internal urls to match external urls.

ProxyPassReverseCookieDomain

ProxyPassReverseCookieDomain adjusts the Set-Cookie header sent by the server to match external domain name.

It’s usage is pretty simple. For example:

ProxyPassReverseCookieDomain internal-domain public-domain

ProxyPassReverseCookiePath

ProxyPassReverseCookiePath adjusts the Set-Cookie header sent by the server to match external path.

It’s usage is pretty simple. For example:

ProxyPassReverseCookiePath internal-path public-path

Configure ProxyPass and ProxyPassReverse in HAProxy

Bellow, an example HAProxy configuration to make HAProxy work the same way as apache ProxyPass and ProxyPassReverse configuration. It should be added in the backend section while the frontend ensure that only traffic matching this external URL would be redirected to that backend.

frontend ft_global
 acl host_dom.com    req.hdr(Host) dom.com
 acl path_mirror_foo path -m beg   /mirror/foo/
 use_backend bk_myapp if host_dom.com path_mirror_foo

backend bk_myapp
[...]
# external URL                  => internal URL
# http://dom.com/mirror/foo/bar => http://bk.dom.com/bar

# ProxyPass /mirror/foo/ http://bk.dom.com/bar
http-request set-header Host bk.dom.com
reqirep  ^([^ :]*)\ /mirror/foo/(.*)     \1\ /\2

# ProxyPassReverse /mirror/foo/ http://bk.dom.com/bar
# Note: we turn the urls into absolute in the mean time
acl hdr_location res.hdr(Location) -m found
rspirep ^Location:\ (https?://bk.dom.com(:[0-9]+)?)?(/.*) Location:\ /mirror/foo3 if hdr_location

# ProxyPassReverseCookieDomain bk.dom.com dom.com
acl hdr_set_cookie_dom res.hdr(Set-cookie) -m sub Domain= bk.dom.com
rspirep ^(Set-Cookie:.*)\ Domain=bk.dom.com(.*) \1\ Domain=dom.com\2 if hdr_set_cookie_dom

# ProxyPassReverseCookieDomain / /mirror/foo/
acl hdr_set_cookie_path res.hdr(Set-cookie) -m sub Path= 
rspirep ^(Set-Cookie:.*)\ Path=(.*) \1\ Path=/mirror/foo2 if hdr_set_cookie_path
Note

HTTP to HTTPS redirect rules should be handled by HAProxy itself and not by the application server (to avoid some redirect loops).

Links

Subscribe to our blog. Get the latest release updates, tutorials, and deep-dives from HAProxy experts.