Files
26ce12f7e3 🤖 chore: adopt Renovate for automated dependency updates (#330)
* ⬆️ bump example image versions to latest stable

Align every docker-compose and Helm-values example on the same set:
- Traefik       v3.0.0 / v3.5.0 → v3.7.1
- Crowdsec      v1.6.1-2 / v1.6.8 / latest → v1.7.8
- Plugin pin    v1.3.0 / v1.4.5 / v1.5.0 → v1.6.0

No env / volume changes needed: every Crowdsec example already mounts
/var/lib/crowdsec/data, so the v1.7 strict volume check is already
satisfied (CROWDSEC_BYPASS_DB_VOLUME_CHECK is only required when
running without persistence, as in the E2E suite).

* 🤖 chore: adopt Renovate (weekly, self-hosted) to replace manual version bumps

Automate the kind of bump this PR did by hand. Renovate covers what Dependabot
could not reach here:

- example docker-compose image tags (traefik / crowdsec) — native manager;
- the plugin self-pin (`experimental.plugins.bouncer.version=` in compose args
  and `version:` in the Traefik Helm values) — customManager, github-tags;
- the Crowdsec/Traefik image tags in the Helm values (no `repository` key, so
  matched by file) — customManager, docker;
- the pinned Traefik binary in the e2e mock suite (`TRAEFIK_VERSION`) —
  customManager, github-releases;
- go.mod + GitHub Actions — native managers (this is why we drop Dependabot:
  running both would open duplicate PRs).

Runs weekly via a self-hosted workflow (Mondays 04:00 UTC, plus manual
dispatch). Needs a RENOVATE_TOKEN secret (documented in the workflow). Renovate
PRs trigger the existing e2e CI, so a Traefik/Crowdsec bump is validated to
actually boot and bounce before merge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* 🔒 ci: pin Go to 1.22 (yaegi ceiling) and cap Renovate's Go updates

The plugin is interpreted by yaegi, bundled in Traefik. Even the latest Traefik
(v3.7.1) ships yaegi v0.16.1, which only supports Go 1.22 — so the plugin's real
ceiling is Go 1.22 on every current Traefik, regardless of the Go version
Traefik itself is built with.

- main.yml: build/test on Go 1.22 (was 1.23) so `go build`/`go test` reject
  newer stdlib early; yaegi v0.16.1 stays the required yaegi_test guard.
- renovate.json: cap the go.mod `go`/`toolchain` directive at `<1.23` so
  Renovate keeps deps/actions/toolchain current but never pushes the plugin
  past what yaegi supports. Raise the cap when Traefik ships a newer yaegi.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* 🐛 ci(renovate): stop ignoring examples/ and tests/ so custom managers run

config:recommended ships a default ignorePaths that excludes **/examples/**
and **/tests/** (and **/vendor/**). That silently disabled 4 of the 5 custom
managers and all example/helm coverage this PR adds — Renovate only saw the
root docker-compose, go.mod and workflows.

Override ignorePaths to keep only vendor/node_modules. Verified via
`renovate --platform=local --dry-run=full`: package files detected go from
7 -> 32, and every custom manager now extracts its dep (plugin self-pin
across 11 compose files, traefik/crowdsec helm tags, e2e TRAEFIK_VERSION pin).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

*  chore: drop one-time example version bumps, let Renovate own them

The manual version catch-up across the example docker-compose files and the
Helm values is now redundant: Renovate (this PR) covers all of them via its
native docker-compose/docker managers plus the custom managers for the plugin
self-pin and the e2e Traefik binary. Reverting these files to keep the PR a
clean "adopt Renovate" change; Renovate will open the bump PRs itself.

Note: examples/tls-auth uses crowdsecurity/crowdsec:latest again — Renovate
does not pin rolling tags, so that one stays floating unless pinned separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* 📌 examples(tls-auth): pin crowdsec to v1.6.8 instead of :latest

Rolling `latest` tags aren't reproducible and Renovate can't manage them.
v1.6.8 is already the crowdsec tag used in the root docker-compose files and,
unlike the `-2` build-suffixed tags, Renovate bumps it (→ v1.7.8).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* 📌 examples: normalize crowdsec v1.6.1-2 -> v1.6.8 so Renovate can manage it

Renovate's docker versioning won't advance a build-suffixed tag (v1.6.1-2) to
a clean release (v1.7.8), so those 8 examples would have stayed frozen. v1.6.8
is already used in the root compose files and Renovate bumps it. Also updated
the captcha README snippet to match its compose.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* 🍱 group all + no dashboard + branch prefix

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: maxlerebourg <maxlerebourg@gmail.com>
2026-07-03 09:22:14 +02:00

162 lines
5.1 KiB
Markdown

# Example
## Enabling catpcha response from crowdsec
Crowdsec support 3 remediations solutions `ban`, `captcha`, and `throttle`.
This plugins support the `ban` and `captcha` remediation.
### Traefik configuration
The minimal configuration is defined below.
For now 3 captcha providers are supported:
- [hcaptcha](https://www.hcaptcha.com/)
- [recaptcha](https://www.google.com/recaptcha/about/)
- [turnstile](https://www.cloudflare.com/fr-fr/products/turnstile/)
```yaml
labels:
# Choose captcha provider
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaProvider=hcaptcha"
# Define captcha site key
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaSiteKey=FIXME"
# Define captcha secret key
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaSecretKey=FIXME"
# Define captcha grace period seconds
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaGracePeriodSeconds=1800"
# Define captcha HTML file path
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaHTMLFilePath=/captcha.html"
```
The captcha HTML file must be present in the Traefik container (bind mounted or added during a custom build).
It is not directly accessible from Traefik even when importing the plugin, so [download](https://raw.githubusercontent.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/master/captcha.html) it locally to expose it to Traefik.
```yaml
...
traefik:
image: "traefik:v3.0.0"
volumes:
- './captcha.html:/captcha.html'
...
```
### Crowdsec configuration
Crowdsec by default will take the ban action on suspicious activity detected in logs.
To instruct Crowdsec to use captcha remediation, change the `/etc/crowdsec/profiles.yaml`.
2 modes are supported:
- Always return a captcha decision
- Return a captcha decision the first X times and then a ban decision.
The second mode could be used to prevent repeated malicious activity.
More information is available on configuring Crowdsec in the [official documentation](https://docs.crowdsec.net/docs/next/local_api/profiles/captcha_profile/).
```yaml
...
crowdsec:
image: crowdsecurity/crowdsec:v1.6.8
volumes:
# For captcha and ban mixed decision
- './profiles.yaml:/etc/crowdsec/profiles.yaml:ro'
# For captcha only remediation
# - './profiles_captcha_only.yaml:/etc/crowdsec/profiles.yaml:ro'
...
```
## Exemple navigation
We can try to query normally the whoami server:
```bash
curl http://localhost:8000/foo
```
We can try to ban ourself
```bash
docker exec crowdsec cscli decisions add --ip 10.0.0.20 -d 4h --type captcha
```
![image decision captcha](image_decision_captcha.png)
We will see in the browser the captcha validation page:
![image captcha validation](image_captcha_validation.png)
To play the demo environment run:
```bash
make run_captcha
```
> Note, if we are banned with a "ban" decision from crowdsec a captcha will not be asked and you will have to wait for the decision to expire or remove it manually.
```bash
docker exec crowdsec cscli decisions add --ip 10.0.0.10 -d 10m --type ban
```
## Captcha Workflow
> Context: The user has no decision attached to his IP
```mermaid
sequenceDiagram
participant User
participant TraefikPlugin
User->>TraefikPlugin: Can I access that webpage
create participant PluginCache
TraefikPlugin-->>PluginCache: Does the user IP has a crowdsec decision ?
destroy PluginCache
PluginCache-->>TraefikPlugin: Nothing, all good!
destroy TraefikPlugin
TraefikPlugin->>Webserver: Forwarding this HTTP Request from User
Webserver->>User: HTTP Response
```
> Context: The user has a captcha decision attached to his IP
```mermaid
sequenceDiagram
participant User
participant TraefikPlugin
User->>TraefikPlugin: Can I access that webpage
create participant PluginCache
TraefikPlugin-->>PluginCache: Does the User IP has a Crowdsec Decision ?
PluginCache-->>TraefikPlugin: Yes a Catpcha Decision
TraefikPlugin->>User: Please complete this captcha
User->>TraefikPlugin: Fine, done!
create participant ProviderCaptcha
TraefikPlugin-->>ProviderCaptcha: Is the validation OK ?
destroy ProviderCaptcha
ProviderCaptcha-->>TraefikPlugin: Yes
TraefikPlugin-->>PluginCache: Set the User IP Clean for captchaGracePeriodSeconds
destroy PluginCache
PluginCache-->>TraefikPlugin: Done
destroy TraefikPlugin
TraefikPlugin->>Webserver: Forwarding this HTTP Request from User
Webserver->>User: HTTP Response
```
> Context: The user has a ban decision attached to his IP
```mermaid
sequenceDiagram
participant User
participant TraefikPlugin
User->>TraefikPlugin: Can I access that webpage
create participant PluginCache
TraefikPlugin-->>PluginCache: Does the User IP has a Crowdsec Decision ?
destroy PluginCache
PluginCache-->>TraefikPlugin: Yes a ban Decision
TraefikPlugin->>User: No, HTTP 403
```
## Captcha Configuration:
- Recaptcha
Choose v2 (challenge) and configure the domain to protect:
![Recaptcha image](image_recaptcha.png)
- Turnstile
TODO
- Hcatpcha
TODO