HOWTO: OWA 2K and 2K3 Front-end SSL Proxy with Apache 1.3

Last update: Tue May 11 00:47:04 JST 2004

If you are looking for a HOWTO that covers Apache 2.0, please see
HOWTO: OWA 2K/2K3 Front-end SSL Proxy with Apache 2.0 [http://3cx.org/item/46]

Keywords: outlook web access, OWA, front-end-https, proxy, libproxy.so, protect OWA, front-end-proxy, header, SSL, front, end, mod_proxy, apache, 2000, 2003, NT, windows

[I have successfully implemented this solution with SSL-aware Apache 1.3.27, 1.3.29, and 1.3.33 on Slackware Linux 9.x, Redhat Linux 7.3, and Redhat Enterprise Linux 3.1. I'm sure this can be done on any Unix that Apache 1.3.x compiles on. I have no idea how to do this on Apache 2.x as I'm lazy and have not yet moved my web servers to it. Also, this "HOWTO" does not cover setting up an OWA or SSL-aware Apache server. That's up to you. Sorry.]

Outlook Web Access 2000 and 2003 (OWA) runs on Microsoft's Internet Information Service (IIS). IIS is considered by many to be the swiss cheese of web servers (and I agree with this... sort of). I would never consider putting an IIS box on a publicly accessible network simply because it's just too much work to secure.

The point of having an OWA server is moot if one is not willing to allow access to it from the world. So, we need to somehow make the OWA service publicly accessible while not actually making the box itself publicly accessible (hopefully that makes sense. ;-). The answer? Proxy incoming requests with something a little more secure - namely Apache. Apache comes with a nice proxy module called mod_proxy. It does almost everything we need it to.

         INTERNET      +--------------+
            |          | APACHE PROXY |
            |          +--------------+
       +----------+           |
       | FIREWALL |------------------
       +----------+     Service net
            |
            |
                      +------------+
         Int Net -----| OWA SERVER |
                      +------------+


Remote users want to access OWA. They type https://webmail.somedomain.com into their browser. Their workstation/laptop then asks their DNS for the IP address of webmail.somedomain.com. The DNS replies with the IP address of the APACHE PROXY. The browser then connects to the proxy and sends its request. The APACHE PROXY then connects to the the internal OWA SERVER and requests the objects on behalf of the remote user. Simple enough.

Be aware that in this example, the Apache "proxy" is on a locked down service network. Nothing gets in or out of this net unless it is required. For the Apache "proxy", connection requests destined for port 443 (https) are allowed through the firewall from the world. Connection requests from the Apache "proxy" are also allowed through to destination port 80 on the internal OWA server. That's it. If the Apache "proxy" generates any traffic other than that, alarms go off (i.e. WARNING! WARNING! You may be 0wn3d!). I highly recommend this configuration for all pubicly accessible services.

Now, to make this bit of magic work, we need to do several things.

  1. Configure Apache to use the mod_proxy module.
  2. Patch the mod_proxy module so that it includes an additional header when sending proxied requests to OWA. OWA requires this header so that it knows it is being proxied by an SSL enable front-end.
  3. Add several ProxyPass configuration directives to the Apache config file.
  4. And finally add an entry to the Apache server's /etc/hosts file.


1. Configure Apache to use the mod_proxy module.

Ensure Apache's configuration file (httpd.conf) includes the following two lines.

LoadModule proxy_module /usr/lib/apache/mod_proxy.so
AddModule mod_proxy.c

NOTE: After adding the above lines to the Apache config file, Apache may not start. It all depends how your distibution's version of Apache was compiled or how you compiled it yourself. We still have to modify the mod_proxy module, compile it, and install it before any of this will work anyway.

2. Patch the mod_proxy module so that it includes an additional header when sending proxied requests to OWA. OWA requires this header so that it knows it is being proxied by an SSL enable front-end.

Modify the source of mod_proxy to include the "front-end-https" header in all proxied requests to OWA. The source for Apache can be downloaded from http://httpd.apache.org/download.cgi. It should also be included with your distribution (perhaps on a source CD). If you download the source from the Apache website, make sure it is the same version you are currently working with. The file that needs to be modified is

<apache source dir>/src/modules/proxy/proxy_http.c.

Somewhere around line 400 in proxy_http.c include the following line of code (You'll need a basic understanding of C to figure out where to put this.):

ap_table_set(req_hdrs, "front-end-https", "on");

After you've modified the source, recompile mod_proxy using the following command (while in the /src/modules/proxy directoy).

apxs -i -c *.c

This command will compile mod_proxy.

Now, copy the compiled proxy (libproxy.so) to your Apache module directory (i.e. /usr/local/apache/libexec - check your httpd.conf to make sure).

3. Add these ProxyPass configuration directives to your Apache config file. You may place them in the main section of the config or in a VirtualHost section. It all depends how you have your server configured. I've done it in both and either will work.

ProxyPass /exchange http://webmail.somedomain.com/exchange/
ProxyPassReverse /exchange http://webmail.somedomain.com/exchange/
ProxyPass /exchweb http://webmail.somedomain.com/exchweb/

ProxyPassReverse /exchweb http://webmail.somedomain.com/exchweb/
ProxyPass /public http://webmail.somedomain.com/public/
ProxyPassReverse /public http://webmail.somedomain.com/public/
ProxyPass /iisadmpwd http://webmail.somedomain.com/iisadmpwd/
ProxyPassReverse /iisadmpwd http://webmail.somedomain.com/iisadmpwd/
NoCache *


[ Updated: I changed the first two proxy configuration directives. The first ProxyPass and ProxyPassReverse directives were proxying /mail. I changed this to /exchange as that is the OWA default. In my office, we cofigured the OWA server so that /mail was /exchange. I thought this may confuse folks as it confused me when I re-read it today. (Thanks to Helmut!) ]

4. And finally add an entry to the Apache server's /etc/hosts file.

You may notice the ProxyPass directives redirect several directories to webmail.somedomain.com. But how can we redirect to webmail.somedomain.com if the Apache server is webmail.somedomain.com? We need to add an entry to the /etc/hosts file pointing webmail.somedomain.com to the internal OWA IP address.

192.168.0.100 webmail.somedomain.com

Be sure your server is configured to look in your hosts file before consulting the DNS. Check your /etc/host.conf file to make sure. It should read like this.

order hosts, bind
multi on

Now start Apache. Watch your logs for any errors. Make sure the appropriate access is configured through your firewall (world --> proxy dst tcp 443 and proxy --> internal OWA server dst tcp 80). Also remember to watch the logs on your internal OWA server.

Some things to watch include

  • Browser warnings about secure and insecure items on the same page - this could be a sign that the mod_proxy patch isn't working
  • Apache complaining about bad directives in its config file - could be a misspeled directive or a configuration conflict with your distro's version of Apache
  • Apache warning it could not find a certain object or could not find the OWA server - make sure you've added the right IP address to your /etc/hosts and that you've redirected all the required directories in your Apache config file (ProxyPass and ProxyReverse directives).


If you try implementing this and have problems or (sorry -- I'm bombarded with questions) have something you think I should add (or modify) to these instructions, feel free to contact me at mikeg@3cx.org. When I finally get around to moving my servers to Apache 2.0, I'll write up another "HOWTO" or possibly expand this one.
posted Fri 29 Apr 12:53:38 PDT 2005 by mikeg - permalink

Comments

Harin wrote:

This is awesome. Thank you for this excellent HOWTO.

Sat 18 Jun 22:46:57 PDT 2005

Steve wrote:

Excellent writeup. This is exactly what I'm trying to do. One queston though, could you tell me precisely where to inject the line above into the proxy_http.c file?

Here is the section around line 400:

if (r->proxyreq == PROXY_PASS) {
const char *buf;

/*
* Add X-Forwarded-For: so that the upstream has a chance to determine,
* where the original request came from.
*/
ap_table_mergen(req_hdrs, "X-Forwarded-For", r->connection->remote_ip);

/* Add X-Forwarded-Host: so that upstream knows what the
* original request hostname was.
*/
if ((buf = ap_table_get(r->headers_in, "Host"))) {
ap_table_mergen(req_hdrs, "X-Forwarded-Host", buf);
}

/* Add X-Forwarded-Server: so that upstream knows what the
* name of this proxy server is (if there are more than one)
* XXX: This duplicates Via: - do we strictly need it?
*/
ap_table_mergen(req_hdrs, "X-Forwarded-Server", r->server->server_hostname);
}

Thanks

Tue 18 Jul 07:20:17 PDT 2006

Steve wrote:

Nevermind, I patched and installed mod_proxy_add_forward from ports (FreeBSD) instead.

Tue 18 Jul 13:35:46 PDT 2006

vinay wrote:

I use apache 1.3.29 on solaris.
I have a Java servlet mapped to a URL pattern /auth on server https://svn500.abc.com.
However, my client wants another URL svn500-new.abc.com to be used for this servlet although my web server is hosted on https://svn500.abc.com.

I went through URL rewrite docs but could not get a constructive answer. Rewrite is not desirable way but will keep as last option.
I tried ProxyPass but proxy_http module is missing from our set up.

Can you suggest me a way out?

Thu 25 Jan 05:11:11 PST 2007

richard wrote:

I found that to get it to compile in 1.3.22 source, it is not "req_hdrs" but "reqhdrs"

Mon 23 Jul 15:38:46 PDT 2007

Chris Crawley wrote:

Thank you very much for a perfect solution. I came across one minor problem... I run Apache 1.3.33.

The minor problem was whenever I logged out, I was getting an invalid redirection. For example, domain.com/exchange after clicking logout, would become domain.com/exchangechris... not domain.com/exchange/chris...

I had to add additional trailing / to my URL but it works! Hope this helps anyone else with the same situation.

ProxyPass /exchange http://domain.com.au/exchan...
ProxyPassReverse /exchange http://domain.com.au/exchan...
ProxyPass /exchweb http://domain.com.au/exchweb//
ProxyPassReverse /exchweb http://domain.com.au/exchweb//
ProxyPass /public http://domain.com.au/public//
ProxyPassReverse /public http://domain.com.au/public//
ProxyPass /iisadmpwd http://domain.com.au/iisadm...
ProxyPassReverse /iisadmpwd http://domain.com.au/iisadm...

Thu 04 Oct 17:08:16 PDT 2007

BG wrote:

Thank you. Works perfectly on OpenBSD 4.0. Apache source on OpenBSD is in src.tar.gz.

Wed 13 Feb 18:46:18 PST 2008

Add Comments

This item is closed, it's not possible to add new comments to it or to vote on it


© 2002-2007 Michael Gauthier
Bother the webmaster at webmaster@3cx.org.


Our VPS Hosting
by RimuHosting
Java and Linux VPS Hosting by RimuHosting

Real Ultimate Power!

[QUIT SLASHDOT TODAY]