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
HTTP to HTTPS redirect rules should be handled by HAProxy itself and not by the application server (to avoid some redirect loops).
Links