From 2702f07bd43fcb254ffb0372c35bb58f12e6d827 Mon Sep 17 00:00:00 2001 From: Ryan Faircloth <35384120+rfaircloth-splunk@users.noreply.github.com> Date: Wed, 26 Aug 2020 17:05:43 -0400 Subject: [PATCH] Support Cisco ACE legacy products (#661) --- docs/sources/Cisco/index.md | 47 ++++++++++++++++ package/etc/conf.d/filters/cisco/ace.conf | 8 +++ .../conf.d/log_paths/lp-cisco_ace.conf.tmpl | 53 +++++++++++++++++++ .../splunk_metadata.csv.example | 1 + tests/test_cisco_ace.py | 48 +++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 package/etc/conf.d/filters/cisco/ace.conf create mode 100644 package/etc/conf.d/log_paths/lp-cisco_ace.conf.tmpl create mode 100644 tests/test_cisco_ace.py diff --git a/docs/sources/Cisco/index.md b/docs/sources/Cisco/index.md index df106a3..49f17b0 100644 --- a/docs/sources/Cisco/index.md +++ b/docs/sources/Cisco/index.md @@ -174,6 +174,53 @@ index= sourcetype=cisco:asa Verify timestamp, and host values match as expected +## Product - Application Control Engine + + + + +| Ref | Link | +|----------------|---------------------------------------------------------------------------------------------------------| +| Splunk Add-on | None | + +### Sourcetypes + +| sourcetype | notes | +|----------------|---------------------------------------------------------------------------------------------------------| +| cisco:ace | This source type is also used for ACE | + +### Sourcetype and Index Configuration + +| key | sourcetype | index | notes | +|----------------|----------------|----------------|----------------| +| cisco_ace | cisco:ace | netops | none | + +### Filter type + +* Cisco ACE products can be identified by message parsing alone + + +### Setup and Configuration + +Unknown this product is unsupported by Cisco + +### Options + +| Variable | default | description | +|----------------|----------------|----------------| +| SC4S_LISTEN_CISCO_ACE_UDP_PORT | empty string | Enable a TCP port for this specific vendor product using a comma-separated list of port numbers | +| SC4S_LISTEN_CISCO_ACE_TCP_PORT | empty string | Enable a UDP port for this specific vendor product using a comma-separated list of port numbers | +| SC4S_ARCHIVE_CISCO_ACE | no | Enable archive to disk for this specific source | +| SC4S_DEST_CISCO_ACE_HEC | no | When Splunk HEC is disabled globally set to yes to enable this specific source | + +### Verification + +Use the following search to validate events are present + +``` +index= sourcetype=cisco:ace | stats count by host +``` + ## Product - Cisco Networking Cisco Network Products of multiple types share common logging characteristics the following types are known to be compatible: diff --git a/package/etc/conf.d/filters/cisco/ace.conf b/package/etc/conf.d/filters/cisco/ace.conf new file mode 100644 index 0000000..3fe8b6b --- /dev/null +++ b/package/etc/conf.d/filters/cisco/ace.conf @@ -0,0 +1,8 @@ +filter f_cisco_ace { + message('^%ACE-\d+-\d{1,10}: ') or + match('^%ACE-\d+-\d{1,10}:', value("LEGACY_MSGHDR")); +}; + +filter f_cisco_ace_nohost { + match('^%ACE-\d+-\d{1,10}:', value("LEGACY_MSGHDR")); +}; diff --git a/package/etc/conf.d/log_paths/lp-cisco_ace.conf.tmpl b/package/etc/conf.d/log_paths/lp-cisco_ace.conf.tmpl new file mode 100644 index 0000000..e61f54c --- /dev/null +++ b/package/etc/conf.d/log_paths/lp-cisco_ace.conf.tmpl @@ -0,0 +1,53 @@ +# Cisco ACE +{{- /* The following provides a unique port source configuration if env var(s) are set */}} +{{- $context := dict "port_id" "CISCO_ACE" "parser" "common" }} +{{- tmpl.Exec "t/source_network.t" $context }} + +log { + junction { +{{- if or (or (getenv (print "SC4S_LISTEN_CISCO_ACE_TCP_PORT")) (getenv (print "SC4S_LISTEN_CISCO_ACE_UDP_PORT"))) (getenv (print "SC4S_LISTEN_CISCO_ACE_TLS_PORT")) }} + channel { + # Listen on the specified dedicated port(s) for CISCO_ACE traffic + source (s_CISCO_ACE); + flags (final); + }; +{{- end}} + channel { + # Listen on the default port (typically 514) for CISCO_ACE traffic + source (s_DEFAULT); + filter(f_cisco_ace); + flags(final); + }; + }; + + rewrite { + set("cisco_ace", value("fields.sc4s_vendor_product")); + r_set_splunk_dest_default(sourcetype("cisco:ace")) + }; + parser {p_add_context_splunk(key("cisco_ace")); }; + parser (compliance_meta_by_source); + + if (filter (f_cisco_ace_nohost)) { + rewrite { set("$(template ${.splunk.sc4s_template} $(template t_legacy_hdr_msg))" value("MSG")); }; + } else { + rewrite { set("$(template ${.splunk.sc4s_template} $(template t_msg_only))" value("MSG")); }; + }; + +{{- if or (conv.ToBool (getenv "SC4S_DEST_SPLUNK_HEC_GLOBAL" "yes")) (conv.ToBool (getenv "SC4S_DEST_CISCO_ACE_HEC" "no")) }} + destination(d_hec); +{{- end}} + +{{- if or (conv.ToBool (getenv "SC4S_ARCHIVE_GLOBAL" "no")) (conv.ToBool (getenv "SC4S_ARCHIVE_CISCO_ACE" "no")) }} + destination(d_archive); +{{- end}} + +{{- if (print (getenv "SC4S_DEST_GLOBAL_ALTERNATES")) }} + {{ getenv "SC4S_DEST_GLOBAL_ALTERNATES" | regexp.ReplaceLiteral "^" "destination(" | regexp.ReplaceLiteral "[, ]+" ");\n destination(" }}); +{{- end }} + +{{- if (print (getenv "SC4S_DEST_CISCO_ACE_ALTERNATES")) }} + {{ getenv "SC4S_DEST_CISCO_ACE_ALTERNATES" | regexp.ReplaceLiteral "^" "destination(" | regexp.ReplaceLiteral "[, ]+" ");\n destination(" }}); +{{- end }} + + flags(flow-control,final); +}; diff --git a/package/etc/context_templates/splunk_metadata.csv.example b/package/etc/context_templates/splunk_metadata.csv.example index 0253251..1c15d75 100644 --- a/package/etc/context_templates/splunk_metadata.csv.example +++ b/package/etc/context_templates/splunk_metadata.csv.example @@ -17,6 +17,7 @@ checkpoint_splunk,index,netops cisco_acs,index,netauth cisco_apic_acl,index,netfw cisco_apic_events,index,netops +cisco_ace,index,netops cisco_asa,index,netfw Cisco_C100V Email Security Virtual Appliance_ESA_CONSOLIDATED_LOG_EVENT,index,email Cisco_C100V Email Security Virtual Appliance_ESA_CONSOLIDATED_LOG_EVENT,sc4s_template,t_legacy_hdr_msg diff --git a/tests/test_cisco_ace.py b/tests/test_cisco_ace.py new file mode 100644 index 0000000..3d672d5 --- /dev/null +++ b/tests/test_cisco_ace.py @@ -0,0 +1,48 @@ +# Copyright 2019 Splunk, Inc. +# +# Use of this source code is governed by a BSD-2-clause-style +# license that can be found in the LICENSE-BSD2 file or at +# https://opensource.org/licenses/BSD-2-Clause +import random + +from jinja2 import Environment + +from .sendmessage import * +from .splunkutils import * +from .timeutils import * + +env = Environment() + + +# Apr 15 2017 00:21:14 192.168.12.1: %ACE-3-251010: Health probe failed for server X.X.X.X on port 8000, server reply timeout' +def test_cisco_ace_traditional( + record_property, setup_wordlist, setup_splunk, setup_sc4s +): + host = "{}-{}".format(random.choice(setup_wordlist), random.choice(setup_wordlist)) + + dt = datetime.datetime.now() + iso, bsd, time, date, tzoffset, tzname, epoch = time_operations(dt) + + # Tune time functions + epoch = epoch[:-7] + + mt = env.from_string( + "{{ mark }} {{ bsd }} {{ host }}: %ACE-3-251010: Health probe failed for server X.X.X.X on port 8000, server reply timeout\n" + ) + message = mt.render(mark="<111>", bsd=bsd, host=host) + + sendsingle(message, setup_sc4s[0], setup_sc4s[1][514]) + + st = env.from_string( + 'search _time={{ epoch }} index=netops host="{{ host }}" sourcetype="cisco:ace"' + ) + search = st.render(epoch=epoch, host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 +