Files
crowdsec-bouncer-traefik-pl…/examples/custom-captcha/README.md
maxlerebourg 4ab4f3f183 Transform banTemplate to add blocking reason and client IP (#290)
*  Transform banTemplate to add blocking reason

* 🍱 fix test

* 🍱 fix lint

* 🍱 fix test

* 🍱 fix lint

* 🍱 fix lint

* 🍱 add doc and fix lint

* 🍱 fix lint

* 🍱 fix lint

* 🍱 fix lint

* 🍱 fix lint

* 🍱 fix lint

* 🍱 lint html

* 🍱 fix comments + fix wicketpeeker readme

* 🍱 Give ClientIP in ban page

* 🍱 fix test
2025-11-15 10:42:14 +01:00

2.7 KiB

Example

Read the example captcha before this, to better understand what is done here.

Traefik configuration

The minimal configuration is defined below to implement custom captcha.
This documentation use https://github.com/a-ve/wicketkeeper, a self-hosted captcha provider that have a similar API than big providers.

Minimal API requirement:

  • the JS file URL to load the captcha on the served captcha.html

  • the HTML className to tell to the JS where to display the challenge

  • the verify URL endpoint to send the field response from the captcha with content-type: application/x-www-form-urlencoded

  • the name of the field when you POST the resolved captcha to Traefik

  • the JS file need to respect the data-callback on the div that contains the captcha if you use our template, but you can customize it by your side

  traefik:
    ...
    labels:
      # Choose captcha provider
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaProvider=custom"
      # Define captcha grace period seconds
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaGracePeriodSeconds=1800"
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaCustomJsURL=http://captcha.localhost:8000/fast.js"
      # Inside Traefik container the plugin must be able to reach wicketkeeper service so we can go through a Traefik localhost
      # domain which would resolve traefik itself and the port for the dashboard
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.CaptchaCustomValidateURL=http://wicketkeeper:8080/v0/siteverify"
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.CaptchaCustomKey=wicketkeeper"
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.CaptchaCustomResponse=wicketkeeper_solution"
      # Define captcha HTML file path
      - "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaHTMLFilePath=/captcha.html"
wicketkeeper:
  image: ghcr.io/a-ve/wicketkeeper:latest
  user: root
  ports:
    - "8080:8080"
  environment:
    - LISTEN_PORT=8080
    - REDIS_ADDR=redis:6379
    - DIFFICULTY=4
    - ALLOWED_ORIGINS=*
    - PRIVATE_KEY_PATH=/data/wicketkeeper.key
  volumes:
    - ./data:/data
  depends_on:
    - redis
redis:
  image: redis/redis-stack-server:latest
<div id="captcha" class="{{ .FrontendKey }}" data-sitekey="{{ .SiteKey }}" data-callback="captchaCallback" data-challenge-url="http://captcha.localhost:8000/v0/challenge">

Exemple navigation

We can try to query normally the whoami server:

curl http://localhost:8000/foo

We can try to ban ourself and retry.

docker exec crowdsec cscli decisions add --ip 10.0.0.20 -d 10m --type captcha

To play the demo environment run:

make run_custom_captcha