Sign inSign up

580132/caddy-cloudflare-crowdsec

By 580132

•Updated 8 days ago

🐳 The Caddy Docker image built with the Cloudflare DNS module and CrowdSec bouncers

Image
0

76

580132/caddy-cloudflare-crowdsec repository overview

⁠🐳 caddy-cloudflare-crowdsec

DockerHub GitHub tag (latest SemVer) Docker Build & Release License Dependabot

The Caddy⁠ Docker image with the added

Built for the same platforms as the upstream Caddy project (except Windows, sorry)!

Note

This image does not change anything with original Caddy Docker image except replace the `caddy` binary.
# Docker Hub
docker pull 580132/caddy-cloudflare-crowdsec:latest

# GHCR
docker pull ghcr.io/580132/caddy-cloudflare-crowdsec:latest

⁠Tags

The following tags are the latest available for the 580132/caddy-cloudflare-crowdsec image.

Check the GitHub Tags⁠ for a list of all versions!

⁠Usage

⁠Docker

Since this is built off the official Docker image all of the same Volumes, Environment variables, etc. can be used with this container. Please refer to the official Caddy⁠ Docker image and docs⁠ for more information on using Caddy.

Simply create the container as usual and include your CF_API_TOKEN (email no longer required for API Tokens). We can utilize Caddy's support for Environment varaiables⁠ to pass these values into our Caddyfile.

Important

Be sure to create your `Caddyfile` beforehand to avoid Docker startup errors.
docker run --rm -it \
  --name caddy \
  -p 80:80 \
  -p 443:443 \
  -v caddy_data:/data \
  -v caddy_config:/config \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  -e CF_API_TOKEN=UhKLc...JD9jk \
  580132/caddy-cloudflare-crowdsec:latest

If you prefer docker-compose you can use the provided docker-compose.yml⁠ after updating it with your CF_API_TOKEN.

docker compose up
⁠Caddy

Set the global acme_dns⁠ directive in your Caddyfile

{
  acme_dns cloudflare {env.CF_API_TOKEN}
}

or via JSON

{
  "module": "acme",
  "challenges": {
    "dns": {
      "provider": {
        "name": "cloudflare",
        "api_token": "{env.CF_API_TOKEN}"
      }
    }
  }
}

See the caddy-dns/cloudflare⁠ module and tls⁠ directive for advanced usage.

⁠CrowdSec

The image bundles the CrowdSec bouncer for Caddy⁠, which blocks malicious traffic based on the decisions made by your CrowdSec⁠ Security Engine.

ModuleDirectivePurpose
httpcrowdsecChecks the client IP of incoming HTTP requests against CrowdSec decisions
appsecappsecChecks incoming HTTP requests against the rulesets of a CrowdSec AppSec component
layer4crowdsec (matcher)Matches TCP/UDP IP addresses against the CrowdSec Local API, for non-HTTP traffic

All three share a single Caddy app, so the Local API credentials only have to be configured once in the global options.

⁠Enabling the bouncer

Declare the crowdsec global option, then use the crowdsec directive in your site block:

{
  crowdsec {
    api_url http://crowdsec:8080
    api_key {env.CROWD_SEC_API_KEY}
    ticker_interval 15s
  }
}

example.com {
  route {
    crowdsec
    reverse_proxy localhost:3000
  }
}

The api_key is the value of a bouncer registered on your CrowdSec instance:

docker exec crowdsec cscli bouncers add caddy-bouncer
⁠Configuration options
OptionDescriptionDefault
api_urlThe URL of the CrowdSec Local API.http://127.0.0.1:8080/
api_keyThe API key to authenticate with the Local API.required
disable_streamingFalls back to LiveBouncer mode (queries the API per request).false
ticker_intervalInterval for pulling decisions from the Local API.60s
metrics_intervalInterval for pushing metrics to the Local API.0s (disabled)
enable_caddy_metricsEnables emitting bouncer metrics at Caddy's /metrics endpoint.false
enable_hard_failsCaddy fails to start if the CrowdSec API is unreachable.false
appsec_urlThe URL of the CrowdSec AppSec component.disabled
appsec_max_body_bytesMaximum request body size sent to AppSec.0 (full request)
appsec_max_timeoutMaximum time for a request to the AppSec component.2s
appsec_fail_openIgnore AppSec component connection errors.false
enable_caddy_errorPropagates decisions as Caddy errors, to allow custom error pages.false

