In many environments, putting an Exchange 2007 front-end server directly on the Internet is not a desired configuration – either because of technical limitations or security concerns.  One solution is to have an Apache HTTP server on the network perimeter to act as a reverse proxy to an internally located Exchange 2007 server.  The following example is an Apache configuration to:

  • Redirect browsers from http://webmail.domain.com/ to the secure https://webmail.domain.com/
  • Redirect from the root of https://webmail.domain.com to https://webmail.domain.com/exchange – you may wish to redirect to /owa if you use a pure Exchange 2007 environment.
  • Any requests to the https://webmail.domain.com/* will be dynamically tunneled through Apache’s reverse proxy to the internal Exchange system and served back to the client.

The main advantage of the below configuration is that using the ReWriteRule directive with the [P] parameter (Proxy), we can avoid having many individual ProxyPass and ProxyPassReverse directives for each of the Exchange 2007 virtual directories.  Nice, clean, simple.

ProxyRequests Off
<VirtualHost webmail.domain.com:80>
  ServerAdmin hostmaster@domain.com
  ServerName webmail.domain.com
  #ErrorLog /var/log/apache2/webmail.domain.com-error_log
  #CustomLog /var/log/apache2/webmail.domain.com-access_log combined

  ProxyPreserveHost On
  RewriteEngine on
  # Redirect http traffic to https
  RewriteRule ^/(.*)$         https://webmail.domain.com/$1 [L,R]
</VirtualHost>

<VirtualHost webmail.domain.com:443>
  ServerAdmin hostmaster@domain.com
  ServerName webmail.domain.com:443
  #ErrorLog /var/log/apache2/webmail.domain.com-ssl_error_log
  #TransferLog /var/log/apache2/webmail.domain.com-ssl_access_log
  #CustomLog /var/log/apache2/webmail.domain.com-ssl_request_log ssl_combined

  SSLEngine on
  SSLProxyEngine On
  RequestHeader set Front-End-Https "On"
  ProxyPreserveHost On
  RewriteEngine on
  CacheDisable *

  # Rewrite the WWW-Authenticate header to strip out Windows Integrated
  # Authentication (NTLM) and only use Basic-Auth
  SetEnvIf User-Agent ".*MSIE.*" value BrowserMSIE
  Header unset WWW-Authenticate
  Header add WWW-Authenticate "Basic realm=webmail.domain.com"  

  # Redirect / to /exchange
  RewriteRule ^/$             https://webmail.domain.com/exchange/ [R]

  # Reverse proxy all requests to the internal Exchange 2007 server
  RewriteRule ^/(.*)          https://exchange.domain.internal/$1 [P]

  SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
  #SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:RC4-MD5:+HIGH:+MEDIUM:+SSLv3:+SSLv2
  SSLCertificateFile /etc/apache2/ssl.crt/webmail.domain.com.crt
  SSLCertificateKeyFile /etc/apache2/ssl.key/webmail.domain.com.key

  SetEnvIf User-Agent ".*MSIE.*"    \
  nokeepalive ssl-unclean-shutdown  \
  downgrade-1.0 force-response-1.0
</VirtualHost>

Related posts:

  1. Creating an Outlook 2007SP1 Autodiscover DNS Record with BIND One of the newest features of Outlook 2007SP1 combined with...
  2. support.microsoft.com not working through proxy? A couple people at work pointed out that support.microsoft.com would...
  3. Blog Stats Since I just surpassed 100 posts on this blog, I...
  4. iMac: The saga begins For almost two hours, we are the proud owners of...
  5. Mac OS X 10.5.x and Windows 2008 Clustered File Share Problems After upgrading a Windows Server 2003 clustered file server to...

