Protect OWA using a reverse proxy
Sometimes you just have a single public IP address (unfortunately ipv6 is not that widespread yet), and you still want to publish stuff like Outlook Web Access and other applications to the net in a secure way. If you want that, the easiest way to do so, is to just pass port 443 to the Exchange server. But this means that if you have other web apps, you have to run them on the Exchange server as well. And besides, not everybody wants to put an IIS machine directly out on the net..
One way to solve that, is by putting a reverse proxy like Apache or Squid in front of it. Since I could not find a ready-to-use recipe, I had to find out a lot for myself. After some trial-and-error and a lot of sniffing and searching through logfiles, I got it to work. I want to share this, so hopefully other people can get it done faster. I would still recommend other people to read a lot and try stuff out for themselves, but sometimes it’s more fun if you get some results early on, instead of after 2 weeks of hard labour
I use 2 reverse proxies myself. I use Apache2 as both a web server and as a remote proxy, so I can have a nice page in the root of the site, create additional php applications in subfolders, and proxy OWA and ActiveSync, running on another box. Then, I use Squid in front of Apache, to act as a cache, to speed up things. Of course all the bits and bytes still have to go to the internet with a reverse cache, but it saves some cpu cycles in the end, and applications feel much ‘snappier’.
So the setup is:
client – (squid – apache) – exchange
I use SSL on all three components (Exchange and the proxies). It probably causes quite some cpu overhead, but its easiest this way. ActiveSync does not support SSL offloading (according to Microsoft), so from the proxy, you will need to connect to the Exchange Server using HTTPS. (And if you use a HTTP frontend, OWA gets mixed up as well, the login screen won’t work anymore, blah blah.)
To start of with, the Exchange server. The only thing I set up there, is a self-signed certificate with multiple SAN’s (subject alternate names). This way, I get a certificate with a common name ‘mail.domain.nl’, but it will also accept requests to ‘exchange01′, and ‘exchange01.internal.local’, etc. Not really required, but saves a lot of frustration. I exported the certificate to a pfx file, and I use it for both Apache and Squid. (I converted the certificate to pem format first: more info)
Since I’m a FreeBSD fan, I cloned a new VMware guest running FreeBSD7, and installed Apache 2.2 from ports. I set Apache to listen to port 8443, and I put the following config in a file. I am not a 100% sure what all the settings mean again, I tried a lot getting it to work over the past week, and at least it works
<VirtualHost *:8443>
ServerName mail.domain.nl
ServerSignature On
ProxyVia On
RequestHeader set Front-End-Https “on”
DocumentRoot /usr/local/www/default/html
ExpiresActive On
<Directory /usr/local/www/default/html>
Order allow,deny
Allow from all
Options FollowSymLinks
AllowOverride None
ExpiresDefault A300
</Directory>
DirectoryIndex default.htm
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyErrorOverride Off
SSLProxyEngine on
SSLEngine on
SSLCertificateFile /usr/local/etc/apache22/certs/cert.pem
SSLCertificateKeyFile /usr/local/etc/apache22/certs/server.key
RewriteEngine on
RewriteRule ^/owa$ owa/ [R]
<Location /owa/>
ProxyPass https://exchange01/owa/
ProxyPassReverse https://exchange01/owa/
</location>
<Location /Microsoft-Server-ActiveSync>
ProxyPass https://exchange01/Microsoft-Server-ActiveSync
ProxyPassReverse https://exchange01/Microsoft-Server-ActiveSync
</location>
RewriteRule ^/customapp$ customapp/ [R]
<Location /customapp/>
ProxyPass http://appserver01/
ProxyPassReverse http://appserver01/
</location>
CustomLog /usr/local/www/default/logs/access.log combined
ErrorLog /usr/local/www/default/logs/error.log
LogLevel warn
</VirtualHost>
And then for Squid. I install Squid 3.0 from ports, and put the following config in:
hierarchy_stoplist cgi-bin
acl QUERY urlpath_regex cgi-bin
cache_effective_user squid
shutdown_lifetime 1 second
visible_hostname mail.domain.nl
#1GB disk cache
cache_dir ufs /usr/local/squid/cache 1024 16 256
maximum_object_size 5 MB
cache_mem 1024 MB
cache_swap_low 90
cache_swap_high 95
maximum_object_size_in_memory 512 KB
cache_replacement_policy heap LFUDA
memory_replacement_policy heap LFUDA
#this following line tells squid to listen on port 443 for SSL connections, and specifies the certs:
https_port 443 cert=/usr/local/etc/apache22/certs/cert.pem key=/usr/local/etc/apache22/certs/server.key vhost vport
#this following line tells squid to connect to the apache server, it will not verify the CA is from
#a trusted root, and it will pass authentication from the client to the apache server.
cache_peer 127.0.0.1 parent 8443 0 ssl no-query originserver sslflags=DONT_VERIFY_PEER front-end-https login=PASS
#make some nice ACL here:
http_access allow all
#for agressive caching
#minimum_expiry_time 3600 seconds
#refresh_pattern . 3600 100% 3600 ignore-no-cache ignore-reload override-expire override-lastmod
access_log /var/log/squid/access.log
cache_log /var/log/squid/cache.log
cache_store_log /var/log/squid/store.log
And that’s pretty much it! I have OWA working nicely, ActiveSync from my mobile phone over GPRS works like a charm. Although I don’t know if I have to tweak the connection timeouts for directpush, or if it will work out of the box. It looks fine for now. And the custom PHP applications run fine as well!






