diff --git a/docs/sources/vendor/Cisco/cisco_meraki.md b/docs/sources/vendor/Cisco/cisco_meraki.md index f34f843461..5968fb1924 100644 --- a/docs/sources/vendor/Cisco/cisco_meraki.md +++ b/docs/sources/vendor/Cisco/cisco_meraki.md @@ -1,65 +1,96 @@ ## Meraki (MR, MS, MX) ## Key facts -* In most cases, Cisco Meraki logs are general and require vendor product by source configuration. -* For distinctive log messages, filters are based on the appliance name and program value. +* Cisco Meraki messages are not distinctive, which means that it's impossible to parse the sourcetype based on the log message. +* Because of the above you should either configure known Cisco Meraki hosts in SC4S, or open unique ports for Cisco Meraki devices. +* [Splunk Add-on for Cisco Meraki 2.1.0](https://splunkbase.splunk.com/app/5580) doesn't support syslog. Use [TA-meraki](https://splunkbase.splunk.com/app/3018) instead. `TA-meraki 1.1.5` requires sourcetype `meraki`. -## Distinctive log messages -See samples in the [vendor documentation](https://documentation.meraki.com/General_Administration/Monitoring_and_Reporting/Syslog_Event_Types_and_Log_Samples). - -The two conjuncted conditions are required: - -1. Program: `(events|urls|firewall|cellular_firewall|vpn_firewall|ids-alerts|flows)` - -2. Appliance name: - -| Sourcetype | Distinct element | -| --------- | -------------- | -| meraki:accesspoints | `host('MR' type(string) flags(ignore-case,prefix))` | -| meraki:securityappliances | `host('MX' type(string) flags(ignore-case,prefix))` | -| meraki:switches | `host('MS' type(string) flags(ignore-case,prefix))` | - ## Links - | Ref | Link | |----------------|---------------------------------------------------------------------------------------------------------| -| Splunk Add-on | | -| Product Manual | | +| Splunk Add-on | | +| Product Manual | | ## Sourcetypes | sourcetype | notes | |----------------|---------------------------------------------------------------------------------------------------------| -| meraki:accesspoints | MR | -| meraki:securityappliances | MX | -| meraki:switches | MS | -| meraki | vendor product by source configuration | +| meraki:accesspoints | Not compliant with the Splunk Add-on | +| meraki:securityappliances | Not compliant with the Splunk Add-on | +| meraki:switches | Not compliant with the Splunk Add-on | +| meraki | For all Meraki devices. Compliant with the Splunk Add-on | -## Sourcetype and Index Configuration +## Index Configuration | key | sourcetype | index | notes | |----------------|----------------|----------------|----------------| -| cisco_meraki_accesspoints | meraki:accesspoints | netfw | Filtered on the message format | -| cisco_meraki_securityappliances | meraki:securityappliances | netfw | Filtered on the message format | -| cisco_meraki_switches | meraki:switches | netfw | Filtered on the message format | -| cisco_meraki | meraki | netfw | Filtered on vendor product by source configuration | +| meraki_accesspoints | meraki:accesspoints | netfw | | +| meraki_securityappliances | meraki:securityappliances | netfw | | +| meraki_switches | meraki:switches | netfw | | +| cisco_meraki | meraki | netfw | | -## Parser Configuration +## Parser Configuration +1. Either by defining Cisco Meraki hosts: ```c -#/opt/sc4s/local/config/app-parsers/app-vps-cisco_meraki.conf +#/opt/sc4s/local/config/app_parsers/app-vps-cisco_meraki.conf #File name provided is a suggestion it must be globally unique -application app-vps-test-cisco_meraki[sc4s-vps] { - filter { - host("^testcm-") +block parser app-vps-test-cisco_meraki() { + channel { + if { + filter { host("^test-mx-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('securityappliances') + ); + }; + } elif { + filter { host("^test-mr-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('accesspoints') + ); + }; + } elif { + filter { host("^test-ms-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('switches') + ); + }; + } else { + parser { + p_set_netsource_fields( + vendor('cisco') + product('meraki') + ); + }; + }; }; - parser { - p_set_netsource_fields( - vendor('cisco') - product('meraki') - ); - }; }; + + +application app-vps-test-cisco_meraki[sc4s-vps] { + filter { + host("^test-meraki-") + or host("^test-mx-") + or host("^test-mr-") + or host("^test-ms-") + }; + parser { app-vps-test-cisco_meraki(); }; +}; +``` + +2. Or by a unique port: ``` +# /opt/sc4s/env_file +SC4S_LISTEN_CISCO_MERAKI_UDP_PORT=5004 +SC4S_LISTEN_MERAKI_SECURITYAPPLIANCES_UDP_PORT=5005 +SC4S_LISTEN_MERAKI_ACCESSPOINTS_UDP_PORT=5006 +SC4S_LISTEN_MERAKI_SWITCHES_UDP_PORT=5007 +``` \ No newline at end of file diff --git a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-cisco_meraki.conf b/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-cisco_meraki.conf deleted file mode 100644 index 69ee78f9e8..0000000000 --- a/package/etc/conf.d/conflib/almost-syslog/app-almost-syslog-cisco_meraki.conf +++ /dev/null @@ -1,28 +0,0 @@ -rewrite set_rfc3164_cisco_meraki{ - set-tag("wireformat:rfc3164_cisco_meraki"); -}; - -block parser app-almost-syslog-cisco_meraki() { - channel { - parser { - regexp-parser( - prefix(".tmp.") - patterns('^(?\<\d+\>) ?(?[A-Z][a-z]{2} *\d{1,2} \d\d:\d\d:\d\d) (?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (?\d) (?\d{10}\.\d{9}) (?.*)') - ); - date-parser( - format('%s.%f', '%s') - template("${.tmp.ts2}") - ); - syslog-parser( - flags(assume-utf8, guess-timezone) - template("${.tmp.pri} $S_ISODATE ${.tmp.message}") - ); - }; - rewrite(set_rfc); - rewrite(set_rfc3164); - rewrite(set_rfc3164_cisco_meraki); - }; -}; -application app-almost-syslog-cisco_meraki[sc4s-almost-syslog] { - parser { app-almost-syslog-cisco_meraki(); }; -}; diff --git a/package/etc/conf.d/conflib/netsource/app-netsource-cisco_meraki.conf b/package/etc/conf.d/conflib/netsource/app-netsource-cisco_meraki.conf index 579cfc295d..6d54b000d5 100644 --- a/package/etc/conf.d/conflib/netsource/app-netsource-cisco_meraki.conf +++ b/package/etc/conf.d/conflib/netsource/app-netsource-cisco_meraki.conf @@ -1,31 +1,88 @@ -block parser app-netsource-cisco_meraki() { - channel { - rewrite { - r_set_splunk_dest_default( - index('netfw') - sourcetype('meraki') - vendor('cisco') - product('meraki') - ); +block filter f_cisco_meraki(vendor() product()) { + ( + match(`vendor`, value('.netsource.sc4s_vendor'), type(string)) + and match(`product`, value('.netsource.sc4s_product'), type(string)) + ) + or (tags('ns_vendor:`vendor`') and tags('ns_product:`product`')) + or tags('`vendor`_`product`') + or "${.netsource.sc4s_vendor_product}" eq '`vendor`_`product`' +}; +block parser app-netsource-cisco_meraki() { + channel { + if { + filter { + f_cisco_meraki( + vendor('cisco') + product('meraki') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki') + vendor('cisco') + product('meraki') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('securityappliances') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:securityappliances') + vendor('meraki') + product('securityappliances') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('accesspoints') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:accesspoints') + vendor('meraki') + product('accesspoints') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('switches') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:switches') + vendor('meraki') + product('switches') + ); + }; }; - - - }; + }; }; + application app-netsource-cisco_meraki[sc4s-network-source] { filter { not filter(f_is_source_identified) and ( - ( - match("cisco", value('.netsource.sc4s_vendor'), type(string)) - and match("meraki", value('.netsource.sc4s_product'), type(string)) - ) - or (tags("ns_vendor:cisco") and tags("ns_product:meraki")) - or tags(".source.s_CISCO_MERAKI") - or "${.netsource.sc4s_vendor_product}" eq "cisco_meraki" - ) - ; - }; - parser { app-netsource-cisco_meraki(); }; -}; + f_cisco_meraki(vendor('cisco') product('meraki')) + or f_cisco_meraki(vendor('meraki') product('securityappliances')) + or f_cisco_meraki(vendor('meraki') product('accesspoints')) + or f_cisco_meraki(vendor('meraki') product('switches')) + ) + }; + parser { app-netsource-cisco_meraki(); }; +}; \ No newline at end of file diff --git a/package/etc/conf.d/conflib/syslog/app-syslog-cisco_meraki.conf b/package/etc/conf.d/conflib/syslog/app-syslog-cisco_meraki.conf deleted file mode 100644 index 73e1d7dff6..0000000000 --- a/package/etc/conf.d/conflib/syslog/app-syslog-cisco_meraki.conf +++ /dev/null @@ -1,45 +0,0 @@ -block parser app-syslog-cisco_meraki() { - channel { - - rewrite { - set("securityappliances", value(".tmp.device") condition( host('MX' type(string) flags(ignore-case,prefix)))); - set("switches", value(".tmp.device") condition( host('MS' type(string) flags(ignore-case,prefix)))); - set("accesspoints", value(".tmp.device") condition( host('MR' type(string) flags(ignore-case,prefix)))); - }; - - rewrite { - r_set_splunk_dest_default( - index('netfw') - source('cisco:meraki:${.tmp.device}') - sourcetype('meraki:${.tmp.device}') - vendor("cisco") - product("meraki") - class("${.tmp.device}") - ); - }; - }; -}; - -application app-syslog-cisco_meraki[sc4s-syslog] { - filter { - ( - ( - host('MX' type(string) flags(ignore-case,prefix)) - or host('MS' type(string) flags(ignore-case,prefix)) - or host('MR' type(string) flags(ignore-case,prefix)) - ) - ) - and ( - ( - program('events' type(string)) - or program('urls' type(string)) - or program('firewall' type(string)) - or program('cellular_firewall' type(string)) - or program('vpn_firewall' type(string)) - or program('ids-alerts' type(string)) - or program('flows' type(string)) - ) - ) - }; - parser { app-syslog-cisco_meraki() }; -}; \ No newline at end of file diff --git a/package/etc/test_parsers/app-vps-test-cisco_meraki.conf b/package/etc/test_parsers/app-vps-test-cisco_meraki.conf index a9c69083c1..60203460f0 100644 --- a/package/etc/test_parsers/app-vps-test-cisco_meraki.conf +++ b/package/etc/test_parsers/app-vps-test-cisco_meraki.conf @@ -1,11 +1,50 @@ +#/opt/sc4s/local/config/app_parsers/app-vps-cisco_meraki.conf +#File name provided is a suggestion it must be globally unique + +block parser app-vps-test-cisco_meraki() { + channel { + if { + filter { host("^test-mx-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('securityappliances') + ); + }; + } elif { + filter { host("^test-mr-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('accesspoints') + ); + }; + } elif { + filter { host("^test-ms-") }; + parser { + p_set_netsource_fields( + vendor('meraki') + product('switches') + ); + }; + } else { + parser { + p_set_netsource_fields( + vendor('cisco') + product('meraki') + ); + }; + }; + }; +}; + + application app-vps-test-cisco_meraki[sc4s-vps] { - filter { - host("^testcm-") - }; - parser { - p_set_netsource_fields( - vendor('cisco') - product('meraki') - ); + filter { + host("^test-meraki-") + or host("^test-mx-") + or host("^test-mr-") + or host("^test-ms-") }; + parser { app-vps-test-cisco_meraki(); }; }; diff --git a/package/lite/etc/addons/cisco/app-almost-syslog-cisco_meraki.conf b/package/lite/etc/addons/cisco/app-almost-syslog-cisco_meraki.conf deleted file mode 100644 index 69ee78f9e8..0000000000 --- a/package/lite/etc/addons/cisco/app-almost-syslog-cisco_meraki.conf +++ /dev/null @@ -1,28 +0,0 @@ -rewrite set_rfc3164_cisco_meraki{ - set-tag("wireformat:rfc3164_cisco_meraki"); -}; - -block parser app-almost-syslog-cisco_meraki() { - channel { - parser { - regexp-parser( - prefix(".tmp.") - patterns('^(?\<\d+\>) ?(?[A-Z][a-z]{2} *\d{1,2} \d\d:\d\d:\d\d) (?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (?\d) (?\d{10}\.\d{9}) (?.*)') - ); - date-parser( - format('%s.%f', '%s') - template("${.tmp.ts2}") - ); - syslog-parser( - flags(assume-utf8, guess-timezone) - template("${.tmp.pri} $S_ISODATE ${.tmp.message}") - ); - }; - rewrite(set_rfc); - rewrite(set_rfc3164); - rewrite(set_rfc3164_cisco_meraki); - }; -}; -application app-almost-syslog-cisco_meraki[sc4s-almost-syslog] { - parser { app-almost-syslog-cisco_meraki(); }; -}; diff --git a/package/lite/etc/addons/cisco/app-netsource-cisco_meraki.conf b/package/lite/etc/addons/cisco/app-netsource-cisco_meraki.conf index 579cfc295d..6d54b000d5 100644 --- a/package/lite/etc/addons/cisco/app-netsource-cisco_meraki.conf +++ b/package/lite/etc/addons/cisco/app-netsource-cisco_meraki.conf @@ -1,31 +1,88 @@ -block parser app-netsource-cisco_meraki() { - channel { - rewrite { - r_set_splunk_dest_default( - index('netfw') - sourcetype('meraki') - vendor('cisco') - product('meraki') - ); +block filter f_cisco_meraki(vendor() product()) { + ( + match(`vendor`, value('.netsource.sc4s_vendor'), type(string)) + and match(`product`, value('.netsource.sc4s_product'), type(string)) + ) + or (tags('ns_vendor:`vendor`') and tags('ns_product:`product`')) + or tags('`vendor`_`product`') + or "${.netsource.sc4s_vendor_product}" eq '`vendor`_`product`' +}; +block parser app-netsource-cisco_meraki() { + channel { + if { + filter { + f_cisco_meraki( + vendor('cisco') + product('meraki') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki') + vendor('cisco') + product('meraki') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('securityappliances') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:securityappliances') + vendor('meraki') + product('securityappliances') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('accesspoints') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:accesspoints') + vendor('meraki') + product('accesspoints') + ); + }; + } elif { + filter { + f_cisco_meraki( + vendor('meraki') + product('switches') + ); + }; + rewrite { + r_set_splunk_dest_default( + index('netfw') + sourcetype('meraki:switches') + vendor('meraki') + product('switches') + ); + }; }; - - - }; + }; }; + application app-netsource-cisco_meraki[sc4s-network-source] { filter { not filter(f_is_source_identified) and ( - ( - match("cisco", value('.netsource.sc4s_vendor'), type(string)) - and match("meraki", value('.netsource.sc4s_product'), type(string)) - ) - or (tags("ns_vendor:cisco") and tags("ns_product:meraki")) - or tags(".source.s_CISCO_MERAKI") - or "${.netsource.sc4s_vendor_product}" eq "cisco_meraki" - ) - ; - }; - parser { app-netsource-cisco_meraki(); }; -}; + f_cisco_meraki(vendor('cisco') product('meraki')) + or f_cisco_meraki(vendor('meraki') product('securityappliances')) + or f_cisco_meraki(vendor('meraki') product('accesspoints')) + or f_cisco_meraki(vendor('meraki') product('switches')) + ) + }; + parser { app-netsource-cisco_meraki(); }; +}; \ No newline at end of file diff --git a/package/lite/etc/addons/cisco/app-syslog-cisco_meraki.conf b/package/lite/etc/addons/cisco/app-syslog-cisco_meraki.conf deleted file mode 100644 index 73e1d7dff6..0000000000 --- a/package/lite/etc/addons/cisco/app-syslog-cisco_meraki.conf +++ /dev/null @@ -1,45 +0,0 @@ -block parser app-syslog-cisco_meraki() { - channel { - - rewrite { - set("securityappliances", value(".tmp.device") condition( host('MX' type(string) flags(ignore-case,prefix)))); - set("switches", value(".tmp.device") condition( host('MS' type(string) flags(ignore-case,prefix)))); - set("accesspoints", value(".tmp.device") condition( host('MR' type(string) flags(ignore-case,prefix)))); - }; - - rewrite { - r_set_splunk_dest_default( - index('netfw') - source('cisco:meraki:${.tmp.device}') - sourcetype('meraki:${.tmp.device}') - vendor("cisco") - product("meraki") - class("${.tmp.device}") - ); - }; - }; -}; - -application app-syslog-cisco_meraki[sc4s-syslog] { - filter { - ( - ( - host('MX' type(string) flags(ignore-case,prefix)) - or host('MS' type(string) flags(ignore-case,prefix)) - or host('MR' type(string) flags(ignore-case,prefix)) - ) - ) - and ( - ( - program('events' type(string)) - or program('urls' type(string)) - or program('firewall' type(string)) - or program('cellular_firewall' type(string)) - or program('vpn_firewall' type(string)) - or program('ids-alerts' type(string)) - or program('flows' type(string)) - ) - ) - }; - parser { app-syslog-cisco_meraki() }; -}; \ No newline at end of file diff --git a/tests/test_cisco_meraki.py b/tests/test_cisco_meraki.py index 02863236c4..afa6d406f4 100644 --- a/tests/test_cisco_meraki.py +++ b/tests/test_cisco_meraki.py @@ -22,31 +22,31 @@ # MX events: vpn connectivity change { "template": "{{ mark }} {{ epoch }} {{ host }} events type=vpn_connectivity_change vpn_type='site-to-site' peer_contact='1.1.1.1:51856' peer_ident='XXXXX' connectivity='false'", - "host_prefix": "MX", + "host_prefix": "test-mx-", "sourcetype": "meraki:securityappliances" }, # urls: HTTP GET requests { "template": "{{ mark }} {{ epoch }} {{ host }} urls src=1.1.1.1:63735 dst=1.1.1.1:80 mac=XX:XX:XX:XX:XX:XX request: GET https://...", - "host_prefix": "MX", + "host_prefix": "test-mx-", "sourcetype": "meraki:securityappliances" }, # MX flows { "template": "{{ mark }} {{ epoch }} {{ host }} flows src=1.1.1.186 dst=8.8.8.8 mac=XX:XX:XX:XX:XX:XX protocol=udp sport=55719 dport=53 pattern: allow all", - "host_prefix": "MX", + "host_prefix": "test-mx-", "sourcetype": "meraki:securityappliances" }, # MX firewall { "template": "{{ mark }} {{ epoch }} {{ host }} firewall src=1.1.1.186 dst=8.8.8.8 mac=XX:XX:XX:XX:XX:XX protocol=udp sport=55719 dport=53 pattern: allow all", - "host_prefix": "MX", + "host_prefix": "test-mx-", "sourcetype": "meraki:securityappliances" }, # MX ids-alerts: ids signature matched { "template": "{{ mark }} {{ epoch }} {{ host }} ids-alerts signature=129:4:1 priority=3 timestamp=1377449842.512569 direction=ingress protocol=tcp/ip src=1.1.1.1:80", - "host_prefix": "MX", + "host_prefix": "test-mx-", "sourcetype": "meraki:securityappliances" } ] @@ -55,13 +55,13 @@ # MS events: port status change { "template": "{{ mark }} {{ epoch }} {{ host }} events port 3 status changed from 100fdx to down", - "host_prefix": "MS", + "host_prefix": "test-ms-", "sourcetype": "meraki:switches" }, # MS events: blocked DHCP server response { "template": "{{ mark }} {{ epoch }} {{ host }} events Blocked DHCP server response from XX:XX:XX:XX:XX:XX on VLAN 100", - "host_prefix": "MS", + "host_prefix": "test-ms-", "sourcetype": "meraki:switches" } ] @@ -70,51 +70,30 @@ # MR events: 802.11 association { "template": "{{ mark }} {{ epoch }} {{ host }} events type=association radio='0' vap='1' channel='6' rssi='23' aid='XXXXXX'", - "host_prefix": "MR", + "host_prefix": "test-mr-", "sourcetype": "meraki:accesspoints" }, # MR events: WPA authentication { "template": "{{ mark }} {{ epoch }} {{ host }} events type=wpa_auth radio='0' vap='1' aid='XXXXXXX'", - "host_prefix": "MR", + "host_prefix": "test-mr-", "sourcetype": "meraki:accesspoints" }, # MR events: splash authentication { "template": "{{ mark }} {{ epoch }} {{ host }} events type=splash_auth ip='1.1.1.1 [More Information] ' duration='3600' vap='2' download='5242880bps' upload='5242880bps'", - "host_prefix": "MR", + "host_prefix": "test-mr-", "sourcetype": "meraki:accesspoints" }, # MR flows: flow denied by Layer 3 firewall { "template": "{{ mark }} {{ epoch }} {{ host }} flows deny src=1.1.1.1 dst=1.1.1.1 mac=XX:XX:XX:XX:XX:XX protocol=tcp sport=52421 dport=80", - "host_prefix": "MR", + "host_prefix": "test-mr-", "sourcetype": "meraki:accesspoints" } ] -mx_almost_syslog_test_data = [ - # MX events: uplink connectivity change - { - "template": "{{ mark }} Dec 6 08:46:12 1.1.1.1 1 {{ epoch }} {{ host }} events Cellular connection down", - "host_prefix": "MX", - "sourcetype": "meraki:securityappliances" - }, - # MX events: dhcp no offers - { - "template": "{{ mark }} Sep 11 16:12:41 1.1.1.1 1 {{ epoch }} {{ host }} events dhcp no offers for mac XX:XX:XX:XX:XX:XX host = 1.1.1.1", - "host_prefix": "MX", - "sourcetype": "meraki:securityappliances" - }, - # MX events: dhcp lease - { - "template": "{{ mark }} Sep 11 16:05:15 1.1.1.1 1 {{ epoch }} {{ host }} events dhcp lease of ip 1.1.1.1 from server mac XX:XX:XX:XX:XX:XX for client mac XX:XX:XX:XX:XX:XX from router 1.1.1.1 on subnet 255.255.255.0 with dns 8.8.8.8, 8.8.4.4", - "host_prefix": "MX", - "sourcetype": "meraki:securityappliances" - } -] - -test_data = mx_test_data + ms_test_data + mr_test_data + mx_almost_syslog_test_data +test_data = mx_test_data + ms_test_data + mr_test_data @pytest.mark.parametrize("test_case", test_data) @@ -156,7 +135,7 @@ def test_cisco_meraki_syslog_app( def test_cisco_meraki_vps_app( record_property, setup_splunk, setup_sc4s ): - host = f"testcm-host-{shortuuid.ShortUUID().random(length=5).lower()}" + host = f"test-meraki-{shortuuid.ShortUUID().random(length=5).lower()}" dt = datetime.datetime.now() _, _, _, _, _, _, epoch = time_operations(dt)