diff --git a/docs/sources/Schneider/index.md b/docs/sources/Schneider/index.md new file mode 100644 index 0000000..9b0f481 --- /dev/null +++ b/docs/sources/Schneider/index.md @@ -0,0 +1,48 @@ +# Vendor - Schneider + + +## Product - APC Power systems + + +| Ref | Link | +|----------------|---------------------------------------------------------------------------------------------------------| +| Splunk Add-on | none | +| Product Manual | multiple | + + +### Sourcetypes + +| sourcetype | notes | +|----------------|---------------------------------------------------------------------------------------------------------| +| apc:syslog | None | + +### Sourcetype and Index Configuration + +| key | sourcetype | index | notes | +|----------------|----------------|----------------|----------------| +| schneider_apc | apc:syslog | main | none | + +### Filter type + +Port or IP based filter is required + +### Setup and Configuration + + + +### Options + +| Variable | default | description | +|----------------|----------------|----------------| +| SC4S_SCHNEIDER_APC_TCP_PORT | empty string | Enable a TCP port for this specific vendor product using the number defined | +| SC4S_SCHNEIDER_APC_UDP_PORT | empty string | Enable a UDP port for this specific vendor product using the number defined | +| SC4S_ARCHIVE_SCHNEIDER_APC | no | Enable archive to disk for this specific source | +| SC4S_DEST_SCHNEIDER_APC_HEC | no | When Splunk HEC is disabled globally set to yes to enable this specific source | + +### Verification + +An active proxy will generate frequent events. Use the following search to validate events are present per source device + +``` +index= sourcetype=apc:syslog | stats count by host +``` diff --git a/mkdocs.yml b/mkdocs.yml index 2cc7387..501f490 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - "Palo Alto Networks": sources/PaloaltoNetworks/index.md - "pfSense": sources/PfSense/index.md - Proofpoint: sources/Proofpoint/index.md + - Schneider: sources/Schneider/index.md - Symantec: sources/Symantec/index.md - Ubiquiti: sources/Ubiquiti/index.md - VMware: sources/VMWare/index.md diff --git a/package/etc/conf.d/filters/schneider/apc.conf b/package/etc/conf.d/filters/schneider/apc.conf new file mode 100644 index 0000000..f51012e --- /dev/null +++ b/package/etc/conf.d/filters/schneider/apc.conf @@ -0,0 +1,4 @@ +filter f_schneider_apc { + match("^schneider_apc", value("fields.sc4s_vendor_product")); + +}; \ No newline at end of file diff --git a/package/etc/conf.d/log_paths/lp-schneider_apc.conf.tmpl b/package/etc/conf.d/log_paths/lp-schneider_apc.conf.tmpl new file mode 100644 index 0000000..97d28d0 --- /dev/null +++ b/package/etc/conf.d/log_paths/lp-schneider_apc.conf.tmpl @@ -0,0 +1,48 @@ +# SCHNEIDER_APC +{{- /* The following provides a unique port source configuration if env var(s) are set */}} +{{- $context := dict "port_id" "SCHNEIDER_APC" "parser" "rfc3164" }} +{{- tmpl.Exec "t/source_network.t" $context }} + +log { + junction { +{{- if or (or (getenv (print "SC4S_LISTEN_SCHNEIDER_APC_TCP_PORT")) (getenv (print "SC4S_LISTEN_SCHNEIDER_APC_UDP_PORT"))) (getenv (print "SC4S_LISTEN_SCHNEIDER_APC_TLS_PORT")) }} + channel { + # Listen on the specified dedicated port(s) for SCHNEIDER_APC traffic + source (s_SCHNEIDER_APC); + flags (final); + }; +{{- end}} + channel { + # Listen on the default port (typically 514) for SCHNEIDER_APC traffic + source (s_DEFAULT); + filter(f_is_rfc3164); + filter(f_schneider_apc); + flags(final); + }; + }; + rewrite { + set("schneider_apc", value("fields.sc4s_vendor_product")); + r_set_splunk_dest_default(sourcetype("apc:syslog"), index("main")) + }; + parser { p_add_context_splunk(key("schneider_apc")); }; + parser (compliance_meta_by_source); + rewrite { set("$(template ${.splunk.sc4s_template} $(template t_legacy_hdr_msg))" value("MSG")); }; + +{{- if or (conv.ToBool (getenv "SC4S_DEST_SPLUNK_HEC_GLOBAL" "yes")) (conv.ToBool (getenv "SC4S_DEST_SCHNEIDER_APC_HEC" "no")) }} + destination(d_hec); +{{- end}} + +{{- if or (conv.ToBool (getenv "SC4S_ARCHIVE_GLOBAL" "no")) (conv.ToBool (getenv "SC4S_ARCHIVE_SCHNEIDER_APC" "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_SCHNEIDER_APC_ALTERNATES")) }} + {{ getenv "SC4S_DEST_SCHNEIDER_APC_ALTERNATES" | regexp.ReplaceLiteral "^" "destination(" | regexp.ReplaceLiteral "[, ]+" ");\n destination(" }}); +{{- end }} + + flags(flow-control,final); +}; diff --git a/package/etc/context_templates/vendor_product_by_source.conf.example b/package/etc/context_templates/vendor_product_by_source.conf.example index 5280b72..ef4a974 100644 --- a/package/etc/context_templates/vendor_product_by_source.conf.example +++ b/package/etc/context_templates/vendor_product_by_source.conf.example @@ -50,6 +50,11 @@ filter f_proofpoint_pps_sendmail { host("pps-*" type(glob)) #or netmask(xxx.xxx.xxx.xxx/xx) }; + +filter f_schneider_apc { + host("test_apc-*" type(glob)) + #or netmask(xxx.xxx.xxx.xxx/xx) +}; filter f_ubiquiti_unifi_fw { host("usg-*" type(glob)) #or netmask(xxx.xxx.xxx.xxx/xx) diff --git a/package/etc/context_templates/vendor_product_by_source.csv.example b/package/etc/context_templates/vendor_product_by_source.csv.example index 9e5eaa3..aec9a34 100644 --- a/package/etc/context_templates/vendor_product_by_source.csv.example +++ b/package/etc/context_templates/vendor_product_by_source.csv.example @@ -11,6 +11,7 @@ f_cisco_nx_os,sc4s_vendor_product,"cisco_nx_os" f_pfsense,sc4s_vendor_product,"pfsense" f_proofpoint_pps_sendmail,sc4s_vendor_product,"proofpoint_pps_sendmail" f_proofpoint_pps_filter,sc4s_vendor_product,"proofpoint_pps_filter" +f_schneider_apc,sc4s_vendor_product,"schneider_apc" f_ubiquiti_unifi_fw,sc4s_vendor_product,"ubiquiti_unifi_fw" f_tzfixhst,sc4s_time_zone,"Pacific/Honolulu" f_tzfixny,sc4s_time_zone,"America/New_York" \ No newline at end of file diff --git a/tests/test_schneider_electric_apc.py b/tests/test_schneider_electric_apc.py new file mode 100644 index 0000000..73f9d48 --- /dev/null +++ b/tests/test_schneider_electric_apc.py @@ -0,0 +1,40 @@ +# 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() + +#<27>Mar 24 21:45:28 10.1.1.1 Detected an unauthorized user attempting to access the SNMP interface from 10.1.1.1 0x0004 +def test_apc(record_property, setup_wordlist, setup_splunk, setup_sc4s): + host = "test_apc-{}-{}".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 }} Detected an unauthorized user attempting to access the SNMP interface from 10.1.1.1 0x0004\n") + message = mt.render(mark="<27>", bsd=bsd, host=host) + sendsingle(message, setup_sc4s[0], setup_sc4s[1][514]) + + st = env.from_string("search _time={{ epoch }} index=main sourcetype=apc:syslog host=\"{{key}}\"") + search = st.render(epoch=epoch, key=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1