// Title: Aruba ClearPass Parser // Author: Microsoft // Version: 1.1 // Last Updated: 01/23/2020 // Comment: Added Supported for Version 6.6+ // // DESCRIPTION: // This parser takes raw Aruba ClearPass logs from a Syslog (CEF) stream and parses the logs into a normalized schema. // // USAGE: // 1. Open Log Analytics/Azure Sentinel Logs blade. Copy the query below and paste into the Logs query window. // 2. Click the Save button above the query. A pane will appear on the right, select "as Function" from the drop down. Enter a Function Name. // It is recommended to name the Function Alias, as ArubaClearPass // 3. Kusto Functions can typically take up to 15 minutes to activate. You can then use Function Alias for other queries. // // REFERENCES: // Using functions in Azure monitor log queries: https://docs.microsoft.com/azure/azure-monitor/log-query/functions // // LOG SAMPLES: // This parser assumes the raw log are formatted as follows: // // Dec 03 2017 16:31:28.861 IST 10.17.4.208 CEF:0|Aruba Networks|ClearPass|6.5.0.69058|0-1-0|Insight Logs|0|Auth.Username=host/Asif-Test-PC2 Auth.Authorization-Sources=null Auth.Login-Status=216 Auth.Request-Timestamp=2017-12-03 16:28:20+05:30 Auth.Protocol=RADIUS Auth.Source=null Auth.Enforcement-Profiles=[Allow Access Profile] Auth.NAS-Port=null Auth.SSID=cppm-dot1x-test TimestampFormat=MMM dd yyyy HH:mm:ss.SSS zzz Auth.NAS-Port-Type=19 Auth.Error-Code=216 Auth.Roles=null Auth.Service=Test Wireless Auth.Host-MAC-Address=6817294b0636 Auth.Unhealthy=null Auth.NAS-IP-Address=10.17.4.7 src=10.17.4.208 Auth.CalledStationId=000B8661CD70 Auth.NAS-Identifier=ClearPassLab3600 // // Nov 19 2017 18:22:40.700 IST 10.17.4.221 CEF:0|Aruba Networks|ClearPass|6.5.0.68754|13-1-0|Audit Records|5|cat=Role timeFormat=MMM dd yyyy HH:mm:ss.SSS zzz rt=Nov 19, 2014 18:21:13 IST src=Test Role 10 act=ADD usrName=admin // // Dec 01 2017 15:28:40.540 IST 10.17.4.206 CEF:0Aruba Networks|ClearPass|6.5.0.68878|1604-1-0|Session Logs|0|RADIUS.Acct-Calling-Station-Id=00:32:b6:2c:28:95 RADIUS.Acct-Framed-IP-Address=192.167.230.129 RADIUS.Auth-Source=AD:10.17.4.130 RADIUS.Acct-Timestamp=2014-12-01 15:26:43+05:30 RADIUS.Auth-Method=PAP RADIUS.Acct-Service-Name=Authenticate-Only RADIUS.Acct-Session-Time=3155 TimestampFormat=MMM dd yyyy HH:mm:ss.SSS zzz RADIUS.Acct-NAS-Port=0 RADIUS.Acct-Session-Id=R00001316-01-547c3b5a RADIUS.Acct-NAS-Port-Type=Wireless-802.11 RADIUS.Acct-Output-Octets=578470212 RADIUS.Acct-Username=A_user2 RADIUS.Acct-NAS-IP-Address=10.17.6.124 RADIUS.Acct-Input-Octets=786315664 // // <143>Aug 10 2016 15:18:04 172.20.21.100 CEF:0|Aruba Networks|ClearPass|6.6.1.84176|2006|Guest Access|1|duser=bob dmac=784b877a4155 dpriv=[User Authenticated] cs2=UNKNOWN cs2Label=System Posture Token outcome=[Allow Access Profile] rt=Aug 10 2016 15:16:51 dvc=172.20.21.100 cat=Session Logs // let LogHeader = CommonSecurityLog | where DeviceVendor == "Aruba Networks" and DeviceProduct == "ClearPass" | extend Category = coalesce( extract(@'cat=([^;]+)(\;|$)',1, AdditionalExtensions), column_ifexists("DeviceEventCategory", "") ), Outcome = coalesce( extract(@'outcome=([^;]+)\;',1, AdditionalExtensions), column_ifexists("EventOutcome", "") ) | project-rename DvcIpAddr = DeviceAddress, DvcVersion = DeviceVersion, SrcIpAddr = SourceIP; let InsightLogs = LogHeader | where Activity == "Insight Logs" or Category == "Insight Logs" // Version 6.5 | extend UserName = extract(@'Auth.Username=([^;]+)\;',1, AdditionalExtensions), AuthorizationSources = extract(@'Auth.Authorization-Sources=([^;]+)\;',1, AdditionalExtensions), NetworkProtocol = extract(@'Auth.Protocol=([^;]+)\;',1, AdditionalExtensions), RequestTimestamp = extract(@'Auth.Request-Timestamp=([^;]+)\;',1, AdditionalExtensions), LoginStatus = extract(@'Auth.Login-Status=([^;]+)\;',1, AdditionalExtensions), Source = extract(@'Auth.Source=([^;]+)\;',1, AdditionalExtensions), EnforcementProfiles = extract(@'Auth.Enforcement-Profiles=([^;]+)\;',1, AdditionalExtensions), NasPort = extract(@'Auth.NAS-Port=([^;]+)\;',1, AdditionalExtensions), TimestampFormat = extract(@'TimestampFormat=([^;]+)\;',1, AdditionalExtensions), Ssid = extract(@'Auth.SSID=([^;]+)\;',1, AdditionalExtensions), NasPortType = extract(@'Auth.NAS-Port-Type=([^;]+)\;',1, AdditionalExtensions), ErrorCode = extract(@'Auth.Error-Code=([^;]+)\;',1, AdditionalExtensions), Roles = extract(@'Auth.Roles=([^;]+)\;',1, AdditionalExtensions), Service = extract(@'Auth.Service=([^;]+)\;',1, AdditionalExtensions), SrcMacAddr = extract(@'Auth.Host-MAC-Address=([^;]+)\;',1, AdditionalExtensions), Unhealthy = extract(@'Auth.Unhealthy=([^;]+)\;',1, AdditionalExtensions), NasIpAddr = extract(@'Auth.NAS-IP-Address=([^;]+)\;',1, AdditionalExtensions), CalledStationId = extract(@'Auth.CalledStationId=([^;]+)\;',1, AdditionalExtensions), NasIdentifier = extract(@'Auth.NAS-Identifier=([^;]+)\;',1, AdditionalExtensions) // Version 6.6+ | extend EndpointStatus = extract(@'ArubaClearpassEndpointStatus=([^;]+)\;',1, AdditionalExtensions), EndpointConflict = extract(@'ArubaClearpassEndpointConflict=([^;]+)\;',1, AdditionalExtensions), EndpointDvcCategory = iif(DeviceCustomString3Label == "Endpoint.Device-Category", DeviceCustomString3, ""), EndpointDvcFamily = iif(DeviceCustomString4Label == "Endpoint.Device-Family", DeviceCustomString4, ""), EndpointDvcName = iif(DeviceCustomString5Label == "Endpoint.Device-Name", DeviceCustomString5, ""), EndpointMacVendor = iif(DeviceCustomString6Label == "Endpoint.MAC-Vendor", DeviceCustomString6, ""), EndpointAddedDate= iif(DeviceCustomDate1Label == "Endpoint.Added-At", todatetime(DeviceCustomDate1), todatetime("")) | extend Category = iif(isempty(Category), "Insight Logs", Category); let AuditRecords = LogHeader | where Activity == "Audit Records" or Category == "Audit Records" | extend TimestampFormat = extract(@'timeFormat=([^;]+)\;',1, AdditionalExtensions), UserName = extract(@'usrName=([^;]+)(\;|$)',1, AdditionalExtensions) | extend Category = iif(isempty(Category), "Audit Records", Category); let SessionLogs = LogHeader | where Activity == "Session Logs" or Category == "Session Logs" | extend Timestamp = extract(@'RADIUS.Acct-Timestamp=([^;]+)\;',1, AdditionalExtensions), CallingStationId = extract(@'RADIUS.Acct-Calling-Station-Id=([^;]+)\;',1, AdditionalExtensions), InputOctets = extract(@'RADIUS.Acct-Input-Octets=([^;]+)\;',1, AdditionalExtensions), TimestampFormat = extract(@'TimestampFormat=([^;]+)\;',1, AdditionalExtensions), SessionTime = extract(@'RADIUS.Acct-Session-Time=([^;]+)\;',1, AdditionalExtensions), FramedIpAddr = extract(@'RADIUS.Acct-Framed-IP-Address=([^;]+)\;',1, AdditionalExtensions), Source = extract(@'RADIUS.Auth-Source=([^;]+)\;',1, AdditionalExtensions), Method = extract(@'RADIUS.Auth-Method=([^;]+)\;',1, AdditionalExtensions), SessionId = extract(@'RADIUS.Acct-Session-Id=([^;]+)\;',1, AdditionalExtensions), ServiceName = extract(@'RADIUS.Acct-Service-Name=([^;]+)\;',1, AdditionalExtensions), NasPortNumber = extract(@'RADIUS.Acct-NAS-Port=([^;]+)\;',1, AdditionalExtensions), NasPortType = extract(@'RADIUS.Acct-NAS-Port-Type=([^;]+)\;',1, AdditionalExtensions), OutputOctets = extract(@'RADIUS.Acct-Output-Octets=([^;]+)\;',1, AdditionalExtensions), UserName = extract(@'RADIUS.Acct-Username=([^;]+)\;',1, AdditionalExtensions), NasIpAddr = extract(@'RADIUS.Acct-NAS-IP-Address=([^;]+)\;',1, AdditionalExtensions) | project-rename DstServiceName = DestinationServiceName, DstUserPriviledges = DestinationUserPrivileges, DstUserName = DestinationUserName, DstMacAddr = DestinationMACAddress | extend Category = iif(isempty(Category), "Sessions Logs", Category); let SystemLogs = LogHeader | where Activity == "System Logs" or Category == "ClearPass System Events" | extend Description = extract(@'description=([^;]+)\;',1, AdditionalExtensions), Action = extract(@'daction=([^;]+)\;',1, AdditionalExtensions), InputOctets = extract(@'RADIUS.Acct-Input-Octets=([^;]+)\;',1, AdditionalExtensions), TimeFormat = extract(@'devTimeFormat=([^;]+)\;',1, AdditionalExtensions) | extend Category = iif(isempty(Category), "System Logs", "System Logs"); union SessionLogs, InsightLogs, AuditRecords, SystemLogs