Elastalert: Is it possible to create alerts combining events and the result of a triggered alert?

Created on 18 May 2017  Â·  26Comments  Â·  Source: Yelp/elastalert

Hi,
I'm starting to use the tool and would like to know if it's possible to create rules through levels. Eg, when a particular alert is triggered and a specific event occurs, you can filter and combine these two events so that another alert is triggered.

Most helpful comment

This not a "feature" necessarily, but since Elastalert logs all alerts into Elasticsearch, you can create a meta rule that will trigger when other alerts occur.

Say you have rule1 and rule2, and you want to alert when both rule1 and rule2 have fired within 30 minutes of each other. You can create a rule3:

name: rule3
type: cardinality
cardinality_field: rule_name
max_cardinality: 1
filter:
 - terms:
     rule_name:
      - rule1
      - rule2
 - term:
      alert_sent: true
index: elastalert_status
timeframe:
  minutes: 30

We use cardinality rule so that when there are two unique values of rule_name, out of the two possibilities in the filter, we trigger an alert.

Eventually I'd like to make this into a easy supported feature and not this hacky method.

All 26 comments

This not a "feature" necessarily, but since Elastalert logs all alerts into Elasticsearch, you can create a meta rule that will trigger when other alerts occur.

Say you have rule1 and rule2, and you want to alert when both rule1 and rule2 have fired within 30 minutes of each other. You can create a rule3:

name: rule3
type: cardinality
cardinality_field: rule_name
max_cardinality: 1
filter:
 - terms:
     rule_name:
      - rule1
      - rule2
 - term:
      alert_sent: true
index: elastalert_status
timeframe:
  minutes: 30

We use cardinality rule so that when there are two unique values of rule_name, out of the two possibilities in the filter, we trigger an alert.

Eventually I'd like to make this into a easy supported feature and not this hacky method.

Amazing feature ! I don't think so but would it be possible to use the same query_key between the 2 alerts into the third alert to correlate the events ?

I think this is possible with enhancement but seems quick and dirty:
query_key : username
Alert_1 => enhancement (write username in a file)
Alert_2 => enhancement (write username in a file)
Alert_3 with rule given above => enhancement (check if username is in file_1 and file_2)

Or maybe there is another way to retrieve the query_key (username field) for Alert_1 and Alert_2.

You might be able to do this without an enhancement. The value of the query_key field should always be saved as part of the "match_body" field. Try using

query_key: match_body.<key>

where is the query_key from the other two alerts.

If you're using use_terms_query, I think it will be match_body.key literally.

It works as expected @Qmando . Thanks a lot !

Do you think that we could introduce a chronology option between the events? For example :

IF rule2 has trigggered AFTER rule1 ----> raise rule3

Once this turns into a real feature, we can add that.

However, using this method, you'd need to write an enhancement probably.

Maybe you could leverage the fact that the "match" contains data from the 2nd event. Though, you may accidentally ignore if the sequence of events goes B, A, B. As the "A" event will trigger the match and then the next "B" might not. Something like:

class ThisAfterThat(BaseEnhancement):
    def process(self, matches):
        if match[0]['rule_name'] == 'first_rule_name':
            raise DropMatchException

@Qmando I tried your solution but it looks like the enhancement can't find the rule_name:

elastalert_1     | ERROR:root:Traceback (most recent call last):
elastalert_1     |   File "/opt/elastalert/elastalert/elastalert.py", line 1181, in alert
elastalert_1     |     return self.send_alert(matches, rule, alert_time=alert_time)
elastalert_1     |   File "/opt/elastalert/elastalert/elastalert.py", line 1233, in send_alert
elastalert_1     |     enhancement.process(match)
elastalert_1     |   File "elastalert_modules/ThisAfterThat.py", line 13, in process
elastalert_1     |     if match[0]['rule_name'] == 'WinEvent_Success_Authentication':
elastalert_1     | KeyError: 0

Here is the rule :

name: "##Combine_alerts_Test"
type: cardinality
cardinality_field: rule_name
max_cardinality: 1
filter:
 - terms:
    rule_name:
      - "##AD_Account_BruteForce"
      - "WinEvent_Success_Authentication"
 - term:
      alert_sent: true

query_key: match_body.TargetUserName
index: elastalert_status
buffer_time:
    minutes: 5
timeframe:
  minutes: 5
match_enhancements:
- "elastalert_modules.ThisAfterThat.ThisAfterThat"

Here is the enhancement :

from elastalert.enhancements import BaseEnhancement, DropMatchException
from elasticsearch.client import Elasticsearch

class ThisAfterThat(BaseEnhancement):
    def process(self, match):
        if match[0]['rule_name'] == 'WinEvent_Success_Authentication':
            raise DropMatchException

The two rule ##AD_Account_BruteForce and WinEvent_Success_Authentication have well triggered an alert, so I'm asking if this is a module issue ?

(the rule works well without the enhancement, but I would like to introduce a chronology option)

Thanks for your help ! :-)

-- if match[0]['rule_name'] == 'WinEvent_Success_Authentication':
++ if match['rule_name'] == 'WinEvent_Success_Authentication':

Hello @Qmando, thanks for your response !

I thaught [0] was used for the chronology -> I mean raise DropMatchException ONLY IF the first alert which trigg is 'WinEvent_Success_Authentication'.

I removed [0] and made a test but now the alert trigg whatever is the alert chronology...

To summarize :

The combine alert must trigg only if the order of the alerts is A followed by B and not B followed by A

Do you think we can figure it out ?

