Duration_expr and exponentiation

Hello,

I try to create exponentially growing ban times like: 2^(# of alerts) * 10m.

Reading through the documentation I thought I can use the expressions from [ antonmedv/expr. But unfortunalety

duration_expr: "Sprintf('%dm', ( 2 ** GetDecisionsCount(Alert.GetValue())) * 10)"

results in:

time="15-10-2022 08:08:06" level=error msg="while pushing to api : failed sending alert to LAPI: http code 500, invalid body: unexpected end of JSON input" 
time="15-10-2022 08:08:07" level=warning msg="Failed to parse expr duration result '%!d(float64=0)m'" name=default_ipv4_remediation type=profile 
time="15-10-2022 08:08:07" level=warning msg="client 127.0.0.1 error : runtime error: invalid memory address or nil pointer dereference" 
time="15-10-2022 08:08:07" level=warning msg="stacktrace written to /tmp/crowdsec-crash.525257133.txt, please join to your issue"

Any hints on how I can achieve this? Thanks a lot!

Since %d is only used for int’s the POW returns a float64 so try
duration_expr: "Sprintf('%vm', ( 2 ** GetDecisionsCount(Alert.GetValue())) * 10)"
OR
duration_expr: "Sprintf('%fm', ( 2 ** GetDecisionsCount(Alert.GetValue())) * 10)"

As you can see from crowdsec log it states !%d(float64=0) which basically means type mismatch %v is basically a generic, however, it shouldn’t be used as if we change the default print for float64’s it may affect this

More info: fmt package - fmt - Go Packages

Thanks @iiAmLoz !

I choose to use duration_expr: "Sprintf('%dm', GetDecisionsCount(Alert.GetValue()) * GetDecisionsCount(Alert.GetValue()) * 10)" to avoid any issues in future.

Worth pointing out that:

  • the expression doesn’t need to be in quotes
  • ** or Pow or math.Pow won’t work because they’re not available in the expression / invalid
  • best to put it at the end of the file to avoid causing an error

I think, with this, for the first detection, the ban would be zero minutes? As the previous decision count on the 1st detection will be 0?

(0 x 0) x 10 ?

You need the +1 so it is at least:

(((0 x 0) +1) x10)

In my case, using hours and multiplying x4:

duration_expr: Sprintf('%dh', (GetDecisionsCount(Alert.GetValue()) * GetDecisionsCount(Alert.GetValue()) + 1) * 4)

So we then get:

1st - 4 hour (zero prior decision count)
2nd - 8 hour (1 prior decision count)
3rd - 20 hour (2 prior decision count)
4th - 40 hour (3 prior decision count)