Skip to content

Commit 700444f

Browse files
Merge branch 'main' into docs/haproxy-spoa-cdn-config
2 parents 761f9b7 + 8a392ec commit 700444f

File tree

7 files changed

+1084
-1664
lines changed

7 files changed

+1084
-1664
lines changed

biome.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"root": true,
3-
"$schema": "https://biomejs.dev/schemas/2.2.0/schema.json",
3+
"$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
44
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false },
55
"files": {
66
"ignoreUnknown": false,
@@ -57,6 +57,9 @@
5757
},
5858
"html": { "formatter": { "selfCloseVoidElements": "always" } },
5959
"css": {
60+
"parser": {
61+
"tailwindDirectives": true
62+
},
6063
"formatter": {
6164
"enabled": true,
6265
"indentStyle": "tab",

crowdsec-docs/docs/expr/other_helpers.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,72 @@ ParseUnix("notatimestamp") -> ""
2020
```
2121
Parses unix timestamp string and returns RFC3339 formatted time
2222

23+
### `AverageInterval(timestamps []time.Time) time.Duration`
24+
25+
Calculates the average interval (time duration) between consecutive timestamps in a slice.
26+
27+
**Use case:** Detecting consistent timing patterns over time, such as slow brute-force attacks or rate anomalies.
28+
29+
**Example:**
30+
31+
```yaml
32+
type: conditional
33+
name: me/slow-http
34+
debug: true
35+
description: "Detect slow HTTP requests returning 404"
36+
filter: "evt.Meta.log_type in ['http_access-log', 'http_error-log'] && evt.Parsed.static_ressource == 'false' && evt.Parsed.verb in ['GET', 'HEAD']"
37+
groupby: "evt.Meta.source_ip + '/' + evt.Parsed.target_fqdn"
38+
capacity: -1
39+
condition: |
40+
len(queue.Queue) >= 3 &&
41+
AverageInterval(map(queue.Queue[-3:], { #.Time })) > duration("5m") &&
42+
all(queue.Queue, #.Meta.http_status == '404')
43+
leakspeed: 1h
44+
labels:
45+
remediation: true
46+
```
47+
48+
In this example, we check if the queue has at least 3 items, compute the average interval between the last 3 requests, and trigger if the average time between requests exceeds 5 minutes and all responses are 404s (indicating a slow scan).
49+
50+
**Notes:**
51+
- Timestamps are automatically sorted internally for correctness
52+
- Requires at least two timestamps
53+
- Useful for detecting consistent behavior patterns over time
54+
55+
### `MedianInterval(timestamps []time.Time) time.Duration`
56+
57+
Calculates the median interval (time duration) between consecutive timestamps in a slice.
58+
59+
**Use case:** Detecting typical timing patterns when intervals vary widely. The median is more robust against outliers than the average, making it ideal for identifying timing anomalies in irregular patterns.
60+
61+
**Example:**
62+
63+
```yaml
64+
type: conditional
65+
name: me/slow-http-median
66+
debug: true
67+
description: "Detect slow HTTP requests returning 404"
68+
filter: "evt.Meta.log_type in ['http_access-log', 'http_error-log'] && evt.Parsed.static_ressource == 'false' && evt.Parsed.verb in ['GET', 'HEAD']"
69+
groupby: "evt.Meta.source_ip + '/' + evt.Parsed.target_fqdn"
70+
capacity: -1
71+
condition: |
72+
len(queue.Queue) >= 5 &&
73+
MedianInterval(map(queue.Queue[-5:], { #.Time })) > duration("10m") &&
74+
all(queue.Queue, #.Meta.http_status == '404')
75+
leakspeed: 1h
76+
labels:
77+
remediation: true
78+
```
79+
80+
In this example, we check if there are at least 5 events in the queue, calculate the median interval between the last 5 requests, and trigger if the median interval exceeds 10 minutes and all responses are 404s.
81+
82+
**Notes:**
83+
- Timestamps are automatically sorted internally for correctness
84+
- Handles both even and odd numbers of intervals correctly
85+
- Requires at least two timestamps
86+
- More robust against outliers compared to `AverageInterval`
87+
- Useful for capturing typical timing patterns in skewed data
88+
2389
## Stash Helpers
2490

2591
### `GetFromStash(cache string, key string)`
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
id: deploy
3+
title: Deploy
4+
sidebar_position: 4
5+
---
6+
7+
:::warning
8+
9+
This documentation mostly focus on installation of custom scenarios. Scenarios from the hub should be installed as a part of the collection, by using `cscli collections install <collection-name>`. Installing scenarios directly with `cscli scenario install <scenario-name>` might lead to unexpected results because of missing dependencies (ie. parsers, enrichers, post-overflows etc.)
10+
11+
:::
12+
13+
14+
## Deployment
15+
16+
### Installation
17+
18+
To deploy a scenario, simply copy it to `/etc/crowdsec/scenarios/`.
19+
20+
### Verification
21+
22+
Use `cscli scenarios list` to view all your installed scenarios:
23+
24+
- `Name` presents the `name` field of the yaml file.
25+
- `Version` represents the version of the scenario according to the hub. Versions increment on upstream changes.
26+
- `Local path` represents the local path to the scenario file.
27+
- `📦 Status` indicates the state:
28+
29+
| Status | Description |
30+
|--------|-------------|
31+
| `✔️ enabled` | Scenario is from the hub and up-to-date |
32+
| `🏠 enabled,local` | This is a custom scenario |
33+
| `⚠️ enabled,tainted` | This is an upstream scenario that has been modified |
34+

0 commit comments

Comments
 (0)