Penguin
Note: You are viewing an old revision of this page. View the current version.

Apache can be used as a reverse proxy - that is, it allows access to internal sites from an external network, such as the Internet.

NOTE This can lead to a security flaw, if you leave your apache unsecured and enable all proxying, you will act as an open relay. Be warned!

There are a few different ways you can use apache to proxy, such as:

  • mod_rewrite
  • mod_proxy
  • mod_proxy_html

mod_rewrite

mod_rewrite will rewrite a source URL transparently to the end user. AddToMe

mod_proxy

mod_proxy is useful for simple proxying rules, such as when you want to expose a flat directory to the world, or if the internal site only uses relative URLs

For example, I have an internal network appliance (a camera) with a very simple web interface, that I wish to expose to a (properly authenticated) Internet:

        <IfModule mod_proxy.c>
                ProxyRequests Off
                <Location /camera>
                        ProxyPass http://camera.internal.org/
                        ProxyPassReverse http://camera.internal.org/
                        AuthType Basic
                        AuthName "Camera"
                        AuthLDAPUrl ldap:///dc=internal,dc=org?uid
                        Require user daniel camera
                </Location>
        </IfModule>

"ProxyRequests Off" disables arbitrary proxying - this stops my webserver being an open relay. I've also configured the /camera location to require some specific auth, authing out of an LDAP tree on localhost.

"ProxyPass http://camera.internal.org" is actually shorthand for "ProxyPass /camera http://camera.internal.org". I can make this shorthand because the ProxyPass directive is inside a <Location> block. This says to proxy any requests for for /camera/* to http://camera.internal.org/*

ProxyPassReverse, which has the same syntax as ProxyPass, will adjust the response URI to keep it pointing at the same place.

This works fairly well, although it fails if the internal website is a bit more complicated, or is on a different port. Use mod_proxy_html for that!

I get "client denied by server configuration: proxy:http://site" errors

You have a <proxy:*> block that is denying your access. Check in mods-enabled/proxy.conf if you're on Debian or Ubuntu, because it defaults to denying all.

mod_proxy_html

Suppose I want to expose a website that is running on a non-standard port internally. I could use mod_proxy, if the website only used relative or path-only absolute URLS. However, the website happens to know what hostname and port it is supposed to be running on, and has some urls which are targetted directly at the hostname and port. mod_proxy will break in this case, because URLs in the webpages aren't rewritten, and I can't access the device directly from the external network.

mod_proxy_html solves this, by rewriting parts of the source code on the fly. It's implemented as a filter in apache2, which means all webpages in the appropriate block pass through it, and can be rewritten on the fly.

Here is an example config for exposing the CUPS web interface, which runs on port 631, via an ApacheReverseProxy:

        <IfModule mod_proxy.c>
                ProxyRequests Off
                ProxyPass /cups http://cups.internal.org:631/
                ProxyHTMLURLMap http://cups.internal.org:631/ /cups
                <Location /cups>
                        ProxyPassReverse http://cups.internal.org:631/
                        SetOutputFilter proxy-html
                        ProxyHTMLURLMap /               /cups/
                        ProxyHTMLURLMap /cups/          /cups/
                </Location>
        </IfModule mod_proxy.c>

New directives that are added include the ProxyHTMLURLMap directive, and the SetOutputFilter directive.

SetOutputFilter tells apache to pass the proxied content through the proxy-html filter, which mod_proxy_html provides. This does all the rewriting discussed below:

The first ProxyHTMLURLMap directive tells mod_proxy_html to rewrite any instance of "http://cups.internal.org:631/" to "/cups". This means any absolute URLs will be rewritten to point under the /cups/ Location, which will then get proxied appropriately.

The remaining ProxyHTMLURLMap directives handle URLs with just a set path, eg "/printers/printer1/". This will get rewritten to "/cups/printers/printer1/" and then proxied correctly. The last directive is a no-rewrite rule, intended to prevent infinite looping.


Using Apache 2 with Outlook Web Access (OWA)

First, enable some useful modules:

a2enmod proxy
a2enmod headers

Placeholder for when I actually get this going:

<VirtualHost 1.2.3.4:80>
        ServerName webmail.example.org
        DocumentRoot /var/www/html/exchange
        RedirectMatch ^/(index.html?)$ https://webmail.example.org/exchange/
        RedirectMatch ^/exchange$ https://webmail.example.org/exchange/
</VirtualHost>

<VirtualHost 1.2.3.4:443>
        # This secures the server from being used as a third party
        # proxy server
        ProxyRequests Off

        # Allows the proxying of a SSL connection
        SSLProxyEngine On
        ProxyVia On

        DocumentRoot /home/user/mail_proxy/html/
        RequestHeader set Front-End-Https "On"

        ServerName mail

        # Set up SSL to work with this host
        SSLEngine On
        SSLCertificateFile /etc/apache/webmail-proxy/server.crt
        SSLCertificateKeyFile /etc/apache/webmail-proxy/server.key

        SSLProxyMachineCertificateFile /etc/apache/webmail-proxy/certnew.cer

        ProxyPass /exchange/ https://mail-internal/exchange/
        ProxyPassReverse /exchange/ https://mail-internal/exchange/

        ProxyPass /exchweb/ https://mail-internal/exchweb/
        ProxyPassReverse /exchweb/ https://mail-internal/exchweb/

        ProxyPass /public/ https://mail-internal/public/
        ProxyPassReverse /public/ https://mail-internal/public/

        ProxyPreserveHost On
</VirtualHost>

Here is a great article on Apache Proxying


Tested set of Apache reverse proxy rules

by Chris Covington - malth@umich.edu

How to ReverseProxy? Outlook Web Access (OWA) and Outlook Mobile Access (OMA) with Apache 2.X, mod_proxy and mod_rewrite

Add the following to your Apache 2.0+ httpd.conf/ssl.conf to use the ReverseProxy feature:

ProxyPreserveHost On

#OWA % character in email subject fix
RewriteEngine On
RewriteMap percentsubject int:escape
RewriteCond $1 ^/exchange/.*\%.*$
RewriteRule (/exchange/.*) ${percentsubject:$1} [P]

#OWA
ProxyPass /exchange https://exchangserver.example.com/exchange
ProxyPassReverse /exchange https://exchangeserver.example.com/exchange
ProxyPass /Exchange https://exchangeserver.example.com/exchange
ProxyPassReverse /Exchange https://exchangeserver.example.com/exchange
ProxyPass /exchweb https://exchangeserver.example.com/exchweb
ProxyPassReverse /exchweb https://exchangeserver.example.com/exchweb
ProxyPass /public https://exchangeserver.example.com/public
ProxyPassReverse /public https://exchangeserver.example.com/public
ProxyPass /iisadmpwd https://exchangeserver.example.com/iisadmpwd
ProxyPassReverse /iisadmpwd https://exchangeserver.example.com/iisadmpwd

#OMA
ProxyPass /oma https://exchangeserver.example.com/oma
ProxyPassReverse /oma https://exchangeserver.example.com/oma

#ActiveSync
ProxyPass /Microsoft-Exchange-ActiveSync https://exchangeserver.example.com/Microsoft-Exchange-ActiveSync
ProxyPassReverse /Microsoft-Exchange-ActiveSync https://exchangeserver.example.com/Microsoft-Exchange-ActiveSync