diff --git a/.env.template b/.env.template index 5a9bda1..58e599a 100644 --- a/.env.template +++ b/.env.template @@ -16,6 +16,6 @@ SPLUNK_HEC_STATSURL=https://splunk:8088/services/collector/event SPLUNK_CONNECT_METHOD=hec SPLUNK_DEFAULT_INDEX=main SPLUNK_METRICS_INDEX=metrics -SPLUNK_APPS_URL=https://splunkbase.splunk.com/app/2757/release/6.1.1/download,https://splunkbase.splunk.com/app/3245/release/1.0/download,https://splunkbase.splunk.com/app/1620/release/3.4.0/download,https://splunkbase.splunk.com/app/1467/release/2.5.8/download,https://splunkbase.splunk.com/app/2846/release/1.6.0/download +SPLUNK_APPS_URL=https://splunkbase.splunk.com/app/2757/release/6.1.1/download,https://splunkbase.splunk.com/app/3245/release/1.0/download,https://splunkbase.splunk.com/app/1620/release/3.4.0/download,https://splunkbase.splunk.com/app/1467/release/2.5.8/download,https://splunkbase.splunk.com/app/2846/release/1.6.0/download,https://splunkbase.splunk.com/app/2847/release/1.2.0/download SPLUNKBASE_USERNAME=username SPLUNKBASE_PASSWORD=password diff --git a/.idea/misc.xml b/.idea/misc.xml index 86b631d..7e25d8b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,8 +3,8 @@ - + - + \ No newline at end of file diff --git a/.idea/splunk-connect-for-syslog.iml b/.idea/splunk-connect-for-syslog.iml index 0ecbb61..14d7789 100644 --- a/.idea/splunk-connect-for-syslog.iml +++ b/.idea/splunk-connect-for-syslog.iml @@ -2,7 +2,7 @@ - + diff --git a/README.md b/README.md index 02b59dd..e0d3259 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,6 @@ index = main # License - - Configuration and documentation licensed subject to [CC0](LICENSE-CC0) Code and scripts licensed subject to [BSD-2-Clause](LICENSE-BSD2) \ No newline at end of file diff --git a/docs/FortiGate_event.png b/docs/FortiGate_event.png new file mode 100644 index 0000000..9a0113d Binary files /dev/null and b/docs/FortiGate_event.png differ diff --git a/docs/FortiGate_traffic.png b/docs/FortiGate_traffic.png new file mode 100644 index 0000000..5bf2971 Binary files /dev/null and b/docs/FortiGate_traffic.png differ diff --git a/docs/FortiGate_utm.png b/docs/FortiGate_utm.png new file mode 100644 index 0000000..dc36625 Binary files /dev/null and b/docs/FortiGate_utm.png differ diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md new file mode 100644 index 0000000..2d7c971 --- /dev/null +++ b/docs/gettingstarted.md @@ -0,0 +1,58 @@ + +# Pre-req + +* Linux host with Docker 19.x or newer with Docker Swarm enabled + * [Getting Started](https://docs.docker.com/get-started/) +* A Splunk index for metrics typically "em_metrics" +* One or more Splunk indexes for events collected by SC4S +* Splunk HTTP event collector enabled with a token dedicated for SC4S + * [Splunk Enterprise](http://dev.splunk.com/view/event-collector/SP-CAAAE6Q) + * [Splunk Enterprise Cloud](http://docs.splunk.com/Documentation/Splunk/7.3.1/Data/UsetheHTTPEventCollector#Configure_HTTP_Event_Collector_on_managed_Splunk_Cloud) +* A network load balancer (NLB) configured for round robin. Note: Special consideration may be required when more advanced products are used. The optimal configuration of the load balancer will round robin each http POST request (not each connection) + +# Setup + +* Create a directory on the server for configuration +* Create a docker-compose.yml file based on the following template + +```yaml +version: "3" +services: + sc4s: + image: rfaircloth/scs:latest + hostname: sc4s + ports: + - "514" + - "601" + - "514/udp" + - "5514" + - "5514/udp" + stdin_open: true + tty: true + environment: + - SPLUNK_HEC_URL=https://foo:8088/services/collector/event + - SPLUNK_HEC_TOKEN= + - SPLUNK_CONNECT_METHOD=hec + - SPLUNK_DEFAULT_INDEX= + - SPLUNK_METRICS_INDEX=em_metrics + volumes: + - splunk_index.csv:/opt/syslog-ng/etc/context/splunk_index.csv +``` + +* Download the latest context.csv file to the current directory +```bash +wget https://raw.githubusercontent.com/splunk/splunk-connect-for-syslog/master/package/etc/context/splunk_index.csv +``` + +* Edit splunk_index.csv review the index configuration and revise as required for sourcertypes utilized in your environment. + +* Start SC4S + +```bash +docker stack deploy --compose-file docker-compose.yml sc4s +``` + + +## Scale out + +Additional hosts can be deployed for syslog collection from additional network zones and locations diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..19dfcad --- /dev/null +++ b/docs/index.md @@ -0,0 +1,24 @@ +# Welcome to Splunk Connect for Syslog + +Splunk Connect for Syslog is an open source packaged solution for +getting data into Splunk using syslog-ng Open Source Edition (Syslog-NG OSE) and the Splunk +HTTP event Collector. + +## Project Goals + +* Bring a tested configuration and build of syslog-ng OSE to the market that will function consistently regardless of the underlying host's linux distribution +* Provide a container with the tested configuration for Docker/K8s that can be more easily deployed than upstream packages directly on a customer OS +* Provide validated (testable and tested) implementations of filter and parse functions for common vendor products +* Reduce latency and improve scale by balancing event distribution across Splunk Indexers + + + +## License + +* Configuration and documentation licensed subject to [CC0](LICENSE-CC0) + +* Code and scripts licensed subject to [BSD-2-Clause](LICENSE-BSD2) + +* Third Party Red Hat Universal Base Image see [License](https://www.redhat.com/licenses/EULA_Red_Hat_Universal_Base_Image_English_20190422.pdf) + +* Third Party Syslog-NG (OSE) [License](https://github.com/balabit/syslog-ng) diff --git a/docs/performance.md b/docs/performance.md new file mode 100644 index 0000000..3eba88d --- /dev/null +++ b/docs/performance.md @@ -0,0 +1,27 @@ +# Performance + +## Tested Configuration + +* SC4S instance requesting 8 cores and 4 GB of memory with K8S scheduler. +* 6 Splunk Indexers clustered in Single site +* 1 loggen test client using the following command +* AWS instance type c5n.4xlarge + +```bash +/opt/syslog-ng/bin/loggen -i --rate=1000 --interval=180 -P -F --sdata="[test name=\"stress17\"]" -s 800 --active-connections=10 sc4s 514 +``` + +## Result + +The single syslog-ng container in this test is able to provided effective balancing and routing of events equivalent 632 GB per day + +``` +average rate = 9717.58 msg/sec, count=1749420, time=180.026, (average) msg size=800, bandwidth=7591.86 kB/sec + +``` + + +## Limitations + +* Splunk Enterprise's implementation of the http event collection server will respond to the client with a status code 200 and fail to commit the events to disk during a rolling restart in our testing 20-30 events per indexer may be lost + diff --git a/docs/sources.md b/docs/sources.md new file mode 100644 index 0000000..3fd78da --- /dev/null +++ b/docs/sources.md @@ -0,0 +1,170 @@ +# Vendor - Cisco + +## Product - ASA (Pre Firepower) + +| Ref | Link | +|----------------|---------------------------------------------------------------------------------------------------------| +| Splunk Add-on | https://splunkbase.splunk.com/app/1620/ | +| Product Manual | https://www.cisco.com/c/en/us/td/docs/security/asa/asa82/configuration/guide/config/monitor_syslog.html | + + +## Sourcetypes + +| sourcetype | notes | +|----------------|---------------------------------------------------------------------------------------------------------| +| cisco:asa | None | +| cisco:pix | Not supported | +| cisco:fwsm | Not supported | + +## Filter type + +MSG Parse: This filter parses message content + +## Setup and Configuration + +* Install the Splunk Add-on on the search head(s) for the user communities interested in this data source. If SC4S is exclusively used the addon is not required on the indexer. +* Review and update the splunk_index.csv file and set the index as required. +* Follow vendor configuration steps per Product Manual above ensure: + * Log Level is 6 "Informational" + * Protocol is TCP/IP + * permit-hostdown is on + * device-id is hostname and included + * timestamp is included + +## Verification + +Use the following search to validate events are present + +``` +index= sourcetype=cisco:asa +``` + +Verify timestamp, and host values match as expected + +# Vendor - Fortinet + +## Product - Fortigate + +| Ref | Link | +|----------------|---------------------------------------------------------------------------------------------------------| +| Splunk Add-on | https://splunkbase.splunk.com/app/2846/ | +| Product Manual | https://docs.fortinet.com/product/fortigate/6.2 | + + +## Sourcetypes + +| sourcetype | notes | +|----------------|---------------------------------------------------------------------------------------------------------| +| fgt_log | The catch all sourcetype is not used | +| fgt_traffic | None | +| fgt_utm | None | +| fgt_event | None + +## Filter type + +MSG Parse: This filter parses message content + +## Setup and Configuration + +* Install the Splunk Add-on on the search head(s) for the user communities interested in this data source. If SC4S is exclusively used the addon is not required on the indexer. +* Review and update the splunk_index.csv file and set the index as required. +* Refer to the admin manual for specific details of configuration to send Reliable syslog using RFC 3195 format, a typical logging configuration will include the following features. + +``` +config log memory filter + +set forward-traffic enable + +set local-traffic enable + +set sniffer-traffic disable + +set anomaly enable + +set voip disable + +set multicast-traffic enable + +set dns enable + +end + +config system global + +set cli-audit-log enable + +end + +config log setting + +set neighbor-event enable + +end + +``` + +## Verification + +An active firewall will generate frequent events, in addition fortigate has the ability to test logging functionality using a build in command + +``` +diag log test +``` + +Verify timestamp, and host values match as expected + +``` +index= (sourcetype=fgt_log OR sourcetype=fgt_traffic OR sourcetype=fgt_utm) +``` + +###UTM Message type + +![FortiGate UTM message](FortiGate_utm.png) + +### Traffic Message Type + +![FortiGate Traffic message](FortiGate_traffic.png) + +###Event Message Type +![FortiGate Event message](FortiGate_event.png) + +Verify timestamp, and host values match as expected + +# Vendor - PaloAlto + +## Product - NGFW + +| Ref | Link | +|----------------|---------------------------------------------------------------------------------------------------------| +| Splunk Add-on | https://splunkbase.splunk.com/app/2757/ | +| Product Manual | https://docs.paloaltonetworks.com/pan-os/9-0/pan-os-admin/monitoring/use-syslog-for-monitoring/configure-syslog-monitoring.html | + + +## Sourcetypes + +| sourcetype | notes | +|----------------|---------------------------------------------------------------------------------------------------------| +| pan:log | None | +| pan:traffic | None | +| pan:threat | None | + +## Filter type + +MSG Parse: This filter parses message content + +## Setup and Configuration + +* Install the Splunk Add-on on the search head(s) for the user communities interested in this data source. If SC4S is exclusively used the addon is not required on the indexer. +* Review and update the splunk_index.csv file and set the index as required. +* Refer to the admin manual for specific details of configuration + * Select TCP or SSL transport option + * Select IETF Format + * Ensure the format of the event is not customized + +## Verification + +An active firewall will generate frequent events use the following search to validate events are present per source device + +``` +index= sourcetype=pan:*| stats count by host +``` \ No newline at end of file diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..ff2258a --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,9 @@ +#Troubleshooting + +## Syslog-ng Metrics + +## Syslog-NG Events + +## Container Events + +# Monitoring diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..38dddfb --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,8 @@ +site_name: Splunk Connect for Syslog +theme: readthedocs +nav: + - Home: 'index.md' + - Performance: 'performance.md' + - Getting Started: 'gettingstarted.md' + - Sources: 'sources.md' + - Troubleshooting: 'troubleshooting.md' \ No newline at end of file diff --git a/package/etc/conf.d/blocks/b_parsers.conf b/package/etc/conf.d/blocks/b_parsers.conf index 407ea8a..8aae8e9 100644 --- a/package/etc/conf.d/blocks/b_parsers.conf +++ b/package/etc/conf.d/blocks/b_parsers.conf @@ -47,9 +47,9 @@ block rewrite r_set_splunk(sourcetype(`splunk-sourcetype`) set("`vendor`", value(".splunk.vendor")); set("`category`", value(".splunk.category")); set("`filename`", value(".splunk.filename")); - set($FACILITY, value("fields.facility")); - set($LEVEL, value("fields.severity")); - set($LOGHOST, value("fields.syslog-server")); + set($FACILITY, value("fields.syslog_facility")); + set($LEVEL, value("fields.syslog_severity")); + set($LOGHOST, value("fields.syslog_server")); }; #Used when for normal filters index and sourcetype must be set in a prior re-write or context @@ -63,7 +63,7 @@ block rewrite r_set_splunk_basic( set("`vendor`", value(".splunk.vendor")); set("`category`", value(".splunk.category")); set("`filename`", value(".splunk.filename")); - set($FACILITY, value("fields.facility")); - set($LEVEL, value("fields.severity")); - set($LOGHOST, value("fields.syslog-server")); + set($FACILITY, value("fields.syslog_facility")); + set($LEVEL, value("fields.syslog_severity")); + set($LOGHOST, value("fields.syslog_server")); }; diff --git a/package/etc/conf.d/destinations/d_destinations.conf b/package/etc/conf.d/destinations/d_destinations.conf index 6d4f9d4..5c59aee 100644 --- a/package/etc/conf.d/destinations/d_destinations.conf +++ b/package/etc/conf.d/destinations/d_destinations.conf @@ -17,15 +17,16 @@ destination d_hec { method("POST") log-fifo-size(`splunk-log-fifo-size`) workers(`SYSLOGNG_HEC_WORKERS`) - batch-lines(500) - batch-bytes(512Kb) + batch-lines(1000) + batch-bytes(2048Kb) batch-timeout(3) timeout(15) user_agent("syslog-ng User Agent") user("syslog-ng") + headers("Connection: close") password("`SPLUNK_HEC_TOKEN`") persist-name("splunk") - disk-buffer(mem-buf-length(500) + disk-buffer(mem-buf-length(15000) disk-buf-size(20000) reliable(no) dir("/opt/syslog-ng/var/data/disk-buffer/")) @@ -44,7 +45,7 @@ destination d_hec { source=${HOST_FROM} sourcetype=${.splunk.sourcetype} index=${.splunk.index} - event=$(template ${.splunk.template}) + event=$(template ${.splunk.template} $(template `splunk-default-template`)) fields.*)') ); }; diff --git a/package/etc/conf.d/filters/fortinet_fgt.conf b/package/etc/conf.d/filters/fortinet_fgt.conf index f862fa9..d6205b5 100644 --- a/package/etc/conf.d/filters/fortinet_fgt.conf +++ b/package/etc/conf.d/filters/fortinet_fgt.conf @@ -6,12 +6,12 @@ log { }; parser { - kv-parser(prefix(".kv.")); - date-parser(format("%Y-%m-%d:%H:%M:%S") template("${.kv.date}:${.kv.time}")); + syslog-parser(); + kv-parser(prefix(".kv.") template("${MSGHDR} ${MSG}")); + date-parser(format("%Y-%m-%d:%H:%M:%S") template("${.kv.date}:${.kv.time}") time-zone(`default-timezone`)); }; rewrite { set("${.kv.devname}", value("HOST")); }; - rewrite { subst('<\d+>(.*)' "$1" value("MSG")); }; #set the source type based on program field and lookup index from the splunk context csv if (match("traffic" value(".kv.type"))) { @@ -24,16 +24,9 @@ log { parser {p_add_context_splunk(key("fgt_log")); }; }; - rewrite { - #drop the header - subst('date=[^ ]+ time=[^ ]+ devname=.+ (devid.*)', '$1', value("MESSAGE")); - #Strip empty fields because SEDCMD can't when we use event endpoint - subst('([^\= ]+=(?: |\"\"|-|\"-") ?)', '', value("MESSAGE")); - }; - #rewrite the final message for splunk json #sourcetype and index are set in the filter defaults won't be used - rewrite {r_set_splunk_basic(template("t_msg_only")) }; #--HEC-- + rewrite {r_set_splunk_basic(template("t_standard")) }; #--HEC-- destination(d_hec); #--HEC-- flags(flow-control,final); diff --git a/package/etc/conf.d/filters/juniper_junos.conf b/package/etc/conf.d/filters/juniper_junos.conf new file mode 100644 index 0000000..3a205e4 --- /dev/null +++ b/package/etc/conf.d/filters/juniper_junos.conf @@ -0,0 +1,65 @@ +# =============================================================================================== +# Juniper Standard and Structured logging +# =============================================================================================== + +log { + + source(s_default-ports); + +# For newer (structured) format; RFC 5424 compliant. The existing TA will not work for this format; these filters +# are included for future TA development. The exception is NSM IDP, for which we're awaiting a data +# sample to confirm that it follows the RFC 5424 format. +# If it is determined that NSM IDP ("syslog@juniper.net") messages are indeed 3164 format, remove the check for +# the "syslog@juniper.net" message below. It will then be caught by the standard section following. + +junction { + channel { + filter { tags("juniper_structured") or message('junos@2636') or message('syslog@juniper.net'); }; + parser { syslog-parser(flags(syslog-protocol)); }; + if (tags("juniper_JunOS_IDP") or program('RT_IDP')) { + parser {p_add_context_splunk(key("juniper:junos:idp:structured")); }; + } elif (tags("juniper_JunOS_Firewall") or program('RT_FLOW|RT_IDS|RT_UTM')) { + parser {p_add_context_splunk(key("juniper:junos:firewall:structured")); }; + } + elif (tags("juniper_idp") or program('Jnpr')) { + parser {p_add_context_splunk(key("juniper:idp:structured")); }; + } + else { + parser {p_add_context_splunk(key("juniper:structured")); }; + }; + rewrite { r_set_splunk_basic(template("t_hdr_sdata_msg"))}; + destination(d_hec); #--HEC-- + flags(final); + }; + +# For legacy "standard" format. The existing Juniper TA will work for these data sources. +# Remove the message filter below when tag support is implemented. + + channel { + filter { tags("juniper_standard") or message('RT_IDP:|RT_FLOW:|RT_IDS:|RT_UTM:|Juniper:|traffic\,\s+traffic\s+log|syslog@juniper.net|predefined\,\s+|NetScreen\s+device_id\=') }; +# filter { tags("juniper_standard") }; + parser { syslog-parser(time-zone(`default-timezone`)); }; + if (program('RT_IDP')) { + parser {p_add_context_splunk(key("juniper:junos:idp")); }; + } elif (program('RT_FLOW|RT_IDS|RT_UTM')) { + parser {p_add_context_splunk(key("juniper:junos:firewall")); }; + } elif (program('Juniper')) { + parser {p_add_context_splunk(key("juniper:sslvpn")); }; + } elif (message('traffic\,\s+traffic\s+log')) { + parser {p_add_context_splunk(key("juniper:nsm")); }; + } elif (message('syslog@juniper.net')) { + parser {p_add_context_splunk(key("juniper:idp")); }; + } elif (message('predefined\,\s+')) { + parser {p_add_context_splunk(key("juniper:nsm:idp")); }; + } elif (message('NetScreen\s+device_id\=')) { + parser {p_add_context_splunk(key("juniper:netscreen")); }; + } + else { + parser {p_add_context_splunk(key("juniper:legacy")); }; + }; + rewrite { r_set_splunk_basic(template("t_standard")) }; + destination(d_hec); #--HEC-- + flags(final); + }; + }; +}; diff --git a/package/etc/conf.d/templates/t_templates.conf b/package/etc/conf.d/templates/t_templates.conf index 825a705..0190f1f 100644 --- a/package/etc/conf.d/templates/t_templates.conf +++ b/package/etc/conf.d/templates/t_templates.conf @@ -8,7 +8,7 @@ # =============================================================================================== template t_standard { - template("${ISODATE} ${HOST} ${MESSAGE}"); + template("${DATE} ${HOST} ${MSGHDR}${MESSAGE}"); }; # =============================================================================================== @@ -35,6 +35,14 @@ template t_hdr_msg { template("${MSGHDR}${MESSAGE}"); }; +# =============================================================================================== +# Message Header, Structured Data (from RFC5424 parse) and Message; for Juniper +# =============================================================================================== + +template t_hdr_sdata_msg { + template("${MSGHDR}${MSGID} ${SDATA} ${MESSAGE}"); + }; + # =============================================================================================== # JSON; for JSON pretty-printing # =============================================================================================== diff --git a/package/etc/context/splunk_index.csv b/package/etc/context/splunk_index.csv index 97cf982..e495491 100644 --- a/package/etc/context/splunk_index.csv +++ b/package/etc/context/splunk_index.csv @@ -10,6 +10,30 @@ fgt_traffic,sourcetype,fgt_traffic fgt_traffic,index,main fgt_utm,sourcetype,fgt_utm fgt_utm,index,main +juniper:structured,index,main +juniper:structured,sourcetype,juniper:structured +juniper:junos:firewall:structured,index,main +juniper:junos:firewall:structured,sourcetype,juniper:junos:firewall:structured +juniper:junos:idp:structured,index,main +juniper:junos:idp:structured,sourcetype,juniper:junos:idp:structured +juniper:junos:firewall,index,main +juniper:junos:firewall,sourcetype,juniper:junos:firewall +juniper:junos:idp,index,main +juniper:junos:idp,sourcetype,juniper:junos:idp +juniper:nsm:idp,index,main +juniper:nsm:idp,sourcetype,juniper:nsm:idp +juniper:sslvpn,index,main +juniper:sslvpn,sourcetype,juniper:sslvpn +juniper:netscreen,index,main +juniper:netscreen,sourcetype,netscreen:firewall +juniper:idp,index,main +juniper:idp,sourcetype,juniper:idp +juniper:idp:structured,index,main +juniper:idp:structured,sourcetype,juniper:idp:structured +juniper:nsm,index,main +juniper:nsm,sourcetype,juniper:nsm +juniper:legacy,index,main +juniper:legacy,sourcetype,juniper:legacy pan:traffic,index,main pan:threat,index,main pan:system,index,main diff --git a/tests/test_fortinet_ngfw.py b/tests/test_fortinet_ngfw.py index e7f982d..60fdae7 100644 --- a/tests/test_fortinet_ngfw.py +++ b/tests/test_fortinet_ngfw.py @@ -19,7 +19,7 @@ def test_fortinet_fgt_event(record_property, setup_wordlist, setup_splunk): host = "{}-{}".format(random.choice(setup_wordlist), random.choice(setup_wordlist)) mt = env.from_string( - "{{ mark }}date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FGT60D4614044725 logid=0100040704 type=event subtype=system level=notice vd=root logdesc=\"System performance statistics\" action=\"perf-stats\" cpu=2 mem=35 totalsession=61 disk=2 bandwidth=158/138 setuprate=2 disklograte=0 fazlograte=0 msg=\"Performance statistics: average CPU: 2, memory: 35, concurrent sessions: 61, setup-rate: 2\"\n") + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FGT60D4614044725 logid=0100040704 type=event subtype=system level=notice vd=root logdesc=\"System performance statistics\" action=\"perf-stats\" cpu=2 mem=35 totalsession=61 disk=2 bandwidth=158/138 setuprate=2 disklograte=0 fazlograte=0 msg=\"Performance statistics: average CPU: 2, memory: 35, concurrent sessions: 61, setup-rate: 2\"\n") message = mt.render(mark="<13>", host=host) sendsingle(message) @@ -41,7 +41,7 @@ def test_fortinet_fgt_traffic(record_property, setup_wordlist, setup_splunk): host = "{}-{}".format(random.choice(setup_wordlist), random.choice(setup_wordlist)) mt = env.from_string( - "{{ mark }}date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FG800C3912801080 logid=0004000017 type=traffic subtype=sniffer level=notice vd=root srcip=fe80::20c:29ff:fe77:20d4 srcintf=\"port3\" dstip=ff02::1:ff77:20d4 dstintf=\"port3\" sessionid=408903 proto=58 action=accept policyid=2 dstcountry=\"Reserved\" srccountry=\"Reserved\" trandisp=snat transip=:: transport=0 service=\"icmp6/131/0\" duration=36 sentbyte=0 rcvdbyte=40 sentpkt=0 rcvdpkt=0 appid=16321 app=\"IPv6.ICMP\" appcat=\"Network.Service\" apprisk=elevated applist=\"sniffer-profile\" appact=detected utmaction=allow countapp=1\n") + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FG800C3912801080 logid=0004000017 type=traffic subtype=sniffer level=notice vd=root srcip=fe80::20c:29ff:fe77:20d4 srcintf=\"port3\" dstip=ff02::1:ff77:20d4 dstintf=\"port3\" sessionid=408903 proto=58 action=accept policyid=2 dstcountry=\"Reserved\" srccountry=\"Reserved\" trandisp=snat transip=:: transport=0 service=\"icmp6/131/0\" duration=36 sentbyte=0 rcvdbyte=40 sentpkt=0 rcvdpkt=0 appid=16321 app=\"IPv6.ICMP\" appcat=\"Network.Service\" apprisk=elevated applist=\"sniffer-profile\" appact=detected utmaction=allow countapp=1\n") message = mt.render(mark="<13>", host=host) sendsingle(message) @@ -62,7 +62,7 @@ def test_fortinet_fgt_utm(record_property, setup_wordlist, setup_splunk): host = "{}-{}".format(random.choice(setup_wordlist), random.choice(setup_wordlist)) mt = env.from_string( - "{{ mark }}date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FGT37D4613800138 logid=0317013312 type=utm subtype=webfilter eventtype=ftgd_allow level=notice vd=root sessionid=1490845588 user=\"\" srcip=172.30.16.119 srcport=53235 srcintf=\"Internal\" dstip=114.112.67.75 dstport=80 dstintf=\"External-SDC\" proto=6 service=HTTP hostname=\"popo.wan.ijinshan.com\" profile=\"scan\" action=passthrough reqtype=direct url=\"/popo/launch?c=cHA9d29vZHMxOTgyQGhvdG1haWwuY29tJnV1aWQ9NDBiNDkyZDRmNzdhNjFmOTNlMjQwMjhiYjE3ZGRlYTYmY29tcGl\" sentbyte=525 rcvdbyte=325 direction=outgoing msg=\"URL belongs to an allowed category in policy\" method=domain cat=52 catdesc=\"Information Technology\"\n") + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} date={% now 'utc', '%Y-%m-%d' %} time={% now 'utc', '%H:%M:%S' %} devname={{ host }} devid=FGT37D4613800138 logid=0317013312 type=utm subtype=webfilter eventtype=ftgd_allow level=notice vd=root sessionid=1490845588 user=\"\" srcip=172.30.16.119 srcport=53235 srcintf=\"Internal\" dstip=114.112.67.75 dstport=80 dstintf=\"External-SDC\" proto=6 service=HTTP hostname=\"popo.wan.ijinshan.com\" profile=\"scan\" action=passthrough reqtype=direct url=\"/popo/launch?c=cHA9d29vZHMxOTgyQGhvdG1haWwuY29tJnV1aWQ9NDBiNDkyZDRmNzdhNjFmOTNlMjQwMjhiYjE3ZGRlYTYmY29tcGl\" sentbyte=525 rcvdbyte=325 direction=outgoing msg=\"URL belongs to an allowed category in policy\" method=domain cat=52 catdesc=\"Information Technology\"\n") message = mt.render(mark="<13>", host=host) sendsingle(message) diff --git a/tests/test_juniper.py b/tests/test_juniper.py new file mode 100644 index 0000000..c69f6c4 --- /dev/null +++ b/tests/test_juniper.py @@ -0,0 +1,276 @@ +# 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 + +from jinja2 import Environment +from flaky import flaky + +from .sendmessage import * +from .splunkutils import * + +env = Environment(extensions=['jinja2_time.TimeExtension']) + + +# <165>1 2007-02-15T09:17:15.719Z router1 mgd 3046 UI_DBASE_LOGOUT_EVENT [junos@2636.1.1.1.2.18 username="user"] User 'user' exiting configuration mode +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_junos_structured(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%Y-%m-%dT%H:%M:%S' %}.700Z {{ host }} mgd 3046 UI_DBASE_LOGOUT_EVENT [junos@2636.1.1.1.2.18 username=\"user\"] User 'user' exiting configuration mode\n") + message = mt.render(mark="<165>1", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:structured\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <165>1 2007-02-15T09:17:15.719Z idp1 RT_IDP - IDP_ATTACK_LOG_EVENT [junos@2636.1.1.1.2.135 epoch-time="1507845354" message-type="SIG" source-address="183.78.180.27" source-port="45610" destination-address="118.127.xx.xx" destination-port="80" protocol-name="TCP" service-name="SERVICE_IDP" application-name="HTTP" rule-name="9" rulebase-name="IPS" policy-name="Recommended" export-id="15229" repeat-count="0" action="DROP" threat-severity="HIGH" attack-name="TROJAN:ZMEU-BOT-SCAN" nat-source-address="0.0.0.0" nat-source-port="0" nat-destination-address="172.xx.xx.xx" nat-destination-port="0" elapsed-time="0" inbound-bytes="0" outbound-bytes="0" inbound-packets="0" outbound-packets="0" source-zone-name="sec-zone-name-internet" source-interface-name="reth0.XXX" destination-zone-name="dst-sec-zone1-outside" destination-interface-name="reth1.xxx" packet-log-id="0" alert="no" username="N/A" roles="N/A" message="-"] +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_junos_idp_structured(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%Y-%m-%dT%H:%M:%S' %}.700Z {{ host }} RT_IDP - IDP_ATTACK_LOG_EVENT [junos@2636.1.1.1.2.135 epoch-time=\"1507845354\" message-type=\"SIG\" source-address=\"183.78.180.27\" source-port=\"45610\" destination-address=\"118.127.xx.xx\" destination-port=\"80\" protocol-name=\"TCP\" service-name=\"SERVICE_IDP\" application-name=\"HTTP\" rule-name=\"9\" rulebase-name=\"IPS\" policy-name=\"Recommended\" export-id=\"15229\" repeat-count=\"0\" action=\"DROP\" threat-severity=\"HIGH\" attack-name=\"TROJAN:ZMEU-BOT-SCAN\" nat-source-address=\"0.0.0.0\" nat-source-port=\"0\" nat-destination-address=\"172.xx.xx.xx\" nat-destination-port=\"0\" elapsed-time=\"0\" inbound-bytes=\"0\" outbound-bytes=\"0\" inbound-packets=\"0\" outbound-packets=\"0\" source-zone-name=\"sec-zone-name-internet\" source-interface-name=\"reth0.XXX\" destination-zone-name=\"dst-sec-zone1-outside\" destination-interface-name=\"reth1.xxx\" packet-log-id=\"0\" alert=\"no\" username=\"N/A\" roles=\"N/A\" message=\"-\"]") + message = mt.render(mark="<165>1", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:junos:idp:structured\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <165>1 2010-06-23T18:05:55 10.209.83.9 Jnpr Syslog 23414 1 [syslog@juniper.net dayId="20100623" recordId="0" timeRecv="2010/06/23 18:05:55" timeGen="2010/06/23 18:05:51" domain="" devDomVer2="0" device_ip="10.209.83.9" cat="Config" attack="" srcZn="NULL" srcIntf="" srcAddr="0.0.0.0" srcPort="0" natSrcAddr="NULL" natSrcPort="0" dstZn="NULL" dstIntf="NULL" dstAddr="0.0.0.0" dstPort="0" natDstAddr="NULL" natDstPort="0" protocol="IP" ruleDomain="" ruleVer="0" policy="" rulebase="NONE" ruleNo="0" action="NONE" severity="INFO" alert="no" elaspedTime="0" inbytes="0" outbytes="0" totBytes="0" inPak="0" outPak="0" totPak="0" repCount="0" packetData="no" varEnum="0" misc="Interaface eth2,eth3 is in Normal State" user="NULL" app="NULL" uri="NULL"] +# +# +# +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_idp_structured(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%Y-%m-%dT%H:%M:%S' %}.700Z {{ host }} Jnpr Syslog 23414 [syslog@juniper.net dayId=\"20100623\" recordId=\"0\" timeRecv=\"2010/06/23 18:05:55\" timeGen=\"2010/06/23 18:05:51\" domain=\"\" devDomVer2=\"0\" device_ip=\"10.209.83.9\" cat=\"Config\" attack=\"\" srcZn=\"NULL\" srcIntf=\"\" srcAddr=\"0.0.0.0\" srcPort=\"0\" natSrcAddr=\"NULL\" natSrcPort=\"0\" dstZn=\"NULL\" dstIntf=\"NULL\" dstAddr=\"0.0.0.0\" dstPort=\"0\" natDstAddr=\"NULL\" natDstPort=\"0\" protocol=\"IP\" ruleDomain=\"\" ruleVer=\"0\" policy=\"\" rulebase=\"NONE\" ruleNo=\"0\" action=\"NONE\" severity=\"INFO\" alert=\"no\" elaspedTime=\"0\" inbytes=\"0\" outbytes=\"0\" totBytes=\"0\" inPak=\"0\" outPak=\"0\" totPak=\"0\" repCount=\"0\" packetData=\"no\" varEnum=\"0\" misc=\"Interaface eth2,eth3 is in Normal State\" user=\"NULL\" app=\"NULL\" uri=\"NULL\"]") + message = mt.render(mark="<165>1", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:idp:structured\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <134> Aug 02 14:45:04 10.0.0.1 65.197.254.193 20090320, 17331, 2009/03/20 14:47:45, 2009/03/20 14:47:50, global, 53, [FW NAME], [FW IP], traffic, traffic log, trust, (NULL), 10.1.1.20, 1725, 82.2.19.2, 2383, untrust, (NULL), 84.5.78.4, 80, 84.53.178.64, 80, tcp, global, 53, [FW NAME], fw/vpn, 4, accepted, info, no, Creation, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0, 0, 1, no, 0, Not Set, sos +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_junos_fw_structured(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%Y-%m-%dT%H:%M:%S' %}.700Z {{ host }} RT_FLOW - RT_FLOW_SESSION_CREATE_LS [junos@2636.1.1.1.2.26 logical-system-name=\"test-lsys\" source-address=\"10.10.10.100\" source-port=\"4206\" destination-address=\"10.20.20.15\" destination-port=\"445\" service-name=\"junos-smb\" nat-source-address=\"10.10.10.100\" nat-source-port=\"4206\" nat-destination-address=\"10.20.20.15\" nat-destination-port=\"445\" src-nat-rule-name=\"None\" dst-nat-rule-name=\"None\" protocol-id=\"6\" policy-name=\"123\" source-zone-name=\"TEST1\" destination-zone-name=\"TEST2\" session-id-32=\"14285714\" username=\"N/A\" roles=\"N/A\" packet-incoming-interface=\"reth1.100\"]") + message = mt.render(mark="<23>1", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:junos:firewall:structured\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + + +# <23> Mar 18 17:56:52 RT_UTM: WEBFILTER_URL_PERMITTED: WebFilter: ACTION="URL Permitted" 192.168.32.1(62054)->1.1.1.1(443) CATEGORY="Enhanced_Information_Technology" REASON="BY_PRE_DEFINED" PROFILE="UTM-Wireless-Profile" URL=ent-shasta-rrs.symantec.com OBJ=/ username N/A roles N/A +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_utm_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} RT_UTM: WEBFILTER_URL_PERMITTED: WebFilter: ACTION=\"URL Permitted\" 192.168.32.1(62054)->1.1.1.1(443) CATEGORY=\"Enhanced_Information_Technology\" REASON=\"BY_PRE_DEFINED\" PROFILE=\"UTM-Wireless-Profile\" URL=ent-shasta-rrs.symantec.com OBJ=/ username N/A roles N/A") + message = mt.render(mark="<23>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:junos:firewall\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <134> Aug 02 14:45:04 10.0.0.1 65.197.254.193 20090320, 17331, 2009/03/20 14:47:45, 2009/03/20 14:47:50, global, 53, [FW NAME], [FW IP], traffic, traffic log, trust, (NULL), 10.1.1.20, 1725, 82.2.19.2, 2383, untrust, (NULL), 84.5.78.4, 80, 84.53.178.64, 80, tcp, global, 53, [FW NAME], fw/vpn, 4, accepted, info, no, Creation, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0, 0, 1, no, 0, Not Set, sos +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_nsm_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} 65.197.254.193 20090320, 17331, 2009/03/20 14:47:45, 2009/03/20 14:47:50, global, 53, [FW NAME], [FW IP], traffic, traffic log, trust, (NULL), 10.1.1.20, 1725, 82.2.19.2, 2383, untrust, (NULL), 84.5.78.4, 80, 84.53.178.64, 80, tcp, global, 53, [FW NAME], fw/vpn, 4, accepted, info, no, Creation, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0, 0, 1, no, 0, Not Set, sos") + message = mt.render(mark="<134>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:nsm\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# THE LOG SAMPLE BELOW IS IMPLIED FROM THE JUNIPER DOCS; need to obtain a real sample. +# <134> Aug 02 14:45:04 10.0.0.1 65.197.254.193 20090320, 17331, 2009/03/20 14:47:45, 2009/03/20 14:47:50, global, 53, [IDP NAME], [IDP IP], predefined, rule, trust, (NULL), 10.1.1.20, 1725, 82.2.19.2, 2383, untrust, (NULL), 84.5.78.4, 80, 84.53.178.64, 80, tcp, global, 53, [IDP NAME], fw/vpn, 4, accepted, info, no, Creation, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0, 0, 1, no, 0, Not Set, sos +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_nsm_idp_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} 65.197.254.193 20090320, 17331, 2009/03/20 14:47:45, 2009/03/20 14:47:50, global, 53, [IDP NAME], [IDP IP], predefined, rule, trust, (NULL), 10.1.1.20, 1725, 82.2.19.2, 2383, untrust, (NULL), 84.5.78.4, 80, 84.53.178.64, 80, tcp, global, 53, [IDP NAME], fw/vpn, 4, accepted, info, no, Creation, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0, 0, 1, no, 0, Not Set, sos") + message = mt.render(mark="<134>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:nsm:idp\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <23> Apr 24 12:30:05 cs-loki3 RT_IDP: IDP_ATTACK_LOG_EVENT: IDP: at 1303673404, ANOMALY Attack log <64.1.2.1/48397->198.87.233.110/80> for TCP protocol and service HTTP application NONE by rule 3 of rulebase IPS in policy Recommended. attack: repeat=0, action=DROP, threat-severity=HIGH, name=HTTP:INVALID:MSNG-HTTP-VER, NAT <46.0.3.254:55870->0.0.0.0:0>, time-elapsed=0, inbytes=0, outbytes=0, inpackets=0, outpackets=0, intf:trust:fe-0/0/2.0->untrust:fe-0/0/3.0, packet-log-id: 0 and misc-message - +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail + +def test_juniper_idp_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} RT_IDP: IDP_ATTACK_LOG_EVENT: IDP: at 1303673404, ANOMALY Attack log <64.1.2.1/48397->198.87.233.110/80> for TCP protocol and service HTTP application NONE by rule 3 of rulebase IPS in policy Recommended. attack: repeat=0, action=DROP, threat-severity=HIGH, name=HTTP:INVALID:MSNG-HTTP-VER, NAT <46.0.3.254:55870->0.0.0.0:0>, time-elapsed=0, inbytes=0, outbytes=0, inpackets=0, outpackets=0, intf:trust:fe-0/0/2.0->untrust:fe-0/0/3.0, packet-log-id: 0 and misc-message -") + message = mt.render(mark="<23>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:junos:idp\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <23> Nov 18 09:56:58 INTERNET-ROUTER RT_FLOW: RT_FLOW_SESSION_CREATE: session created 192.168.1.102/58662->8.8.8.8/53 junos-dns-udp 68.144.1.1/55893->8.8.8.8/53 TRUST-INET-ACCESS None 17 OUTBOUND-INTERNET-ACCESS TRUST INTERNET 6316 N/A(N/A) vlan.192 +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail + +def test_juniper_firewall_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} RT_FLOW: RT_FLOW_SESSION_CREATE: session created 192.168.1.102/58662->8.8.8.8/53 junos-dns-udp 68.144.1.1/55893->8.8.8.8/53 TRUST-INET-ACCESS None 17 OUTBOUND-INTERNET-ACCESS TRUST INTERNET 6316 N/A(N/A) vlan.192") + message = mt.render(mark="<23>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:junos:firewall\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <23> Feb 27 15:00:00 vpn-001 Juniper: 2013-02-27 15:00:00 - ive - [000.000.000.000] SAMPLE::xxx@xxx.xxx(Users)[] - Session timed out for xxx@xxx.xxx.xxx/Users (session:00000000) due to inactivity (last access at 13:59:31 2013/02/27). Idle session identified during routine system scan. +# <23> Feb 27 15:00:00 vpn-001 Juniper: 2013-02-27 15:00:00 - ive - [000.000.000.000] SAMPLE::xxx@xxx.xxx(Users)[User_Role] - Remote address for user xxx@xxx.xxx/Users changed from 000.000.000.000 to 000.000.000.000. Access denied. +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail + +def test_juniper_sslvpn_standard(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} Juniper: {% now 'utc', '%Y-%m-%d %H:%M:%S' %} - ive - [000.000.000.000] SAMPLE::xxx@xxx.xxx(Users)[User_Role] - Remote address for user xxx@xxx.xxx/Users changed from 000.000.000.000 to 000.000.000.000. Access denied.") + message = mt.render(mark="<23>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"juniper:sslvpn\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 + +# <23> Mar 18 17:56:52 [FW IP] [FW Model]: NetScreen device_id=netscreen2 [Root]system-notification-00257(traffic): start_time="2009-03-18 16:07:06" duration=0 policy_id=320001 service=msrpc Endpoint Mapper(tcp) proto=6 src zone=Null dst zone=self action=Deny sent=0 rcvd=16384 src=21.10.90.125 dst=23.16.1.1 +@flaky(max_runs=3, min_passes=2) +# @pytest.mark.xfail +def test_juniper_netscreen(record_property, setup_wordlist, get_host_key, setup_splunk): + host = get_host_key + + mt = env.from_string( + "{{ mark }} {% now 'utc', '%b %d %H:%M:%S' %} {{ host }} ns204: NetScreen device_id=netscreen2 [Root]system-notification-00257(traffic): start_time=\"2009-03-18 16:07:06\" duration=0 policy_id=320001 service=msrpc Endpoint Mapper(tcp) proto=6 src zone=Null dst zone=self action=Deny sent=0 rcvd=16384 src=21.10.90.125 dst=23.16.1.1\n") + message = mt.render(mark="<23>", host=host) + + sendsingle(message) + + st = env.from_string("search index=main host=\"{{ host }}\" sourcetype=\"netscreen:firewall\" | head 2") + search = st.render(host=host) + + resultCount, eventCount = splunk_single(setup_splunk, search) + + record_property("host", host) + record_property("resultCount", resultCount) + record_property("message", message) + + assert resultCount == 1 \ No newline at end of file