In the last view months when I was doing consulting projects in UAG implementations, there was a high demand for a solution to an apparently very simple problem. Customers asked me to implement a MAC based filter to deny or grant access to clients logging on to a UAG portal. As you probably know, there is no out-of-the-box checkbox-based way get this up and running. However, because UAG is customizable in various and unbelievable ways, I want to give you a basic idea of how to deal with this specific requirement. So let´s have a look on the base scenario, to build a working prototype solution. Please notice, that in production environments, you should carefully review the pieces you get in this article and you double-check the security impacts and possible gaps to improve this proof of concept implementation. But, let´s start now!
1. Store a list of allowed MAC Addresses (a simple file in my case)
2. Detect all MAC Addresses during client connection
3. Compare the detected values against the file
I assume you already have a HTTPS-Trunk up and running before you follow the steps below.
1. Store a list of allowed MAC Addresses:
I decided to store the MAC Addresses I want to grant access to as a simple text file on the local c: drive of the UAG Server. Therefore I created a folder named MACPolicies and dropped a file called MACAddresses.csv there. The content of the file looks very simple as you can see here:
2. Detect all MAC Addresses during client connection:
The next part is a little bit more tricky and needs some manual configuration changes using the custom update mechanism built into UAG. We need to built a custom endpoint detection script which runs in the browser context on the user device. You have to pay attention that all the things you are doing here are sandboxed by Internet Explorer and you have to take care about the associated security restrictions. I generated a little VB-Script to query all network interfaces on the client device by using WMI. A very detailed description on how endpoint detections scripts can be used to gather different kind of data I recommend you to read through Ben´s Article Detection Agency. The code I used to detect the MAC Addresses can be examined here:
After developing and testing save your script on the UAG Server at the following location:
<UAG Installation Path>\von\InternalSite\CustomUpdate as you can see in my example.
The next step is to let UAG know that our custom script needs to be executed when client detection takes place. To get this done we need to create a new file in <UAG Installation Path>\von\InternalSite\inc\CustomUpdate with the name TrunkName(1:https,0:http)detect.inc, where TrunkName is the name of your trunk, 1 defines a https trunk, 0 defines a http trunk, and detect.inc. The content of the file is as simple as:
g_scriptList("/InternalSite/CustomUpdate/DetectMAC.vbs") = false
This custom include file tells the UAG Server that the DetectMAC.vbs script should also be used for client detection. You can compare your configuration with the following screenshot:
After you placed your files you can activate your UAG configuration and log on to your UAG Portal. You can use the Web-Monitor to check if there is a new session parameter called MACAddressSet which contains all detected MAC Addresses on your client device.
Now we got a string with all MAC Addresses on the client side and we can access this parameter any time we need to.
3. Compare the detected values against the file:
To compare the gathered values we need to make sure that the following steps are made. We need a server side place to put in some script code to get access to the session parameter. Further the code needs to open the file and the values there need to match one of the detected MAC Addresses. In my case I decided to use the PostPostValidate-Process to place my code. To achieve this we need to place a second file into <UAG Installation Path>\von\InternalSite\inc\CustomUpdate and name it in the same way we did before so that it looks like:
Let´s look into the content of the file. The script uses the GetSessionParam-Function to access the MACAddressSet variable. The MACAddressSet is split into an array and for each MACAddress in the array a check based on regular expressions is done. Once there is a match between the content of the file and the MACAddress in the array we know the user can get access to the portal. If there is no matching entry the user gets logged out and redirected to logoff page. Of course you can redirect to a second page and present a custom error page to the user. It is up to you. You can look at code here:
Save the file and activate your configuration. Then you can play around with your MAC Address file and test the results. As stated above this is proof of concept and you can feel free to refine the solution. Hopefully you got an impression on how flexible UAG can be and that most things can be done.