[...] Protect OWA using a reverse proxy [...]
Angelo’s blog » Protect OWA using a reverse proxy | November 24, 2008 | 11:51 pm[...] Protect OWA using a reverse proxy [...]
Ah, I made a mistake with the certificate. I should
Ah, I made a mistake with the certificate. I should have just converted the pfx file using:
openssl pkcs12 -in yourcert.pfx -out yourcert.pem -nodes
and then use that in Squid and Apache.
First of all, thx for the nice tutorial. I'm trying to
First of all, thx for the nice tutorial.
I’m trying to get a simular setup working but then without the apache.
Only problem I came across is starting squid with the ssl cert and key although I converted them to the right format.
Would it be possible to explain shortly how u was able to get a working pem and key file, as I can not seems to export to a .pfx key on the 2003 owa server.
The method I used was exporting the CAcertificate on w2003 to a .cer(DER) file and converted it using openssl to .pem, next I exported the ca certificate chain to a p7b file (only option in Microsoft Certificate Services) and also converted it to a pem key file. Squid keep telling me: Failed to acquire SSL private key :no start line. I guess I messed the the certificates up ?
Matthias, Probably you did not export the private key. And easy
Matthias,
Probably you did not export the private key. And easy way to export to pfx is to open the IIS Manager, then go to the default site, security, and there’s an option somewhere to export to PFX file INCLUDING the private key. If you can’t find it, google is your friend.
Got it working properly now, exporting the certs there did
Got it working properly now, exporting the certs there did the trick.
Thx again!
Hi Angelo I need to know if EXCH2007 SAN certificate
Hi Angelo I need to know if EXCH2007 SAN certificate needs to point to my squid server FQDN and how to do that.
Thanks, your post is very usefull for me.
Lucas, the certificate you have installed on your exchange box
Lucas, the certificate you have installed on your exchange box does not have anything to do with squid, it’s just for internal use.
The squid acts as a client to your exchange box, that’s it.
Can you explain why you had to use 'sslflags=DONT_VERIFY_PEER'
Can you explain why you had to use ‘sslflags=DONT_VERIFY_PEER’
I have a valid SSL cert on my exchange server but for some reason, squid doesn’t like it. (It threw a whole lot of errors (fwdNegotiateSSL: Error negotiating SSL connection on FD 17: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed)
I was eventually able to make it work by adding it to my squid.conf file too… but I don’t understand why I had to do it. The cert is valid and my browser doesn’t complain about it when I connect directly to OWA on the exchange server. Thoughts?
Wow... After banging my head against a wall for hours,
Wow… After banging my head against a wall for hours, I finally realized why I was getting that error. I will write it down here in hopes that it will help someone else.
I needed the ‘sslflags=DONT_VERIFY_PEER’ because I used an IP instead of a FQDN in the cache_peer line. (I changed ‘cache_peer 10.10.10.10 parent…’ to ‘cache_peer yoursite.yourdomain.com parent….’ (Where yoursite.yourdomain.com = the FQDN of the server you want to reverse proxy) and then added an entry for that site in my /etc/hosts file (with the real IP for the server I wanted to reverse proxy))
Again, I hope that the above gets picked up by the search engines and saves someone else a bit of pain.
Hey man thanks for the tutorial. Just wondering do you
Hey man thanks for the tutorial.
Just wondering do you know of any ways of getting any better performance out of squid? It seems pretty darn slow.
Any help with fine-tuning it’s performance would be appreciated.
In the meantime I’ll be RTFM’ing
I have tried this and I can't get it to
I have tried this and I can’t get it to work. I get errors about
An error occurred during a connection to owa.oursite.com.
SSL received a record that exceeded the maximum permissible length.
(Error code: ssl_error_rx_record_too_long)
Then the /var/log/httpd/error_log shows these errors:
[Mon Jan 25 20:36:05 2010] [error] [client 68.60.30.212] Invalid method in request \x16\x03\x01
[Mon Jan 25 20:36:05 2010] [error] [client 68.60.30.212] Invalid method in request \x16\x03\x01
[Mon Jan 25 20:36:22 2010] [error] [client 68.186.192.18] Invalid method in request \x16\x03\x01
[Mon Jan 25 20:36:26 2010] [error] [client 68.60.30.212] Invalid method in request \x16\x03\x01
[Mon Jan 25 20:36:26 2010] [error] [client 68.60.30.212] Invalid method in request \x16\x03\x01
Any ideas?
Arch
don't know, try http://www.google.com/search?q=squid+ssl_error_rx_record_too_long
don’t know, try http://www.google.com/search?q=squid+ssl_error_rx_record_too_long
I figured out the record too long thing....now I'm stuck
I figured out the record too long thing….now I’m stuck with the certificate problems (or whatever ever is keeping them from talking). OWA works but Outlook HTTP/RPC flat will not work How did you do your certificates?.
Arch
I don't use RPC over http, I only use OWA..
I don’t use RPC over http, I only use OWA.. Can’t help you with that, sorry.
Oh well....thanks anyway! Arch
Oh well….thanks anyway!
Arch
I figured out the record too long thing And the answer
And the answer was……?