Skip to content

Commit 01a2da1

Browse files
authored
Merge pull request #899 from crowdsecurity/remediation_sync_intent
clarify intent
2 parents 36f6513 + 5a77ff2 commit 01a2da1

File tree

5 files changed

+136
-5
lines changed

5 files changed

+136
-5
lines changed

crowdsec-docs/docs/appsec/create_rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: create_rules
3-
title: Rules Creation & Testing
3+
title: Creation & Testing
44
sidebar_position: 3
55
---
66

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
id: rules_deploy
3+
title: Deployment
4+
sidebar_position: 81
5+
---
6+
7+
# WAF Rules Deployment
8+
9+
This walkthrough assumes you already wrote and validated a custom AppSec (WAF) rule. We will deploy a concrete example so you can mirror the exact commands on your host.
10+
11+
## Example Rule We Will Deploy
12+
13+
The example blocks any `GET` request whose `user_id` query argument contains non-numeric characters. While you iterate locally, keep it in a working directory as `./block-nonnumeric-user-id.yaml`:
14+
15+
```yaml title="./block-nonnumeric-user-id.yaml"
16+
name: custom/block-nonnumeric-user-id
17+
description: Block GET requests with a non-numeric user_id parameter.
18+
rules:
19+
- and:
20+
- zones:
21+
- METHOD
22+
match:
23+
type: equals
24+
value: GET
25+
- zones:
26+
- ARGS
27+
variables:
28+
- user_id
29+
match:
30+
type: regex
31+
value: "[^0-9]"
32+
labels:
33+
type: exploit
34+
service: http
35+
confidence: 2
36+
spoofable: 0
37+
behavior: "http:exploit"
38+
label: "Non numeric user id"
39+
```
40+
41+
Once the rule behaves as expected, the remaining steps package it for CrowdSec, wire it into the acquisition pipeline, and test it end to end.
42+
43+
## Step 1 — Stage the Rule File
44+
45+
CrowdSec loads AppSec rules from `/etc/crowdsec/appsec-rules/`. Copy your YAML rule into that directory (create a `custom/` subfolder to keep things tidy if you manage several rules):
46+
47+
```bash
48+
sudo install -d -m 750 /etc/crowdsec/appsec-rules/custom
49+
sudo install -m 640 ./block-nonnumeric-user-id.yaml \
50+
/etc/crowdsec/appsec-rules/custom/block-nonnumeric-user-id.yaml
51+
```
52+
53+
Make sure the `name` inside the rule file matches the file name convention you plan to reference (in our example `custom/block-nonnumeric-user-id`).
54+
55+
:::tip
56+
If you run CrowdSec in a container, copy the file into the volume that is mounted at `/etc/crowdsec/appsec-rules/` inside the container.
57+
:::
58+
59+
## Step 2 — Create an AppSec Configuration
60+
61+
An AppSec configuration lists which rules to load and how to handle matches. Create a new file under `/etc/crowdsec/appsec-configs/` that targets your custom rule:
62+
63+
```yaml title="/etc/crowdsec/appsec-configs/custom-block-nonnumeric-user-id.yaml"
64+
name: custom/block-nonnumeric-user-id
65+
default_remediation: ban
66+
inband_rules:
67+
- custom/block-nonnumeric-user-id
68+
# Add outofband_rules or hooks here if needed
69+
```
70+
71+
Key points:
72+
- `name` is how you will reference this configuration from the acquisition file and in logs.
73+
- `inband_rules` (and/or `outofband_rules`) accept glob patterns, so you can load multiple rules with a single entry such as `custom/block-*`.
74+
- During the reload step CrowdSec validates the syntax; if anything is off, the reload fails and the service logs the parsing error.
75+
76+
## Step 3 — Reference the Configuration in the Acquisition File
77+
78+
The AppSec acquisition file (`/etc/crowdsec/acquis.d/appsec.yaml`) controls which configurations are active for the WAF component. Add your configuration to the `appsec_configs` list. Order matters: later entries override conflicting defaults such as `default_remediation`.
79+
80+
```yaml title="/etc/crowdsec/acquis.d/appsec.yaml"
81+
appsec_configs:
82+
- crowdsecurity/appsec-default
83+
- custom/block-nonnumeric-user-id
84+
labels:
85+
type: appsec
86+
listen_addr: 127.0.0.1:7422
87+
source: appsec
88+
```
89+
90+
If you only want to run your custom configuration, remove other entries and keep the list with a single item.
91+
92+
## Step 4 — Reload CrowdSec and Validate the Load
93+
94+
Apply the changes by reloading the CrowdSec service:
95+
96+
```bash
97+
sudo systemctl reload crowdsec
98+
```
99+
100+
If your init system does not support reload, perform a restart instead. Then verify the rule and configuration are active:
101+
102+
```bash
103+
sudo cscli appsec-rules list | grep block-nonnumeric-user-id
104+
sudo cscli appsec-configs list | grep block-nonnumeric-user-id
105+
```
106+
107+
The rule should appear as `enabled`, and the configuration should show up in the list. CrowdSec logs confirm the configuration was loaded without errors.
108+
109+
## Step 5 — Functional Test with `curl`
110+
111+
Trigger the behaviour your rule is meant to catch to ensure it blocks as expected. For the example rule, send a request with a non-numeric `user_id` value:
112+
113+
```bash
114+
curl -i 'http://127.0.0.1/profile?user_id=abc123'
115+
```
116+
117+
A successful block returns an HTTP status such as `403 Forbidden`, and CrowdSec logs a matching alert:
118+
119+
```bash
120+
sudo cscli alerts list -s custom/block-nonnumeric-user-id
121+
```
122+
123+
If the request is not blocked, double-check that the rule `name` matches the pattern in your AppSec configuration, that the acquisition file lists your configuration, and that the CrowdSec service picked up the changes.
124+
125+
## Next Steps
126+
127+
- Add automated regression tests with `cscli hubtest` so future updates do not break the rule.
128+
- Version-control your custom rule and configuration files to keep track of changes.