40 Responses to “Apache as a reverse proxy to Exchange 2007 Outlook Web Access”
  1. solo says:

    Is there an apache2 config version also ?

    Len Reply:

    Hi Solo,
    This config is for Apache 2. I have it running in production on Apache 2.0.49.

  2. nh says:

    Hi Len,

    is this configuration useable with ActiveSync? I set up a Apache 2 on ubuntu server but i have Problems to export the SSL Cert from Exchange server. Its a selfsigned certificate which was created on Exchange installation. At first i wanna test the apache 2 proxy in our internal network, so proxy and exchange are in same subnet.

    SSL is activated on exchange, owa and activesync work on internal network. Now i wanna check the redirection from Apache. How can i create myexchange.crt and myexchange.key for apache 2 server?

    Len Reply:

    Hi nh,
    Yes, this does with with Windows Moble Activesync. Activesync can be pretty finicky about the SSL certificate. The SSL certficate MUST be trusted by the Windows mobile device. This means a self-signed certificate must be manually installed in to the devices trusted root certificates store OR a valid SSL certificate must be used on your front-end server. I’ve found it’s just plain easier to use a true valid SSL certificate.

    I believe that the /Microsoft-Server-ActiveSync virtual directory in IIS will require Windows Authentication to be enabled as well.

  3. Rob says:

    Hi,

    First of all, nice write-up.

    I a wondering if you can get this to work with a HTTPS front-end on Apache, and a HTTP (instead of HTTPS) back-end on Exchange. I am trying for some time to get this to work, but no luck yet. It seems like OWA rewrites the URL including the used protocol.

    Do you have any ideas on how to do this?

    Len Reply:

    Hi Rob,
    Going to HTTP instead of HTTPS on the back-end should be easy. You should only need to change:
    # Reverse proxy all requests to the internal Exchange 2007 server
    RewriteRule ^/(.*) https://exchange.domain.internal/$1 [P]
    to:
    # Reverse proxy all requests to the internal Exchange 2007 server
    RewriteRule ^/(.*) http://exchange.domain.internal/$1 [P]

    I have tried that configuration and it did work but unfortunately, it seemed to break the Microsoft Activesync for whatever reason.

  4. Crispin says:

    Great stuff – clear, simple, concise.

    Does the proxy have any issues with attaching large files…? We’ve got a reverse proxy setup on apache 1.x and can’t attach files larger than 47K.

    Might move to this config if it solves that issue though – thanks!

    Len Reply:

    Hi Crispin,
    I vaguely remember hearing about this issue a while back. I think it is limited to Apache 1.x installations. You might want to give Apache 2.x a try as I have not encountered this issue myself. As mentioned in another comment, I run this configuration with Apache 2.0.49 with no problems.

  5. Scott says:

    Hi there.
    Fantastic work. It took me a while to get going (mostly my fault). But it’s the best solution I’ve seen to the problem. I can confirm that ActiveSync works (on the iPhone). I haven’t checked push yet.
    Just a couple of things:
    There are backslashes (\) missing on the line (which is broken into three):
    “SetEnvIf User-Agent “.*MSIE.*” nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0″
    It should either look like the line above, or:
    SetEnvIf User-Agent “.*MSIE.*” \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0

    The second thing is that I could not get it to work with exchange 2007 unless I changed /exchange to /owa in the line:
    RewriteRule ^/$ https://webmail.domain.com/exchange/ [R]

    This is actually mentioned right at the start, which of course I forgot. It also says “may”, whereas I found the I “must” change it to /owa.

    Thanks for the great work.
    Scott

    Len Reply:

    Hi Scott,
    Thanks for pointing out the missing backslashes. I’ve corrected the configuration.

  6. Rocco says:

    Hey,

    thanks for this quick and simple guide for reverse proxying to Exchange. However RPC over HTTPS doesn’t work on Apache > 2.0.54, due to the bugfix as stated on

    Rocco Reply:

    … as stated on https://issues.apache.org/bugzilla/show_bug.cgi?id=40029

    Len Reply:

    Hi Rocco,
    You are correct that RPC over HTTPS (Outlook Anywhere) will not work on recent versions of Apache. It seems Microsoft is unwilling to fix the compatibility and Apache will not allow a configuration feature to correct this function even if it breaks HTTP spec.

    The most effective work around I found was to have a separate instance of Apache 2.0.49 listening on the SSL port (443) of the front-end system. The exact configuration will likely depend on your environment. For work, I run multiple reverse-proxies through Apache 2.2.3. Since RPC over HTTP is picky, I have a very minimal install and configuration for Apache 2.0.49 only to listen on the webmail IP and port 443.

    Building Apache 2.0.49 on a modern Linux distribution can be a bit challenging. Here are some instructions that may help:

    1. Download Apache 2.0.49 from http://archive.apache.org/dist/httpd/httpd-2.0.49.tar.gz

    2. Patch the clean Apache 2.0.49 with: apr_network-sctp-detection.patch

    3. Run ./buildconf

    4. Configure as:
    ./configure –enable-modules=”headers proxy proxy-http proxy-connect rewrite vhost_alias ssl”

    5. Change the occurances of PEM_F_DEF_CALLBACK in ./modules/ssl/ssl_engine_pphrase.c to: PEM_F_PEM_DEF_CALLBACK

    6. make

    7. Configure similar to above and remember to set your Listen directive.

    Good luck!

    Rafal Reply:

    Hi Len,

    I’m not an expert of apache server. For last week I tried set the apache 2.2.3 to work as RPC proxy, especially for PRC via HTTPS. I found your solution, I download apache source in proper version, but I don’t know how do the path operation with apr_network-sctp-detection.patch

    I found file named “apr_network” and I reedited, found main function, added few lines i saved. So i have done it manually.
    Next, I changed the file ./modules/ssl/ssl_engine_pphrase. When I tried to compile, appeared error, definition or function named PEM_F_PEM_DEF_CALLBACK doesn’t exists.
    I think either I didn’t pathed proper or something else was wrong.

    regards

    Rocco Reply:

    Thanks for your workaround, however I am more keen on having more recent versions. My workaround is now trying to get Squid working as a reverse proxy for Outlook. It works great, but only I have some security issues with proxying for other Apache servers :)

    Regards,

    Len Reply:

    Hi Rocco,
    I certainly wish there was a better solution than using a very old version of Apache and patching it to make it work with modern Linux distributions. It would be nice if a patch or –configure switch was available with recent versions of Apache to make it compatible with RPC over HTTP. Just the same, it would be nice if Microsoft would not roll their own HTTP protocols specific to their products.

    I’ve looked in to the squid solution for reverse-proxying RPC over HTTP but didn’t want to have two different applications performing the same functionality.

    Unfortunately there just isn’t a simple way to get RPC over HTTP working correctly. On the bright side, a competent system administrator can still get everything working and the end-users will have the functionality they require.

  7. Matt says:

    Hi and thanks,

    I am getting an error when restarting apache with the above config, modified for my environment.

    Syntax error on line 55:

    It says “Invalid command “CacheDisable”, perhaps misspelled or . . . . . . . .etc”

    Please help. If I # this line, it then errors at SSLCertificateFile: file %path% does not exist or is empty. I am assuming I need to get an SSL cert for the external FQDN and stick it in this path?

    Thanks.

    Len Reply:

    Hi Matt,
    You probably don’t have a caching module installed so you can safely #comment out the CacheDisable line.

    The SSLCertificate is a good recommendation since you probably don’t want usernames, passwords and potentially confidential information being transmitted in clear text from your webmail system. You are able to generate your own SSL certificate for testing purposes.

    I haven’t tried this configuration wich Apache on Windows but it should work.

  8. Matt says:

    Apologies, my version of Apache is 2.2.11 with openssl 0.98i. Running on windows 2003 R2 SP2.

    Thanks.

  9. Bruce Muir says:

    Hi i have a slight issue i’ve been smacking my head against a wal all day.

    No matter what i do i get an “you are not allowed to access /exchange/ on this server, i don;t have access to the exchange server itself, is there something in exchange i need to alter?

    Len Reply:

    Hi Bruce,
    Are you able to provide a little more detail about this error? I’m not sure if it is being generated by your Apache front-end or by the Exchange server itself. If using the rewrite with proxy statements shown in the article, Apache should not give an error like this.

    Of course you should verify that your Outlook Web Access is working 100% correctly on your internal network to minimize any problems when putting the service on the Internet.

    Ezequiel Alaimo Reply:

    i solve this adding a line in /etc/apache2/mods-available/proxy.conf

    Allow from all

    but now, i have an error:

    cat /var/log/apache2/error.log
    [warn] proxy: No protocol handler was valid for the URL /owa. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

    and this error in my browser:
    Internal Server Error

    The server encountered an internal error or misconfiguration and was unable to complete your request.

    Please contact the server administrator, hostmaster@domain.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.

    More information about this error may be available in the server error log.
    Apache/2.2.9 (Debian) mod_ssl/2.2.9 OpenSSL/0.9.8g Server at mail.mariva.com.ar Port 443

    Sorry for my bad english!.

    Ezequiel Alaimo Reply:

    i solve this with

    a2enmod proxy_http and restarting the APACHE

  10. rupat says:

    Is there a way to get rpc over https running with Apache Exchange Communication via standard http (not https) and only get the connections outlook client Apache Proxy over https ?
    We have to “offload” the rcp connection via the reg entries described. here.
    I tried it this way (no certifikat and ssl on the windows host) but getting the following errors in apache vhost:
    [Thu Jul 16 17:48:34 2009] [error] (104)Connection reset by peer: proxy: prefetch request body failed to 10.0.10.2:80 (10.0.10.2) from 43.118.184.37 ()
    [

  11. Martijn says:

    I’ve put your vhost on my apache and it works great, but i seem to have some trouble with my certificates.
    I have a certificate on my owa witch i want to convert to a .key and .crt, i honestly don’t know how.

  12. Frederick says:

    As regarding 2.0.49 and the patch. I downloaded both the tar.gz and the tar.Z files of pache2.0.49 and compared their checksums and everything matched up.

    When I went to apply the patch the file ./build/apr_network.m4 was not there. The only apr_ file was apr_common.m4.

    I’ve considered checking earlier or later sources to see if apr_network.m4 is there but who knows how it may have changed over the revisions?

    Does anyone have any suggestions or an idea where I can get the apr_network.m4 file?

    Thanks,
    Frederick

    Len Reply:

    Hi Frederick,
    The full path to the file is:
    httpd-2.0.49/srclib/apr/build/apr_network.m4

    I hope that helps.

  13. Frederick says:

    A VERY large thank you!!!

  14. Frederick says:

    I’m back. I would like to greatly thank you for this tutorial you’ve posted as it is the basis for upon which I’ve built my current reverse proxy for exchange. I am, however, still not able to get rpc/http(s) working.
    This is because when I try to follow the instructions herein for cimpoling apache from source It won’t compile firstly just running buildconf generates the following errors
    snippet
    buildconf: checking installation…
    buildconf: autoconf version 2.63 (ok)
    buildconf: libtool version 2.2.6 (ok)
    Copying libtool helper files …
    buildconf: Using libtool.m4 at /usr/share/aclocal/libtool.m4.
    Creating include/arch/unix/apr_private.h.in …
    autoheader2.50: WARNING: Using auxiliary files such as `acconfig.h’, `config.h.bot’
    autoheader2.50: WARNING: and `config.h.top’, to define templates for `config.h.in’
    autoheader2.50: WARNING: is deprecated and discouraged.
    autoheader2.50:
    /snippet
    It goes on for many more lines of errors all pointing to an issue with the libtool version. (which it requests >1.3 and i’m running 2.2.6) //which is likely to be too different.

    The main reason I’m wanting to use apache is so that I might make use of mod_security, otherwise I’d use pound or squid.

    I’m guessing my main question is this; if I wish to continue upon this path is my only reasonable recourse to install an old OS and statically compile apache? Or is there perhaps some avenue I might have over looked.

    Thanks again for all the great sharing and work you’ve done.

    Frederick

  15. Frederick says:

    Update:
    After sleeping on it I awoke refreshed and of a clearer head.
    Notes to anyone who may be needing them.
    I, at least, on debian squeeze/unstable had to do the following to get it to compile

    Following Len’s instructions (which were very helpful) in addition to his instruction above

    I had to download the source for the following:
    openssl-0.9.6m
    libtool-1.4.3 //was referenced but available in repo
    httpd-2.0.49

    install autoconf 2.13 from the repos

    And now begins the fun of configuring the old apache.

    Note: if anyone is interested I plan on doing a full how-to/write-up as to my adventures in this and will find somewhere online to post them. As I feel, that unless either apache or MS decide to get their head out, many other sys-admins in the future will face similar issues.

    Thanks again Len and everyone for your help.

  16. Ezequiel Alaimo says:

    Very thankyou!!!…

    I had to load these modules to run the solution:

    a2enmod proxy
    a2enmod proxy_http
    a2enmod ssl
    a2enmod headers
    a2enmod rewrite
    a2enmod cache

    ALL IS WORKING VERY WELL!!

    PD: sorry about my english..

  17. Scott says:

    Hi there (again!)
    Just wondering if anyone has problems with this configuration with the new iPhone iOS 4? I’m having trouble sending mail.
    When I bypass my reverse proxy by using a VPN to my network, everything works fine. When I go through the RP, sending mail fails.
    My suspicion is with either the phone or the proxy not setting either a Content Length or the Transfer Encoding to Chunked. I have tried with and without “SetEnv force-proxy-request-1.0 1″.
    I have also tried ” SetEnv proxy-sendchunked 1″ and “SetEnv proxy-sendcl 1″ in various permutations, and it seems to me that Apache is not honouring thsoe settings (I cannot see chunked or content-length in the request headers).
    Looking at a packet trace, midway through the POST from the phone I get:
    “HTTP/1.1 411 Length Required … HTTP Error 411. The request must be chunked or have a content length” (snipped for brevity).
    I need to trace my old iPhone to see if anything has changed from 3.1.x to 4.0 of iOS. Also, I’m running Exchange 2010 but because the proxied request doesn’t contain chunked or content-length I don’t think it’s relevant.
    Thanks
    Scott

    Scott Reply:

    Quick update: Apache 2.0.49 silently ignores the directives SetEnv proxy-sendchunked and SetEnv proxy-sendcl (they weren’t included until later in the mod_proxy code).

    Scott Reply:

    Ok – Seems Apache 2.0.49 doesn’t support Transfer-Encoding: chunked. And I think support for it was included at the same time as the fix which disabled the use of Microsoft’s dodgy RPC_DATA implementation.
    However, I’ve installed a patch which was mooted on the apache web forums which works with 2.0.54 (the last release before the RPC_DATA fix, along with 2.0.49). Find it here: http://www.apache.org/~trawick/20proxyreqbody.txt. The discussion at https://issues.apache.org/bugzilla/show_bug.cgi?id=15859 is really interesting.
    The upshot of all of this is that if you want the iPhone iOS4 to send mail though the Exchange server via the proxy, you’ll need this patch. Bearing in mind the vulnerability inherent with supporting Microsoft’s RPC over HTTP kludge (comment #1 in the discussion).
    Scott

    Duncan Reply:

    Hi Scott,

    I am running into a comparable issue. The Windows Mobile devices won’t sync if apache is in between (449 errors in IIS logs). I have also tried the SetEnv proxy-sendchunked 1 setting, but to no avail.
    The devices have their mailbox stored on Exchange 2003 and are proxied through an Exchange 2007 CAS.

    Duncan

  18. ehcache.net says:

    Apache as a reverse proxy to Exchange 2007 Outlook Web Access…

    In many environments, putting an Exchange 2007 front-end server directly on the Internet is not a desired configuration – either because of technical limitations or security concerns. One solution is to have an Apache HTTP server on the network perimet…

  19. Andrew says:

    I am curious Len to see what exact modules i need to do this. I am trying to do your config above for Exchange 2010. and am curious to see if it works. I also would like to use a non standard port externally of 8080 can you help me as to what that would look like? Im using Centos to do this config. please help thank you

  20. raymond says:

    I added the example code to a clean install of apache2, enable all the mod but when i hit the reserve proxy server, i get the index.html page. What am I missing. Sorry i’m a noob here.

    Raymond

  21. James Laszko says:

    I used this as a guide to create a proxy on Windows Apache 2.2.21 with OpenSSL and had to make the following changes:

    Uncomment the modules listed above in httpd.conf

    Add in httpd.conf: Listen 443

    Uncomment the httpd-vhosts.conf line in httpd.conf

    Put the configuration listed above in httpd-vhosts.conf (clear out everything in there before)

    Add in httpd-vhosts.conf: NameVirtualHost
    Modify VirtualHost statements to use private IP instead of hostname
    Make sure ServerName element inside VirtualHost is the “webmail” hostname and for SSL is the CN on the certificate

    Hope this helps Windows Apache users out there!

    James

  22. Peter Haas says:

    I have managed this with apache 2.2.22 & Exchange 2010 owa
    Outlook 2007 produces a proxy error, however afterward the application proceeds as normal.

    I used the following in my virtual host:
    RewriteEngine On
    RewriteRule ^/$ /owa [R,L]
    RequestHeader set Front-End-Https “On”
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / http://FQDN/
    ProxyPassReverse / http://FQDN/
    #PH – I haven’t compiled with a cache module
    #CacheDisable *
    SetEnv force-proxy-request-1.0 1
    SetEnv proxy-nokeepalive 1