|
| 1 | +--- |
| 2 | +id: rules_deploy |
| 3 | +title: Custom Rules deployment |
| 4 | +sidebar_position: 81 |
| 5 | +--- |
| 6 | + |
| 7 | +# WAF Rules Deployment |
| 8 | + |
| 9 | +This guide starts once you have already authored and validated a custom AppSec (WAF) rule locally. The steps below focus on packaging that rule so CrowdSec can load it, wiring the configuration into the acquisition pipeline, deploying the files, and finally smoke-testing the result. |
| 10 | + |
| 11 | +## Step 1 — Stage the Rule File |
| 12 | + |
| 13 | +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): |
| 14 | + |
| 15 | +```bash |
| 16 | +sudo install -d -m 750 /etc/crowdsec/appsec-rules/custom |
| 17 | +sudo install -m 640 ./my-virtual-patch.yaml \ |
| 18 | + /etc/crowdsec/appsec-rules/custom/my-virtual-patch.yaml |
| 19 | +``` |
| 20 | + |
| 21 | +Make sure the `name` inside the rule file matches the file name convention you plan to reference (for example `custom/my-virtual-patch`). |
| 22 | + |
| 23 | +:::tip |
| 24 | +If you run CrowdSec in a container, copy the file into the volume that is mounted at `/etc/crowdsec/appsec-rules/` inside the container. |
| 25 | +::: |
| 26 | + |
| 27 | +## Step 2 — Create an AppSec Configuration |
| 28 | + |
| 29 | +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: |
| 30 | + |
| 31 | +```yaml title="/etc/crowdsec/appsec-configs/custom-virtual-patching.yaml" |
| 32 | +name: custom/virtual-patching |
| 33 | +default_remediation: ban |
| 34 | +inband_rules: |
| 35 | + - custom/my-virtual-patch |
| 36 | +# Add outofband_rules or hooks here if needed |
| 37 | +``` |
| 38 | + |
| 39 | +Key points: |
| 40 | +- `name` is how you will reference this configuration from the acquisition file and in logs. |
| 41 | +- `inband_rules` (and/or `outofband_rules`) accept glob patterns, so you can load multiple rules with a single entry such as `custom/my-virtual-patch-*`. |
| 42 | +- Keep file permissions restrictive (`640`) so only the `crowdsec` user can read the file. |
| 43 | +- During the reload step CrowdSec validates the syntax; if anything is off, the reload fails and the service logs the parsing error. |
| 44 | + |
| 45 | +## Step 3 — Reference the Configuration in the Acquisition File |
| 46 | + |
| 47 | +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`. |
| 48 | + |
| 49 | +```yaml title="/etc/crowdsec/acquis.d/appsec.yaml" |
| 50 | +appsec_configs: |
| 51 | + - crowdsecurity/appsec-default |
| 52 | + - custom/virtual-patching |
| 53 | +labels: |
| 54 | + type: appsec |
| 55 | +listen_addr: 127.0.0.1:7422 |
| 56 | +source: appsec |
| 57 | +``` |
| 58 | +
|
| 59 | +If you only want to run your custom configuration, remove other entries and keep the list with a single item. |
| 60 | +
|
| 61 | +## Step 4 — Reload CrowdSec and Validate the Load |
| 62 | +
|
| 63 | +Apply the changes by reloading the CrowdSec service: |
| 64 | +
|
| 65 | +```bash |
| 66 | +sudo systemctl reload crowdsec |
| 67 | +``` |
| 68 | + |
| 69 | +If your init system does not support reload, perform a restart instead. Then verify the rule and configuration are active: |
| 70 | + |
| 71 | +```bash |
| 72 | +sudo cscli appsec-rules list | grep my-virtual-patch |
| 73 | +sudo cscli appsec-configs list | grep virtual-patching |
| 74 | +sudo journalctl -u crowdsec --since "5 minutes ago" | grep appsec |
| 75 | +``` |
| 76 | + |
| 77 | +The rule should appear as `enabled`, and the configuration should show up in the list. CrowdSec logs confirm the configuration was loaded without errors. |
| 78 | + |
| 79 | +## Step 5 — Functional Test with `curl` |
| 80 | + |
| 81 | +Trigger the behaviour your rule is meant to catch to ensure it blocks as expected. For example, if the rule protects `/admin` against a malicious header, you can test from the WAF host: |
| 82 | + |
| 83 | +```bash |
| 84 | +curl -i -H 'X-Foobar-Bypass: 1' \ |
| 85 | + -d 'user_id=123;cat /etc/passwd&do=yes' \ |
| 86 | + http://127.0.0.1/admin |
| 87 | +``` |
| 88 | + |
| 89 | +A successful block returns an HTTP status such as `403 Forbidden`, and CrowdSec logs a matching alert: |
| 90 | + |
| 91 | +```bash |
| 92 | +sudo journalctl -u crowdsec -n 20 | grep "my-virtual-patch" |
| 93 | +``` |
| 94 | + |
| 95 | +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. |
| 96 | + |
| 97 | +## Next Steps |
| 98 | + |
| 99 | +- Add automated regression tests with `cscli hubtest` so future updates do not break the rule. |
| 100 | +- Version-control your custom rule and configuration files to keep track of changes. |
0 commit comments