From 9dc6c3c18242fd886aafa9ab89d7fd05b6566f27 Mon Sep 17 00:00:00 2001 From: Ryan Faircloth <35384120+rfaircloth-splunk@users.noreply.github.com> Date: Mon, 17 Aug 2020 19:03:41 -0400 Subject: [PATCH] [filtermod] Cisco ACS (#642) * [filtermod] Cisco ACS * Prefix parsers and templates * Apply appropriate `t-` and `p-` prefix to templates and parsers Co-authored-by: mbonsack --- docs/sources/Cisco/index.md | 9 ++++++- .../conf.d/log_paths/lp-cisco_acs.conf.tmpl | 25 +++++++++++++------ tests/test_cisco_acs.py | 4 +-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/docs/sources/Cisco/index.md b/docs/sources/Cisco/index.md index 1222800..9aaf4bf 100644 --- a/docs/sources/Cisco/index.md +++ b/docs/sources/Cisco/index.md @@ -27,7 +27,14 @@ PATTERN MATCH ### Setup and Configuration -* No special steps required +* Replace the following extract using Splunk local configuration. Impacts version 1.5.0 of the addond + +``` +EXTRACT-AA-signature = CSCOacs_(?\S+):? +# Note the value of this config is empty to disable +EXTRACT-AA-syslog_message = +EXTRACT-acs_message_header2 = ^CSCOacs_\S+\s+(?\S+)\s+(?\d+)\s+(?\d+)\s+(?.*) +``` ### Options diff --git a/package/etc/conf.d/log_paths/lp-cisco_acs.conf.tmpl b/package/etc/conf.d/log_paths/lp-cisco_acs.conf.tmpl index eb3ca7b..d68f7df 100644 --- a/package/etc/conf.d/log_paths/lp-cisco_acs.conf.tmpl +++ b/package/etc/conf.d/log_paths/lp-cisco_acs.conf.tmpl @@ -13,7 +13,7 @@ filter f_cisco_acs_complete{ #This grabs the sequence numbers from the event; message gets group-parsed #if the total number of events (ACS.seq) is greater than 1 -parser acs_get_sequence { +parser p_acs_get_sequence { csv-parser( columns(PID, ACS.num, ACS.seq, MESSAGE) delimiters(chars(" ")) @@ -23,7 +23,7 @@ parser acs_get_sequence { #This parser adds messages from ACS to a context without sending them on to Splunk -parser acs_grouping { +parser p_acs_grouping { grouping-by( scope(program) key("$PID") @@ -31,6 +31,11 @@ parser acs_grouping { sort-key("${ACS.seq}") aggregate( value("MESSAGE" "$(implode '' $(context-values ${MESSAGE}))") + value("PID" "${PID}@1") + value("PROGRAM" "${PROGRAM}@1") + value("ACS.DATE" "${ACS.DATE}@1") + value("ACS.TIME" "${ACS.TIME}@1") + value("ACS.TZ" "${ACS.TZ}@1") value("ACS.COMPLETE" "yes") ) timeout(30) @@ -40,7 +45,7 @@ parser acs_grouping { #The syslog message includes a date with milliseconds and TZ which is not in the header #So must reparse the date -parser acs_event_time { +parser p_acs_event_time { csv-parser( columns(ACS.DATE, ACS.TIME, ACS.TZ, MESSAGE) delimiters(chars(" ")) @@ -54,6 +59,10 @@ parser acs_event_time { ); }; +template t_acs_message { + template("${PROGRAM} ${PID} 1 0 ${ACS.DATE} ${ACS.TIME} ${ACS.TZ} ${MESSAGE}"); +}; + log { junction { {{- if or (or (getenv (print "SC4S_LISTEN_CISCO_ACS_TCP_PORT")) (getenv (print "SC4S_LISTEN_CISCO_ACS_UDP_PORT"))) (getenv (print "SC4S_LISTEN_CISCO_ACS_TLS_PORT")) }} @@ -73,17 +82,17 @@ log { }; # Do not run the events through the group parser if there is only one event - parser(acs_get_sequence); + parser(p_acs_get_sequence); if (match("1" value("ACS.num"))) { rewrite { set("yes" value("ACS.COMPLETE")); }; } else { - parser(acs_grouping); + parser(p_acs_grouping); }; if { filter(f_cisco_acs_complete); - parser(acs_event_time); + parser(p_acs_event_time); rewrite { set("cisco_acs", value("fields.sc4s_vendor_product")); r_set_splunk_dest_default(sourcetype("cisco:acs")) @@ -91,7 +100,7 @@ log { parser {p_add_context_splunk(key("cisco_acs")); }; parser (compliance_meta_by_source); - rewrite { set("$(template ${.splunk.sc4s_template} $(template t_msg_only))" value("MSG")); }; + rewrite { set("$(template ${.splunk.sc4s_template} $(template t_acs_message))" value("MSG")); }; {{- if or (conv.ToBool (getenv "SC4S_DEST_SPLUNK_HEC_GLOBAL" "yes")) (conv.ToBool (getenv "SC4S_DEST_CISCO_ACS_HEC" "no")) }} destination(d_hec); @@ -104,4 +113,4 @@ log { flags(flow-control,final); }; -}; \ No newline at end of file +}; diff --git a/tests/test_cisco_acs.py b/tests/test_cisco_acs.py index 5ec5b6e..de00935 100644 --- a/tests/test_cisco_acs.py +++ b/tests/test_cisco_acs.py @@ -26,7 +26,7 @@ def test_cisco_acs_single(record_property, setup_wordlist, setup_splunk, setup_s epoch = epoch[:-3] mt = env.from_string( - "{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications 0765855540 1 0 {{ date }} {{ time }} {{ tzoffset }} 0178632943 5202 NOTICE Device-Administration: Command Authorization succeeded, ACSVersion=acs-5.8.1.4-B.462.x86_64, ConfigVersionId=16489, Device IP Address=10.0.0.93, DestinationIPAddress=10.0.0.10, DestinationPort=49, UserName=nsdevman, CmdSet=[ CmdAV=show CmdArgAV=vpn-sessiondb CmdArgAV=full CmdArgAV=ra-ikev2-ipsec ], Protocol=Tacacs, MatchedCommandSet=fw3, RequestLatency=11, Type=Authorization, Privilege-Level=15, Authen-Type=ASCII, Service=None, User=nsdevman, Port=443, Remote-Address=10.0.0.15, Authen-Method=TacacsPlus, Service-Argument=shell, AcsSessionID=mnsvdcfpiuac03/359448835/9871764, AuthenticationIdentityStore=AD1, AuthenticationMethod=Lookup, SelectedAccessService=Default Device Admin, SelectedCommandSet=fw3, IdentityGroup=IdentityGroup:All Groups:SystemID, Step=13005 , Step=15008 , Step=15004 , Step=15012 , Step=15041 , Step=15004 , Step=15013 , Step=24210 , Step=24212 , Step=24432 , Step=24325 , Step=24313 , Step=24319 , Step=24323 , Step=24420 , Step=24355 , Step=24416 , Step=22037 , Step=15044 , Step=15035 , Step=15042 , Step=15036 , Step=15004 , Step=15018 , Step=13024 , Step=13034 , SelectedAuthenticationIdentityStores=Internal Users, NetworkDeviceName=devicenamehere, NetworkDeviceGroups=Device Type:All Device Types:Firewall:Cisco Systems:Firewall:ASA5545, NetworkDeviceGroups=Location:All Locations:MN, ServiceSelectionMatchedRule=TACACS, IdentityPolicyMatchedRule=Firewall, AuthorizationPolicyMatchedRule=nsdevman, AD-User-Candidate-Identities=nsdevman@ent.example.corp, AD-User-DNS-Domain=ent.example.corp, AD-User-NetBios-Name=AD-ENT, AD-User-Resolved-Identities=nsdevman@ent.example.corp, AD-User-Join-Point=ENT.example.CORP, AD-User-Resolved-DNs=CN=nsdevman\,OU=Service Accounts\,OU=CAO\,OU=ENT\,DC=ent\,DC=wfb\,DC=example\,DC=corp, StepData=10=nsdevman, StepData=11=ent.example.corp, StepData=12=example.corp, StepData=15=ent.example.corp, AD-Domain=ent.example.corp, IdentityAccessRestricted=false, UserIdentityGroup=IdentityGroup:All Groups:SystemID, Cisco-Firewall=Superuser, Firewall=Superuser, NetSec-CSM=User, NetSec-Logging=Engineer, Response={Type=Authorization; Author-Reply-Status=PassAdd; ExternalIdentityStoreName=AD1; }\n" + "{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications: 0765855540 1 0 {{ date }} {{ time }} {{ tzoffset }} 0178632943 5202 NOTICE Device-Administration: Command Authorization succeeded, ACSVersion=acs-5.8.1.4-B.462.x86_64, ConfigVersionId=16489, Device IP Address=10.0.0.93, DestinationIPAddress=10.0.0.10, DestinationPort=49, UserName=nsdevman, CmdSet=[ CmdAV=show CmdArgAV=vpn-sessiondb CmdArgAV=full CmdArgAV=ra-ikev2-ipsec ], Protocol=Tacacs, MatchedCommandSet=fw3, RequestLatency=11, Type=Authorization, Privilege-Level=15, Authen-Type=ASCII, Service=None, User=nsdevman, Port=443, Remote-Address=10.0.0.15, Authen-Method=TacacsPlus, Service-Argument=shell, AcsSessionID=mnsvdcfpiuac03/359448835/9871764, AuthenticationIdentityStore=AD1, AuthenticationMethod=Lookup, SelectedAccessService=Default Device Admin, SelectedCommandSet=fw3, IdentityGroup=IdentityGroup:All Groups:SystemID, Step=13005 , Step=15008 , Step=15004 , Step=15012 , Step=15041 , Step=15004 , Step=15013 , Step=24210 , Step=24212 , Step=24432 , Step=24325 , Step=24313 , Step=24319 , Step=24323 , Step=24420 , Step=24355 , Step=24416 , Step=22037 , Step=15044 , Step=15035 , Step=15042 , Step=15036 , Step=15004 , Step=15018 , Step=13024 , Step=13034 , SelectedAuthenticationIdentityStores=Internal Users, NetworkDeviceName=devicenamehere, NetworkDeviceGroups=Device Type:All Device Types:Firewall:Cisco Systems:Firewall:ASA5545, NetworkDeviceGroups=Location:All Locations:MN, ServiceSelectionMatchedRule=TACACS, IdentityPolicyMatchedRule=Firewall, AuthorizationPolicyMatchedRule=nsdevman, AD-User-Candidate-Identities=nsdevman@ent.example.corp, AD-User-DNS-Domain=ent.example.corp, AD-User-NetBios-Name=AD-ENT, AD-User-Resolved-Identities=nsdevman@ent.example.corp, AD-User-Join-Point=ENT.example.CORP, AD-User-Resolved-DNs=CN=nsdevman\,OU=Service Accounts\,OU=CAO\,OU=ENT\,DC=ent\,DC=wfb\,DC=example\,DC=corp, StepData=10=nsdevman, StepData=11=ent.example.corp, StepData=12=example.corp, StepData=15=ent.example.corp, AD-Domain=ent.example.corp, IdentityAccessRestricted=false, UserIdentityGroup=IdentityGroup:All Groups:SystemID, Cisco-Firewall=Superuser, Firewall=Superuser, NetSec-CSM=User, NetSec-Logging=Engineer, Response={Type=Authorization; Author-Reply-Status=PassAdd; ExternalIdentityStoreName=AD1; }\n" ) message = mt.render( mark="<165>", bsd=bsd, host=host, date=date, time=time, tzoffset=tzoffset @@ -60,7 +60,7 @@ def test_cisco_acs_multi(record_property, setup_wordlist, setup_splunk, setup_sc epoch = epoch[:-3] mt = env.from_string( - "{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications 0000000002 2 0 {{ date }} {{ time }} {{ tzoffset }} 0000008450 5203 NOTICE Device-Administration: Session Authorization succeeded, ACSVersion=acs-5.2.0.26-B.3075, ConfigVersionId=117, Device IP Address=192.168.26.137, UserName=edward, CmdSet=[ CmdAV= ], Protocol=Tacacs, RequestLatency=10, NetworkDeviceName=switch, Type=Authorization, Privilege-Level=1, Authen-Type=ASCII, Service=Login, User=edward, Port=tty2, Remote-Address=10.78.167.190, Authen-Method=TacacsPlus, Service-Argument=shell, AcsSessionID=ACS41/101085887/112, AuthenticationIdentityStore=Internal Users, AuthenticationMethod=Lookup, SelectedAccessService=Default Device Admin, SelectedShellProfile=Permit Access, IdentityGroup=IdentityGroup:All Groups, Step=13005 , Step=15008 , Step=15004 , Step=15012 , Step=15041 , Step=15006 , Step=15013 , Step=24210 , Step=24212 , Step=22037 , Step=15044 , Step=15035 , Step=15042 , Step=15036 , Step=15004 , Step=15017 , Step=13034 , \n{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications 0000000002 2 1 Step=13015 , SelectedAuthenticationIdentityStores=Internal Users, NetworkDeviceGroups=s1Migrated_NDGs:All s1Migrated_NDGs, NetworkDeviceGroups=Device Type:All Device Types, NetworkDeviceGroups=Location:All Locations, ServiceSelectionMatchedRule=Rule-2, IdentityPolicyMatchedRule=Default, AuthorizationPolicyMatchedRule=Rule-0, Action=Login, Privilege-Level=1, Authen-Type=ASCII, Service=Login, Remote-Address=10.78.167.190, UserIdentityGroup=IdentityGroup:All\n" + "{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications: 0000000002 2 0 {{ date }} {{ time }} {{ tzoffset }} 0000008450 5203 NOTICE Device-Administration: Session Authorization succeeded, ACSVersion=acs-5.2.0.26-B.3075, ConfigVersionId=117, Device IP Address=192.168.26.137, UserName=edward, CmdSet=[ CmdAV= ], Protocol=Tacacs, RequestLatency=10, NetworkDeviceName=switch, Type=Authorization, Privilege-Level=1, Authen-Type=ASCII, Service=Login, User=edward, Port=tty2, Remote-Address=10.78.167.190, Authen-Method=TacacsPlus, Service-Argument=shell, AcsSessionID=ACS41/101085887/112, AuthenticationIdentityStore=Internal Users, AuthenticationMethod=Lookup, SelectedAccessService=Default Device Admin, SelectedShellProfile=Permit Access, IdentityGroup=IdentityGroup:All Groups, Step=13005 , Step=15008 , Step=15004 , Step=15012 , Step=15041 , Step=15006 , Step=15013 , Step=24210 , Step=24212 , Step=22037 , Step=15044 , Step=15035 , Step=15042 , Step=15036 , Step=15004 , Step=15017 , Step=13034 , \n{{ mark }} {{ bsd }} {{ host }} CSCOacs_Passed_Authentications 0000000002 2 1 Step=13015 , SelectedAuthenticationIdentityStores=Internal Users, NetworkDeviceGroups=s1Migrated_NDGs:All s1Migrated_NDGs, NetworkDeviceGroups=Device Type:All Device Types, NetworkDeviceGroups=Location:All Locations, ServiceSelectionMatchedRule=Rule-2, IdentityPolicyMatchedRule=Default, AuthorizationPolicyMatchedRule=Rule-0, Action=Login, Privilege-Level=1, Authen-Type=ASCII, Service=Login, Remote-Address=10.78.167.190, UserIdentityGroup=IdentityGroup:All\n" ) message = mt.render( mark="<165>", bsd=bsd, host=host, date=date, time=time, tzoffset=tzoffset