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.