Warning

When enabling `enable_caddy_error`, make sure `handle_errors` routes are strictly static, to avoid resource exhaustion (DoS).
⁠AppSec

If you run a CrowdSec AppSec⁠ component, point the bouncer at it and add the appsec directive:

{
  crowdsec {
    api_url http://crowdsec:8080
    api_key {env.CROWD_SEC_API_KEY}
    appsec_url http://crowdsec-appsec:7422
  }
}

example.com {
  route {
    crowdsec
    appsec
    reverse_proxy localhost:3000
  }
}
⁠Layer 4

The Layer 4 matcher blocks TCP and UDP traffic by IP address, using the caddy-l4⁠ app:

{
  crowdsec {
    api_url http://crowdsec:8080
    api_key {env.CROWD_SEC_API_KEY}
  }

  layer4 {
    :443 {
      @crowdsec crowdsec
      route @crowdsec {
        proxy {
          upstream localhost:8443
        }
      }
    }
  }
}
⁠Client IP

The bouncer relies on Caddy's native client IP detection. Caddy uses the X-Forwarded-For header by default, so if you run behind a proxy or CDN you must configure the trusted_proxies⁠ global directive, otherwise every request will be checked against the proxy's IP address.

{
  trusted_proxies static private_ranges
}
⁠Blocked request details

The HTTP and AppSec handlers record why a request was blocked, so matchers and logs can tell blocks apart:

VariableDescriptionExamples
{http.vars.crowdsec.module}The handler that blocked the request.http, appsec
{http.vars.crowdsec.remediation}The remediation that was applied.ban, captcha, throttle
{http.vars.crowdsec.origin}The origin of the decision.appsec, crowdsec, lists:foo
{http.vars.crowdsec.duration}The duration of the decision.3h59m58s
handle_errors {
  log_append blocked-by {http.vars.crowdsec.module}
}
⁠Runtime utilities

Building Caddy with the bouncer also enables the caddy crowdsec command, which talks to the Caddy Admin API to inspect the integration:

caddy crowdsec health    # check the integration health
caddy crowdsec info      # show runtime information
caddy crowdsec ping      # ping the Local API endpoint
caddy crowdsec check <IP> # check whether an IP is banned

Note

The `caddy crowdsec` command is currently experimental.
⁠Creating a Cloudflare API Token

You can generate a Cloudflare API token via the Cloudflare web console using the following steps:

  1. Login to your Dashboard⁠
  2. Go to Account Profile⁠ > API Tokens⁠
  3. Click "Create token" (Use the "Create Custom Token" option)
  4. Grant the following permissions:
    • Zone > Zone > Read
    • Zone > DNS > Edit

⁠Building

You can easily build the Docker image locally by doing

docker build -t caddy-cloudflare-crowdsec .

If you prefer docker-compose you can use the provided docker-compose.yml⁠ for building

docker compose build

⁠Container signatures

All container images will be automatically signed via Cosign⁠ using keyless signatures⁠. You can use the following command to verify the integrity of these images yourself.

cosign verify \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp https://github.com/580132/caddy-cloudflare-crowdsec/.github/workflows/ \
  580132/caddy-cloudflare-crowdsec:latest

⁠Contributing

Feel free to contribute and make things better by opening an Issue⁠ or Pull Request⁠.

⁠License

See LICENSE⁠.

Tag summary

Content type

Image

Digest

sha256:53fba11f6…

Size

42.1 MB

Last updated

8 days ago

docker pull 580132/caddy-cloudflare-crowdsec