Hm I think this should still work. The "match" is always the event that triggers the alert and should therefore be the second event chronologically. You get alerts both when both orderings happen?

Yes. With or without the enhancement, the combine alert trigg

@satishdsgithub : Your question is not related to this topic. This is not smart . Remove this !!

This is an awesome hack, but I've faced with a problem of combining "frequency" with "percentage_match" while using query_key. The problem is that "elastalert_status" receives "match_body.key_name" for "frequency" and "match_body.key_name.keyword" for "percentage_match", so it's impossible to match them in cardinality.

That's a good point. Probably the easiest and least disruptive way to fix this would be to add an option to rename or copy arbitrary fields to some new alias. Something like

rename_fields:
  key_name.keyword: key_name

Though, I'd also like to eventually support this as a real feature, and not have to rely on this cardinality hack. I'll keep this in mind, and would accept pull requests.

@Qmando I have a similar issue where i write two alerts(metric aggregation) and based on the difference between the two aggregated values need to trigger an alert. Any possible way to get it done

@Qmando I'm facing a similar issue, and I have created a new question for it in here: https://github.com/Yelp/elastalert/issues/1939

What if you need to define a rule3, but you don't want to be triggering rule1 and rule2 on their own? You just want to fire rule3 when rule1 and rule2 satisfy a given condition at a given period of time.

Is that possible?

@Qmando you also mentioned that, in order to correlate alarms you can do the following:

You might be able to do this without an enhancement. The value of the query_key field should always be saved as part of the "match_body" field. Try using

I tried looking at the alarm in the elast alert index, but I cannot find any fields called match_body, Where should it be stored?

Thank you!.

@lucasalvarezlacasa I could solve the issue by triggering a dummy alert for the other two rules which is a "command" alert type which executes "echo" command to /dev/null of the linux File system.

The rule3 can use frequency /flatline rule which matches when rule1 or rule2 occurs by querying elastalert_status index

@lucasalvarezlacasa I could solve the issue by triggering a dummy alert for the other two rules which is a "command" alert type which executes "echo" command to /dev/null of the linux File system.

The rule3 can use frequency /flatline rule which matches when rule1 or rule2 occurs by querying elastalert_status index

Why did you use this approach instead of the one mentioned by @Qmando before?

I guess u are asking abt the approach of using match_body? If so then my answer is I infact used the same approach. From what I understood, the field match_body is present when an alert is triggered. So, in order to serve my purpose of having an alert but without any info or overhead i chose that way

Yeah exactly, the approach worked :).

Do you know how to force a certain order between the alarms provided in the greater alarm? Let's say I have a ruleA that is triggered when rule1, rule2 and rule3 are fired in the last x minutes.

Is there a way to say that I want to fire ruleA only if rule1 occurred before rule2 and rule2 before rule3?
I would need to enforce a certain order between them.

Thank you!.

You will be needing to write a custom rule with your own logic of when to
match the rule based on time stamp of rule 1, rule 2 rule 3

regards,
tarun

On Thu, Oct 4, 2018 at 8:20 PM Lucas Alvarez Lacasa <
[email protected]> wrote:

Yeah exactly, the approach worked :).

Do you know how to force a certain order between the alarms provided in
the greater alarm? Let's say I have a ruleA that is triggered when rule1,
rule2 and rule3 are triggered in the last x minutes.

Is there a way to say that I want to fire ruleA only if rule1 happened
before rule2 and rule2 before rule3?
I would need to enforce a certain order between them.

Thank you!.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Yelp/elastalert/issues/1108#issuecomment-427048321,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AnvIwx26NwnMJY3RlZFs6ocr9GGFVpNkks5uhiAegaJpZM4NfkRo
.

--
The content of this e-mail is confidential and is intended solely for the
use of the individual or entity to whom it is addressed. If you have
received this e-mail by mistake, please reply to this e-mail and follow
with its deletion. If you are not the intended recipient, please note that
it shall be considered unlawful to copy, forward or in any manner reveal
the contents of this e-mail or any part thereof to anyone. Although
Freshworks has taken reasonable precautions to ensure no malware is present
in this e-mail, Freshworks cannot accept responsibility for any loss or
damage arising from the use of this e-mail or attachments.

@sivatarunp Can you provide me a sample with that? Do you know if you can do the same thing with an enhancement?
Thanks!.

@Trustys Have you figured out how to implement this functionality? I'm trying to replicate exactly the same thing.

Thanks!.

@Qmando How many rules can we take in rule_name :

filter:

  • terms:
    rule_name:

    • rule1

    • rule2

    • rule3

    • rule4

    • rule5

Will this work ?

Hi @Qmando I am facing the following problem while correlating 3 rules with cardinality rule. My situation is the following: I want the R4 (cardinality) to trigger when R1, R2 and R3 occur. It works perfectly when the 3 of them are triggering, but if one of them stops, R4 still triggers for the other 2.
I don't know how to force that only triggers only if the 3 rules are occurring.

Here my R4-cardinality rule:

```
type: cardinality
cardinality_field: rule_name
max_cardinality: 1

index: elastalert_status
timeframe:
# hours: 1
minutes: 3

aggregation:
minutes: 2
filter:

  • terms:
    rule_name: [r2_1_redmov, r2_2_wifi, r2_3_ids]

````

Thank you very much!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

serialdoom picture serialdoom  Â·  3Comments

shortstack picture shortstack  Â·  3Comments

tkumark picture tkumark  Â·  3Comments

MaximilianKaltner picture MaximilianKaltner  Â·  3Comments

JeffAshton picture JeffAshton  Â·  3Comments