Publishing Exchange Web Services remotely only for Lync

A recent Lync project for me involved a scenario where the customer who was not publishing any aspect of Exchange remotely. They were using Good for all email to mobile devices, and had elected not to publish Outlook Anywhere or Outlook Web app remotely. This presented some challenges in terms of features available to remote Lync clients since a lot of functionality comes from Exchange Web Services (EWS). If EWS is not available a Windows Lync client can fall back to pull some data from Outlook via MAPI, but that does nothing to help a Mac Lync user, Lync mobile devices for iOS, or any Lync Phone Edition clients. All of those require EWS to be published remotely or there will be some feature loss and very visible errors within the user interface.

To work around this issue we started with a goal to publish only Exchange Web Services to support Lync clients, and still prevent all other types of clients from connecting to Exchange remotely. Publishing only EWS is a straightforward process and can be done through the TMG publishing rules. After using the Outlook Anywhere publishing rule template in TMG simply edit the paths tab and remove everything except /EWS/* and /Autodiscover/*:

image

This will effectively allow remote users to connect and do autodiscover queries. Remote Outlook clients will perform a successful autodiscover lookup, but see Outlook Anywhere is disabled (assuming you’ve disabled it on the CAS!) and not attempt a connection. You’ll also want to make sure the ExternalURL property of your EWS virtual directories are populated with the correct FQDN and that public names for that URL and autodiscover are allowed in TMG:

image

This would work great if all you had in the world were PCs, but the challenge here is the Mac Outlook and older Entourage 2008 Web Services clients are entirely based on EWS and by configuring the previous tasks in TMG we were now allowing those remote clients to connect. We needed some way to block those clients so we settled on filtering based on the User Agent string, which is a unique string within the HTTP header identifying the type of client making a request. We started with working out which user agents we actually needed to allow and came up with the following list after running some logs and tracking the user agent headers in sample client connections:

  • Lync iOS (iPad and iPhone): Microsoft Lync iPhone
  • Lync Phone Edition: OCPhone
  • Lync PC: OC
  • Lync for Mac: MC

TMG actually has a User Agent filtering tool built in, but it was very unfortunately written backwards for what we needed. You can see here that TMG is expecting you to explicitly block specific user agents that you don't want to allow:

image

That seems like a good idea if you know all the strings for every possible EWS client out there, but what happens when a new client comes out that’s not specified here? It would be allowed to connect and bypass the restrictions we were trying to impose. In this scenario a load balancer such as an F5 BigIP or A10 Networks AX device can be incredibly handy because of their iRules and aFlex engine. In our case we were able to use the aFlex rules to block requests from everything except the clients we wanted to explicitly allow. The actual code is here:

when HTTP_REQUEST {

#log local0. "[HTTP::header "User-Agent"] INBOUND"

if { ([HTTP::header "User-Agent"] matches_regex "Lync.*") or ([HTTP::header "User-Agent"] matches_regex "Microsoft\+Lync\+iPhone\/.*") or ([HTTP::header "User-Agent"] matches_regex "MC\/.*") or ([HTTP::header "User-Agent"] matches_regex "OC\/.*") or ([HTTP::header "User-Agent"] matches_regex "OCPhone.*") } {

pool ews

} else {

#log local0. "[HTTP::header "User-Agent"] REJECT"

reject

}

}

This method is not foolproof since a user agent can be spoofed fairly easily, but it met the needs of this particular project. You should also keep in mind that if Outlook Web App and the Exchange Control Panel are not published remotely then users will be unable to edit their voicemail options or manage personal call answering rules from the Internet. In my case requiring users to connect their VPN to use those features was an acceptable solution.

Exchange 2010 SSL Offloading

One of the deployments I've been working on recently involved using F5 BigIP hardware load balancers to do SSL offloading for a two-node Exchange 2010 design. To give some background here usually you would just pass through port 443 (I'm skipping over the RPC Client Access piece since it's not relevant here) from your load balancer straight to the Exchange servers, letting the servers handle the SSL encryption like in this diagram:

image

The benefit of that approach is it's simple and a very common deployment method. On the flip side, you can benefit from offloading SSL encryption to the BigIPs and gain some more advanced forms of load balancing. In this case the improved load balancing was the goal along with some internal policies forcing this approach. What happens with SSL offloading is the HTTPS traffic ends at the BigIPs which turn around and pass port 80 clear-text traffic back to the Exchange servers so they have a bit less CPU work to do. That strategy looks more like this:

image

The problem with this configuration is Exchange is really designed to operate with SSL in mind and you have to go out of your way to allow it to operate in clear-text. What you'll need to configure on each CAS server is:

The issue I ran into is after following all of these steps Autodiscover was still not functional through the load balancing. I could enter https://<CAS Array FQDN>/Autodiscover/Autodiscover.xml into a browser and reach the XML file with no problem, but running the Autodiscover test within Outlook would return a 404 error. Every other service was working just fine:

image

This threw me for awhile and after a bit of searching I ran across KB 980048 where it's noted that Autodiscover cannot be used on port 80 with an HTTP POST request, which is what Outlook uses. My attempts at accessing the XML directly succeeded because I was only trying to download the file. Supposedly this is going to be fixed in Service Pack 1.

While the KB provides no immediate solution what I found that works is to use the same methodology Technet recommends for the Exchange Web Services web.config file. Go into your /Autodiscover folder and edit the web.config to replace all instances of httpsTransport with httpTransport (a simple search and replace should work). Be sure to save a copy before you make modifications, restart your server after making the change and you should be able to offload SSL for Autodiscover successfully. Since as far as I know this is undocumented today you can try this at your own risk, but it appears to be working.