NetScaler – Exchange ActiveSync Device-Check

Reading Time: 3 minutes

Table of Contents

Overview

First of all, when using Microsoft Exchange Server OnPrem, try to use Modern-Authentication Methods like HMA (Hybrid Modern Authentication with Entra ID) or OAuth with ADFS (with NetScaler in front of 🙂 ) when there’s no Entra ID. Both is using the latest technology with browser-based authentication, giving different methods of MFA for ActiveSync.

When both isn’t technically possible, you maybe have to stay “classic” with NetScaler’s AAA 401-based Authentication.

This Post will cover some higher Security. Enabling Exchange ActiveSync Access only for iPhone and iPad, both coming from Apple’s native Mail-App and filtering DeviceID’s on the NetScaler directly, not on the Exchange with Quarantine (for example).

There’s a great Post from Michael Adam doing a similar thing, but checking the DeviceID’s filter on the Active Directory Attribute msExchMobileAllowedDeviceIDs.

Configuration

During my first tests with an iPhone and generating some traffic, I got an understanding on how ActiveSync works. And that’s the reason why the following script is using two times ActiveSync LB with different Content Switching Policies in front of.

When adding an E-Mail Account on iOS (iPhone and iPad with the native Apple Mail-App), the first Request to the Backend (Exchange Server, doesn’t matter if AAA is in place or not) is only requesting https://eas.julianjakob.com/Microsoft-Server-ActiveSync – there’s no DeviceID or other Device-Informations in the complete Request. If we are now filtering directly DeviceID’s on NetScaler, the Request never reaches Exchange and so the E-Mail Account can’t be added.

So we need to allow that first Request during adding a new account, followed by a Device-Check. So it might be possible to add an account from every Device – BUT when the Device isn’t listed in our Pattern Set, no E-Mail syncing will ever happen, the account is still empty.

The second Request (after the Mail-Wizard completed successfully) looks like that: eas.julianjakob.com/Microsoft-Server-ActiveSync?User=julian&DeviceId=D36561F5PT5E7314FOKPCVHHEE&DeviceType=iPhone&Cmd=Settings”

Now we are having a DeviceId, DeviceType and the Cmd=Settings stands for the first creation of the Account-Sync – followed by the third Request:

eas.julianjakob.com/Microsoft-Server-ActiveSync?User=julian&DeviceId=D36561F5PT5E7314FOKPCVHHEE&DeviceType=iPhone&Cmd=FolderSync”

FolderSync, like the name says, is the Request to sync Mails and Folders of the Account.

According of these informations on how the Account-Creation and Account-Syncing is working, the following CLI-Config includes:

  • A Content Switch Policy (lowest Prio, hits first) which checks FQDN, Header Microsoft-Server-ActiveSync, only hits when there is NO DeviceId in the Request, only hits for “Apple-iPhone” and “Apple-iPad” which are the Header of the native iOS Mail-App. This CS-Policy is only used for adding the account.
  • Another Content Switch Policy (higher Prio, hits second) which checks the DeviceId along a PatternSet, Checks also DeviceType iPhone or iPad (so only these two devices are allowed to sync). This CS-Policy is constantly used after adding the account, for syncing Mails / Calender / Contacts,…
  • Some matching Message-Actions for better understanding in ns.log who’s accessing Active Sync
#####replace cs_vsrv_exchange_ssl_443 with your CS vServer Name
#####replace eas.julianjakob.com with your public ActiveSync DNS-FQDN
#####replace AAA_vServer_nFactor with your AAA vServer Name for 401-based authentication for Active Sync
#####replace 10.10.10.10 with your Exchange-Server IP #01
#####replace 10.10.10.11 with your Exchange-Server IP #02
#####replace eg D36561F5PT5E7314FOKPCVHHEH with your allowed ActiveSync Device-ID's


set audit syslogParams -logLevel ALL -userDefinedAuditlog YES
set audit nslogParams -userDefinedAuditlog YES