crowdsec-docs/docs/appsec/rules_syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: rules_syntax
3-
title: Rules syntax
3+
title: Syntax
44
sidebar_position: 8
55
---
66

crowdsec-docs/sidebars.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,9 @@ const sidebarsConfig: SidebarConfig = {
737737
label: "Rules",
738738
items: [
739739
{ type: "doc", id: "appsec/rules_syntax" },
740-
{ type: "doc", id: "appsec/hooks" },
741740
{ type: "doc", id: "appsec/create_rules" },
741+
{ type: "doc", id: "appsec/rules_deploy" },
742+
{ type: "doc", id: "appsec/hooks" },
742743
{ type: "doc", id: "appsec/rules_examples" },
743744
],
744745
},

crowdsec-docs/unversioned/console/remediation_metrics.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ It provides key insights into:
1818
- The blocklist that contribute to remediate malicious traffic
1919

2020
The page is divided into three main sections:
21-
- **Malicious Intents** – A breakdown of attack types associated over time and the total number of attacks prevented.
21+
- **Malicious Intents** – A breakdown of attack types associated with the IPs that your remediation components blocked.
2222
- **Malicious Traffic Dropped/Discarded** – Raw and estimated data showing how much malicious traffic has been dropped by your remediation components.
2323
- **Projected Resources Saved** – An estimate of the resources preserved thanks to traffic being dropped (e.g., storage, bandwidth, log volume).
2424

@@ -30,7 +30,9 @@ At the top of the page, you'll see the **Total Prevented Attacks** for the selec
3030

3131
![Total Prevented Attacks](/img/console/remediation_metrics/rc-metrics-total-prevented-attacks.png)
3232

33-
The **Malicious Intents** section provides a detailed breakdown of the types of attacks that were prevented. These are based on the behavior and typology of IPs remediated by your remediation components, including blocklists and security engines.
33+
The **Malicious Intents** section summarizes what a blocked IP was *likely* attempting (for example spam, scanning, or brute-force), based on behaviour patterns observed across the CrowdSec network. Because these IPs are blocked, we may not have direct evidence of what they tried in **your** environment. Treat the intent as an informed estimate derived from community data rather than a record of actions on your system.
34+
35+
> **Note:** We cannot determine the exact action an IP took against your service. The displayed intent is an estimate inferred from broader network observations.
3436
3537
![Malicious Intents Breakdown](/img/console/remediation_metrics/rc-metrics-malicious-intents.png)
3638

0 commit comments

Comments
 (0)