Apache2 as a transparent HTTP-Gateway

Imagine you want to provide some content but at the same time hide its true origin. Sounds ridiculous? Well, there may be good reasons to do so:

  • hide the original server from the net for security reasons
  • circumvent or help to circumvent location based censorship
  • make content of some unsuitable CMS available to authorized users only (estimated effort to switch CMS is about ‚one hundred before thousand‘ – the largest number known to mankind)

From the technical perspective the actual reason is not so important – let’s get on with the details:

Setting up the gateway

If you want to use the path /proxy/ as entry point for your gateway to www.example.com then you need to enable mod_proxy and mod_proxy_http and define PassProxy and PassProxyReverse directives for that:

<Location /proxy/>
    ProxyPass http://www.example.com/
    ProxyPassReverse http://www.example.com/
</Location>

An SSL remote additionally needs mod_proxy_connect and the following directives in the virtual host:

# required
SSLProxyEngine On
# recommended
SSLProxyCheckPeerCN On
SSLProxyCheckPeerExpire On

Rewrite links in the returned page

Links and referenced style sheets in the retrieved page will point to the proxied URL. Using mod_proxy_html Apache2 can rewrite them to also go through the proxy. For me the Perl implementation worked better (needs mod_perl):

PerlInputFilterHandler Apache2::ModProxyPerlHtml
PerlOutputFilterHandler Apache2::ModProxyPerlHtml

<Location /proxy/>    
    # inflate and deflate enables processing of compressed pages
    SetOutputFilter INFLATE;proxy-html;DEFLATE
    # multiple mappings and use of regular expressions possible
    PerlAddVar ProxyHTMLURLMap "http://www.example.com/ /proxy/"
</Location>

The complete gateway configuration:

SSLProxyEngine On
SSLProxyCheckPeerCN On
SSLProxyCheckPeerExpire On

PerlInputFilterHandler Apache2::ModProxyPerlHtml
PerlOutputFilterHandler Apache2::ModProxyPerlHtml

<Location /proxy/>
   ProxyPass http://www.example.com/
   ProxyPassReverse http://www.example.com/

   SetOutputFilter INFLATE;proxy-html;DEFLATE
   PerlAddVar ProxyHTMLURLMap "http://www.example.com/ /proxy/"
</Location>

Further notes

If the proxied site relies on cookies, then you need to configure ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath.

ProxyPassReverse will only rewrite Location, Content-Location and URI headers. If you need any other headers rewritten, you must put additional measures into place.

Docs for the used proxy modules: mod_proxy, mod_proxy_http, mod_proxy_connect

Leave a comment

Your comment

(required)