add audit messageaction log_ActiveSync_General NOTICE "\"Allowed authenticated non-device-check request for \" + CLIENT.IP.SRC + \" who is \" + AAA.USER.NAME + \" who tried to access \" + HTTP.REQ.HOSTNAME + HTTP.REQ.URL.PATH_AND_QUERY" -logtoNewnslog YES
add audit messageaction log_ActiveSync_DeviceCheck NOTICE "\"Allowed authenticated device-check request for \" + CLIENT.IP.SRC + \" who is \" + AAA.USER.NAME + \" who tried to access \" + HTTP.REQ.HOSTNAME + HTTP.REQ.URL.PATH_AND_QUERY" -logtoNewnslog YES

add policy patset PatSet_ActiveSyncDeviceALLOWList
bind policy patset PatSet_ActiveSyncDeviceALLOWList D36561F5PT5E7314FOKPCVHHEH -index 2
bind policy patset PatSet_ActiveSyncDeviceALLOWList D36561F5PT5E7314FOKPCVHHEG -index 1

add server LB_Server_Exchange2019_01 10.10.10.10
add server LB_Server_Exchange2019_02 10.10.10.11


add lb monitor LB_Monitor-Exchange-EAS HTTP-ECV -send "GET /Microsoft-Server-ActiveSync/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add serviceGroup LB_ServiceGroup-Exchange-EAS SSL -maxClient 0 -maxReq 0 -cip DISABLED -usip NO -useproxyport YES -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP NO

bind serviceGroup LB_ServiceGroup-Exchange-EAS LB_Server_Exchange2019_01 443
bind serviceGroup LB_ServiceGroup-Exchange-EAS -monitorName LB_Monitor-Exchange-EAS

add lb vserver LB_vServer-Exchange-EAS-NA SSL 0.0.0.0 0 -persistenceType SRCIPDESTIP -cltTimeout 180 -authn401 ON -authnVsName AAA_vServer_nFactor
add lb vserver LB_vServer-Exchange-EAS-DeviceCheck-NA SSL 0.0.0.0 0 -persistenceType SRCIPDESTIP -cltTimeout 180 -authn401 ON -authnVsName AAA_vServer_nFactor

bind lb vserver LB_vServer-Exchange-EAS-NA LB_ServiceGroup-Exchange-EAS
bind lb vserver LB_vServer-Exchange-EAS-DeviceCheck-NA LB_ServiceGroup-Exchange-EAS

add cs action CS_Action_Exchange-EAS -targetLBVserver LB_vServer-Exchange-EAS-NA
add cs action CS_Action_Exchange-EAS-DeviceCheck -targetLBVserver LB_vServer-Exchange-EAS-DeviceCheck-NA


add cs policy CS_Policy_Exchange-EAS -rule "HTTP.REQ.HOSTNAME.SET_TEXT_MODE(IGNORECASE).EQ(\"eas.julianjakob.com\")&&HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"Microsoft-Server-ActiveSync\")&&HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"DeviceId\").NOT&&(HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"Apple-iPhone\")||HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"Apple-iPad\"))" -action CS_Action_Exchange-EAS -logAction log_ActiveSync_General

add cs policy CS_Policy_Exchange-EAS-DeviceCheck -rule "HTTP.REQ.URL.AFTER_STR(\"DeviceId=\").CONTAINS_ANY(\"PatSet_ActiveSyncDeviceALLOWList\")&&(HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"DeviceType=iPhone\")||HTTP.REQ.URL.SET_TEXT_MODE(IGNORECASE).CONTAINS(\"DeviceType=iPad\"))" -action CS_Action_Exchange-EAS-DeviceCheck -logAction log_ActiveSync_DeviceCheck


bind cs vserver cs_vsrv_exchange_ssl_443 -policyName CS_Policy_Exchange-EAS -priority 10
bind cs vserver cs_vsrv_exchange_ssl_443 -policyName CS_Policy_Exchange-EAS-DeviceCheck -priority 15


Summary

I hope this Post will help all Exchange OnPrem Fans to understand a simple and great way to heighten up the ActiveSync Security with NetScaler.

Leave a Reply

Your email address will not be published. Required fields are marked *