Share via


Using URL Rewrite to block certain clients from Exchange

There are a number of ways to block undesirable connections from Exchange.  Take a look at the parent article for other methods.  Using this method, we can utilize a built-in feature of IIS 7 and above to prevent access from specific clients or client behavior.

Examples

Scenario 1
A VIP while traveling changed their password.  Unfortunately an ActiveSync device left at home continues to synchronize and eventually causes the VIP's Active Directory (AD) account to get locked.  The VIP needs to work while traveling but doesn't want to remote wipe the device.  The key pieces that make this a good example for URL rewrite are, a unique DeviceID, and the need to block before authentication.  The Allow Block Quarantine (ABQ) feature in Exchange 2010 or or configuring the allow list at the CASmailbox layer wouldn't work here since the authentication module is engaged before a deviceID can be blocked.

Scenario 2
Certain behavior identified by a new version of a client causes performance issues with Exchange.  For example, iOS 6.1 can cause high CPU and transaction log growth when very specific actions are taken.  Although we know how to block all devices of a user agent, in this case we just want to prevent these devices from performing the action.  The key pieces that make this a good example for URL rewrite are, a user agent, and a specific URL string that identifies the action.

Whenever considering a URL rewrite solution, first verify with your perimeter solution.  The most desirable solution implementation is at the perimeter, instead of each individual Client Access Server (CAS).  Also, since many perimeter solutions are Application aware (layer 7 in the OSI model), a custom response from the URL rewrite may trigger an unexpected response from the perimeter solution.  Here's a great example from the F5 community of an application aware perimeter solution that sparked the idea for the URL rewrite for the iOS 6.1 issue.

Let's take a look at how to implement a URL rewrite.  There are a couple ways to do this, but the new and improved URL Rewrite Module 2.0 makes getting started much easier.

 
1. Download and Install URL Rewrite Module

After downloading and installing URL Rewrite Module 2.0 from http://www.microsoft.com/en-us/download/details.aspx?id=7435 you'll see a new module available in IIS manager.

     

2.  Decide what layer is most appropriate to configure the rule

You can create a rule at the Web Site level, or the virtual directory level.  In Scenario 1, we would want to place the rule at the Default Web Site level in order to act upon the request before the authentication module is reached.  In Scenario 2, the best place to configure the rule is at the Microsoft-Server-Activesync virtual directory.  You can verify the layer the rule is applied by viewing the input field showing "URL path after".

     

3.  Create a rule

For simple rules like the example in Scenario 1, choose the "Request Blocking rule"

     

Here's the options to choose for a rule that blocks a specific Device ID.

       

The Blank rule is better suited for more complex requirements like Scenario 2.  Here's what the options should look like for blocking any request with the MeetingResponse command coming from an iOS 6.1 or iOS 6.1.1 device.  Since iOS 6.1.2 appears to fix the issue and the user agent is 1002.146 or higher, we can't use the wildcard notation.  Instead we can use Regular Expressions as detailed in the figure below.

     

After hitting Apply, the rule takes effect immediately.

4.  Copying the Rule.

To replicate this rule to other Exchange CAS, you can use the URL Rewrite GUI again, or you can insert the appropriate configuration information directly into the web.config file for the level you created the rule for.  Be sure to make a backup of the original web.config.  In the example above, the Scenario 1 rule for the DeviceID would go in the <system.webServer> section of the web.config for the Default Web Site [by default located C:\inetpub\wwwroot]

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
         <rewrite>
            <rules>
                <rule name="DeviceID block" patternSyntax="Wildcard" stopProcessing="true">
                    <match url="*" />
                    <conditions>
                        <add input="{QUERY_STRING}" pattern="*DeviceId=E3335CDF280E06835EE8529B688405DF*" />
                    </conditions>
                    <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

The same can be accomplished in the web.config for ActiveSync [by default located C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Sync] for the Scenario 2 rule.  Here's what the rewrite section would look like for the sample regular expression rule above.

       <rewrite>
            <rules>
                <rule name="iOS 6.1 to 6.1.1 block meeting response" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{HTTP_USER_AGENT}" pattern="^Apple.*1002[.]14[12345]" />
                        <add input="{QUERY_STRING}" pattern=".*Cmd=MeetingResponse.*" />
                    </conditions>
                    <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />
                </rule>
            </rules>
        </rewrite>

5.  Verifying the rule

The best way to verify the rule is to look at the IIS logs based on the custom response code specified in the rule created.  The default response is a 403.  I recommend this since it is a well-known HTTP status code that most perimeter solutions will honor.

Use the following commands from a powershell window to get a quickly get the glimpse you need.        

netsh http flush logbuffer
dir C:\inetpub\logs\LogFiles\W3SVC1\u_exyymmdd.log | select-string "403 0 " | Select-Object -last 20

If you see results like this, then you will know the rule is working correctly.

...
C:\inetpub\logs\LogFiles\W3SVC1\u_ex130215.log:2528:2013-02-15 20:59:51 192.168.1.50 POST /Microsoft-Server-ActiveSync/default.eas User=jane.doe@fabrikam.com&DeviceId=ApplALLURBASE&DeviceType=iPad&Cmd=MeetingResponse 443 - 172.16.1.110 Apple-iPad2C1/1002.141 403 0 0 93
...
C:\inetpub\logs\LogFiles\W3SVC1\u_ex130215.log:2889:2013-02-15 23:05:31 192.168.1.50 POST /Microsoft-Server-ActiveSync/default.eas User=john.doe&DeviceId=Appl8675309&DeviceType=iPhone&Cmd=MeetingResponse 443 - 172.16.1.104 Apple-iPhone3C1/1002.144 403 0 0 78
...

6.  Troubleshooting the rule

  • If the Application Pool for the service the rule was implemented is failing to start, this is likely due to a typo in the web.config - restore the original web.config and create the rule using the URL Rewrite module.
  • If devices are getting authentication prompts or resynchronizing the entire mailbox, this is unexpected.  This is likely due to the perimeter solution responding to the device translating customer response of the rule to something else.  Be sure to verify with your firewall, load balancer, Mobile Device Management solution or other perimeter solutions to see if there is a way to honor the custom response delivered by IIS.
  • If you are seeing 500 50 HTTP status codes in the IIS logs, there's a problem with the syntax of the rule.  Every character is important, especially if you are using regular expressions.
  • For Scenario 2, it's expected the organizer won't receive a meeting response.  If they are, the attendee is either responding to the meeting from another client or the rule isn't working.  Ensure the Logical Grouping "Match All" was selected and the checkbox "Ignore Case" is ticked from step 3.
  • For Scenario 2, it's expected the meeting request calendar item will get synchronized to the device and mailbox calendar.  If it isn't the device is likely not synching correctly and you should confirm with your perimeter solution provider a translated response isn't being sent to the device.

**7.  What is the end-user experience?
**
After implementing the rule, iOS 6.1/6.1.x users will have a different experience when it comes to meetings.

  • iOS 6.1/6.1.x users will not be able to respond to meeting requests
  • On the device it will appear that the response was successful
  • On the device, the user will see "my status" set to their status (Accepted, Maybe, etc) when viewing the event on the Calendar.  The meeting organizer will never see this response of course, since IIS is dropping the response before it gets to Exchange.
  • The meeting request in the Inbox will remain, where a successful MeetingResponse would have triggered this invite item to be deleted