billmurrin / graylog-plugin-slookup-function

Stream Lookup function for GrayLog2 Pipeline Processor
GNU General Public License v3.0
14 stars 4 forks source link

Pipeline processor crashing #9

Open jasonkeller opened 6 years ago

jasonkeller commented 6 years ago

So I've written a pipeline rule attempting to use this plugin for conditionals on additional processing, however it seems it's crashing the pipeline processor and dropping messages. It's supposed to additionally tag a message if the same fileHash value is seen in a previous message in the last minute with a different destinationHostName value (meaning we see the same file detection on two different machines within a minute).

rule "patraps-alert-filehash-1m"
when
    $message.fileHash == slookup("5a5916e3683c3d3c4875ff17", "fileHash", "fileHash", ["fileHash"], "60", "asc")[0] AND NOT
    $message.destinationHostName == slookup("5a5916e3683c3d3c4875ff17", "fileHash", "fileHash", ["destinationHostName"], "60", "asc")[0]
then
    set_field("alert", "security");
    route_to_stream("-security-");
end

I believe these are the error messages relating to this...

2018-01-18T09:33:29.617-06:00 WARN  [ProcessBufferProcessor] Unable to process message <ef13c971-fc64-11e7-bdc6-0050568a5665>: java.lang.ClassCastException: org.graylog.plugins.pipelineprocessor.ast.expressions.MessageRefExpression cannot be cast to org.graylog.plugins.pipelineprocessor.ast.expressions.LogicalExpression
2018-01-18T09:33:36.510-06:00 WARN  [ProcessBufferProcessor] Unable to process message <f3302f81-fc64-11e7-bdc6-0050568a5665>: java.lang.ClassCastException: org.graylog.plugins.pipelineprocessor.ast.expressions.MessageRefExpression cannot be cast to org.graylog.plugins.pipelineprocessor.ast.expressions.LogicalExpression

Syntax checks out in the editor, but is there something amiss with how I'm calling the function? Is it not intended to use this for conditionals in the 'when' section? I'm using 2.0.0 in Graylog 2.4.0 on RHEL7 with OpenJDK 8u131.

billmurrin commented 6 years ago

Per the docs,

Any function that returns a value can be called in the when clause, but it must eventually evaluate to a boolean. For example: we were able to use to_ip in the from firewall subnet since it was being passed to cidr_match, which returns a boolean, but could not use route_to_stream since it doesn’t return a value.

You are clearly trying to evaluate the when to a boolean by using a comparison operator.

Can you test hard-coding an actual string with a hash in it instead of calling slookup? I'm wondering if you get the same error or if it works.

billmurrin commented 6 years ago

@jasonkeller

After some testing on 2.4.0, what you are trying to do should totally work.

Here's a ridiculous rule I created to compare on a winlogbeat_computer_name coming from a Windows Event Log

rule "Log Enrichment - Ascending"
when
    has_field("winlogbeat_computer_name") AND $message.winlogbeat_computer_name == slookup("5a5db2bc15a79f05b3430bbe", "winlogbeat_computer_name", "winlogbeat_computer_name", ["winlogbeat_computer_name"], "30", "desc")[0]
then
    debug("Made it to the then clause");
    //StreamID, Source Field, Destination Field, Return Field(s), Relative Time, Ascending SortOrder
    let system_info = slookup("5a5db2bc15a79f05b3430bbe", "winlogbeat_source_name", "winlogbeat_source_name", ["winlogbeat_computer_name","winlogbeat_event_id","winlogbeat_task"], "60", "desc");
    set_field("winlogbeat_computer_name_new", system_info[0]);
    set_field("winlogbeat_event_id_new", to_string(system_info[1]));
    set_field("winlogbeat_task_new", system_info[2]);
end

My Debug Output in the server log:

2018-01-20_02:35:12.92851 INFO  [Function] PIPELINE DEBUG: Made it to the then clause
2018-01-20_02:35:12.93078 INFO  [Function] PIPELINE DEBUG: Made it to the then clause
2018-01-20_02:35:20.93336 INFO  [Function] PIPELINE DEBUG: Made it to the then clause
2018-01-20_02:35:22.93433 INFO  [Function] PIPELINE DEBUG: Made it to the then clause

Fields being created in output:

winlogbeat_computer_name: BMGMPC
winlogbeat_computer_name_new: BMGMPC
winlogbeat_event_id: 4689
winlogbeat_event_id_new: 4689
winlogbeat_task: Process Termination
winlogbeat_task_new: Process Termination
jasonkeller commented 6 years ago

@billmurrin what OS/Java are you running by chance? I am on RHEL7 and previously had to restrict Java to 8u131 to prevent Graylog from crashing back in 2.3; however in 2.4 in my lab (Ubuntu) it's on 8u151 and appears to not completely crash Graylog. I'm wondering if Java 8u131 that I'm on now in RHEL7 is causing issues with your plugin. I'll have more time Monday hopefully to test.

billmurrin commented 6 years ago

@jasonkeller I tested this out using the GL 2.4.0 OVA. It has java 8u151 and Ubuntu 14.04.5 LTS. Hope that helps.

jasonkeller commented 6 years ago

@billmurrin so here's what I've found so far...

I'm now running Graylog 2.4.1 (updated from 2.4.0 over the weekend); Java has also been updated to 8u161. Thus far if I do a single slookup call like yours in the when clause, it succeeds. However, the moment I add a second one, it still throws the same error...

2018-01-22T15:27:25.888-06:00 WARN  [ProcessBufferProcessor] Unable to process message <0a89cde1-ffbb-11e7-8974-0050568a570f>: org.graylog.plugins.pipelineprocessor.ast.exceptions.FunctionEvaluationException: java.lang.NullPointerException

I'm pretty lost at this point why doing a second lookup in the when clause is failing. It's a bit cumbersome as well that we can't do any variable assignment in the when clause, otherwise I could capture both fields in the same lookup and do the two comparisons against the resulting variable.

jasonkeller commented 6 years ago

@billmurrin any ideas?

jasonkeller commented 6 years ago

@billmurrin I've worked around this for now with a completely separate pipeline with multiple stages (one for each slookup() call).