cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
20768
Views
10
Helpful
0
Comments
Nelson Rodrigues
Cisco Employee
Cisco Employee

Note: Use of ASA security applicance Dynamic Access Policy (DAP) Advanced custom LUA functions should be used only if the ASDM GUI configuration or the EVAL function doesn't provide the needed matching behavior.

 

In a real production deployments ,use Advanced LUA functions with extreme care and with guidance from Cisco engineering/TAC, to avoid any unintended behavior with DAP.

 

 

 

 

Introduction

When working with Dynamic Access Policies ( DAP ) for remote access VPN, sometimes additional flexibility of match criteria may be desired. For example, you may wish to apply a different DAP based on:

  1. Organizational Unit (OU) that the user object is contained within (or other level of the hierarchy)
  2. Group Name (memberOf) that follows a naming convention but has many possible matches (customer might request the ability to wildcard on group names".
  3. Check for Any Antivirus, AntiSpyware, Firewall packages on the endpoint PC

This can be accomplished by creating a logical expression in the Advanced section of the dynamic access policy.

In DAP Advanced mode , custom functions can be entered using the following syntax:

 

assert(function()

           <insert custom Lua code here>

end)()

 

 

 

 

 

 

 

 

 

The code must be valid LUA code and should return true or false.

 

If images  don't show in this document you may need to View as PDF in the Actions box.

 

Here's an example of how it it configured in ASDM:

 

Dap_advanced1.gif

 

1. OU-Based Match Example

There are many attributes returned from the LDAP server which DAP can use in a logical expression.

 

See the DAP trace section for example output of this, or run a debug dap trace on the ASA console.

 

A user's Distinguished Name (DN) is returned by the LDAP server, which implicitly identifies where in the directory the user object is located. For example, if the user's DN is CN=Joe User,OU=Admins,dc=cisco,dc=com this user is located in OU=Admins,dc=cisco,dc=com. If all administrators are in this OU (or any container below this level) we can use a logical expression to match on this criteria as follows:

 

assert(function()

   if ( (type(aaa.ldap.distinguishedName) == "string") and

        (string.find(aaa.ldap.distinguishedName, "OU=Admins,dc=cisco,dc=com$") ~= nil) ) then

       return true

   end

   return false

end)()

 

 

 

 

 

 

 

 

 

In the example above, note the string.find function allows for a regular expression. We've used the $ at the end of the string to anchor this string to the end of the distinguishedName field.

 

Don't forget to escape special characters (   )   .   %   +   -   *   ?   [   ^   $ with the escape character % in your search string. For example "OU=Admins,dc=my-domain,dc=com$" should be escaped as "OU=Admins,dc=my%-domain,dc=com$".

 

2. Group Membership (memberOf) Example

A basic logical expression could similarly be created for pattern matching of AD group membership. Because users can be members of multiple groups, DAP will parse the response from the LDAP server into separate entries and hold them in a table. To accommodate this, a more advanced function is required to:

  • Compare the memberOf field as a string (in the event the user belongs to only one group)
  • Iterate through each returned memberOf field if the returned data is of type "table"

The function written and tested for this purpose is shown below. In this example, if a user is a member of any group ending with "-stu" they will match this DAP.

 

assert(function()

   local pattern = "-stu$"

   local attribute = aaa.ldap.memberOf

   if ((type(attribute) == "string") and

       (string.find(attribute, pattern) ~= nil)) then

       return true

   elseif (type(attribute) == "table") then

       local k, v

       for k, v in pairs(attribute) do

           if (string.find(v, pattern) ~= nil) then

               return true

           end

       end

   end

   return false

end)()

 

 

 

 

 

 

 

 

3. AntiVirus, AntiSpyware, Firewall Examples

The following LUA functions will check for any AV, AS, and FW package on the endpoint PC returned by CSD Host scan.

A. Check for Any AntiVirus

Below is an example of using a custom function to check if any anti-virus is detected by CSD.

Enter (copy/paste) the following function into the DAP record's Advanced box.

 

assert(function()

 

    for k,v in pairs(endpoint.av) do

 

         if (EVAL(v.exists, "EQ", "true", "string")) then

 

              return true

 

         end

 

    end

 

    return false

 

end)()

 

 

 

 

 

 

 

 

 

B. Check for Any AntiSpyware

Below is an example of using a custom function to check if any anti-spyware is detected by CSD.

Enter (copy/paste) the following function into the DAP record's Advanced box.

 

assert(function()

    for k,v in pairs(endpoint.as) do

         if (EVAL(v.exists, "EQ", "true", "string")) then

              return true

         end

    end

    return false

end)()

 

 

 

 

 

 

 

 

 

C. Check for Any firewall

Below is an example of using a custom function to check if any firewall is detected by CSD.

Enter (copy/paste) the following function into the DAP record's Advanced box.

 

assert(function()

    for k,v in pairs(endpoint.fw) do

         if (EVAL(v.exists, "EQ", "true", "string")) then

              return true

         end

    end

    return false

end)()

 

 

 

 

 

 

 

 

D. Check for Any AntiVirus, any AntiSpyware, or any firewall

The following function will return 'true' if an AntiVirus, AnitSpyware or a Firewall is found.

 

   assert(function()

 

       function check(antix)

 

           if (type(antix) == "table") then

 

               for k,v in pairs(antix) do

 

                   if (EVAL(v.exists, "EQ", "true", "string")) then

 

                       return true

 

                   end

 

               end

 

           end

 

           return false

 

       end

 

       return (check(endpoint.av) or check(endpoint.fw) or check(endpoint.as))

 

   end)()

 

 

 

 

 

 

 

 

 

E. Terminate if no Spyware is present

Note: The only difference here is the "not" if front of the assert

 

not assert(function()

   for k,v in pairs(endpoint.as) do

        if (EVAL(v.exists, "EQ", "true", "string")) then

             return true

        end

   end

   return false

end)()

 

 

 

 

 

 

 

 

F. CheckAndMsg with Custom Function

This function is intended to be used with a dap with action set to terminate. Upon terminate, it displays the following message

 

Login denied.

 

<AV Name> does not exists; last update is <X> days

 

 

 

 

 

 

 

 

 

 

(assert(function()                                                  

 

      local block_connection = true

 

      local update_threshold = "150000" --

this is the value of lastupdate in seconds                                   

 

      for k,v in pairs(endpoint.av) do                                

 

           if (CheckAndMsg(EVAL(v.exists, "EQ", "true", "string") and EVAL(v.lastupdate, "LT", update_threshhold, "integer"),                                  

 

                           k.." exists; last update is "..string.sub((tonumber(v.lastupdate)/86400), 1, 3).." days",                      

 

                           k.." does not exist; last update is "..string.sub((tonumber(v.lastupdate)/86400), 1, 3).." days")) then        

 

                block_connection = false                              

 

           end                                                        

 

      end                                                             

 

      return block_connection                                         

 

end)())

 

 

 

 

 

 

 

 

 

 

 

 


 

If you wish to have a DAP that checks for anti virus, anti virus last update, and notify the user for remediation; a modified version of the above can be used. Set the AAA attributes you wish to match on, and in the advanced field ensure the "AND" operation is selected. Also in the action field the "terminate" option is selected. What this means is if the user matches the AAA attributes AND the LUA function returns a value of "TRUE" the DAP will be selected. In this case it will display a message as to why the DAP record was displayed and terminate the users connection. If the LUA function does not return a value of true the DAP wont match, thereby permitting access. Then in the message box field enter in a message "No Anti Virus program found, please install AV and try again.". Also note that if the user has anti virus and is under the update days threshold they will not be given a message as indicated by the double quotes in line 7.

 

    (assert(function()

 

      local block_connection = true

 

      local update_days = "15" --days

 

      local av_lastupdate = update_days*86400

 

      for k,v in pairs(endpoint.as) do

 

              if (CheckAndMsg(EVAL(v.exists, "EQ", "true", "string") and EVAL(v.lastupdate, "LT", av_lastupdate, "integer"),

 

                       "",

 

                       k.." exists; but last update is greater than 15 days old.  Expecting under 15 days.")) then

 

                       block_connection = false

 

              elseif (EVAL(v.exists, "NE", "true", "string")) then

 

              block_connection = true

 

              end

 

        end

 

      return block_connection

 

      end)())

 

 

 

 

 

 

 

 

 


Thereby this function will display the following sample message if the user has Norton AV but the last update is greater than 15 days: "NortonAV exists; but last update is greater than 15 days old. Expecting under 15 days.

 

If the EVAL does not match, it goes on to the next function and will match returning a value of true. Since there is no CheckAndMsg associated with the second function it uses the DAP's message text which was filled in earlier: No Anti Virus program found, please install AV and try again.

 

So to reiterate how this function works is that the DAP is looking for a user AAA + Endpoint attribute to match in order to select this DAP. If the DAP matches, the user gets terminated with a message. The endpoint match is a result of a LUA eval that returns "true" or "false" to the DAP. If a "true" is returned it will match and deny the connection. A "false" will not match and permit the connection.

 

So the first function in the loop checks if the endpoint.av.xxxxx.exists is equal to true and the last update is less than the configured days. If the user does not have anti virus software at all they WILL be permitted into the system. This is because the fact that the users AAA will match but the LUA is looking specifically for (endpoint.av.xxxxx.exists = true ) AND ( endpoint.av.xxxxx.lastupdate <= days). So the second loop catches the user if they do not have AV installed and blocks them. Because the second function is looking for only (endpoint.av.xxxxx.exists NE true). This means if their "endpoint av exists" is not equal to true the function will return a value of true (meaning they don't have anti virus) thereby the DAP will match and deny the connection.

 

4. Regular Expression matching

This function uses regular expression matching to see if the hotfix list contains a pattern.

In the example below, Cisco Secure Desktop will return all hotfixes on the endpoint PC, and if we find an instance of KB944, the DAP policy will match and enforced.

 

In this case 2 instances of KB44 were found by CSD hostscan:

 

  endpoint.os.hotfix["KB944533"]="true";

  endpoint.os.hotfix["KB944653"]="true";

 

 

 

 

 

 

 

 

 

assert(function ()

 

local pattern = "KB944"

 

local true_on_match = true

 

local match = false

 

for k,v in pairs(endpoint.os.hotfix) do

 

   print(k)

 

   match = string.find(k, pattern)

 

   if (match) then

 

      if (true_on_match) then

 

         return true

 

      else

 

         return (false)

 

      end

 

   end

 

end

 

end)()

 

 

 

 

 

 

 

 

 


Note: A different version of this function would be required for a multi-valued checking. Stay tuned for that version!!!!

Regular Expression Notes

More information / validation is required for this section.

 

The following regex capabilities have been tested:

  • $ to anchor the search string to the end of the returned value
  • ^ to anchor the search string to the beginning of the returned value
  • [Aa] to match multiple characters in a specific position. To match OU=Cisco in a case insensitive way one would use OU=[Cc][Ii][Ss][Cc][Oo]
  • . will match any single character in this position.  Example: Group..Users might be used to match Group01Users, Group33Users etc.

 

5. DAP support for Windows 7 and CSD 3.5

 

Windows 7 platforms will be supported with CSD 3.5 (in Beta in late fall 2009).

An Advanced DAP LUA script is required until ASDM DAP GUI can include this capability in an ASDM 6.2.x  maintenance release and following major 6.3.x release.


On an ASA running version 8.x version and pre-beta CSD 3.5, enter the following LUA script string into the ASDM DAP Advanced box to perform checks for Windows 7 machines :

 

 

(EVAL(endpoint.os.version,"EQ","Windows 7","string"))

 

Update:The ASDM version 6.3.1 and above provide this capability in the GUI, so the Advanced LUA function is not required.

 

 

Further Information and References

Detailed LUA programming information can be found at http://www.lua.org/manual/5.1/manual.html.

 

 

ASA 8.x Dynamic Access Policies (DAP) Deployment Guide https://supportforums.cisco.com/docs/DOC-1369

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: