hslatman / caddy-crowdsec-bouncer

A Caddy module that blocks malicious traffic based on decisions made by CrowdSec.
139 stars 4 forks source link

Error: directive 'crowdsec' is not an ordered HTTP handler #24

Closed doums closed 10 months ago

doums commented 10 months ago

Hi, I'm trying to use this module. But I got an error when I try to use the crowdsec directive:

Error: adapting config using caddyfile: directive 'crowdsec' is not an ordered HTTP handler, so it cannot be used here - try placing within a route block or using the order global option

This is how I build my custom caddy image:

FROM caddy:builder-alpine AS builder

RUN xcaddy build\
      --with github.com/caddy-dns/cloudflare\
      --with github.com/mholt/caddy-dynamicdns\
      --with github.com/hslatman/caddy-crowdsec-bouncer/http

FROM caddy:alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

This is my compose file (shortened)

{
  email m@m.m

  dynamic_dns {
    provider cloudflare {env.CLOUDFLARE_API_TOKEN}
    domains {
      mydomain.com
    }
    check_interval 10m
    versions ipv4
    dynamic_domains
  }

  crowdsec {
    api_url host.docker.internal:8080
    api_key xxx
    ticker_interval 15s
    # disable_streaming
    # enable_hard_fails
  }
}

# I have a wildcard domain setup
*.mydomain.com, mydomain.com {
  tls {
    dns cloudflare {env.CLOUDFLARE_API_TOKEN}
  }

  encode gzip
  crowdsec

  # MicroBin
  @microbin host bin.mydomain.com
  handle @microbin {
    reverse_proxy microbin:12345
  }

  // [...] other services handlers
}

Any idea about the issue?

hslatman commented 10 months ago

Hey @doums,

Can you try putting order crowdsec first in your global Caddy options?

doums commented 10 months ago

Hi, yes that seems to fix the issue. But now I have to deal with a new one. As I run caddy in a docker container but crowdsec is running on the host

{"level":"error","ts":1699635582.6078553,"logger":"crowdsec","msg":"auth-api: auth with api key failed return nil response, error: dial tcp 172.17.0.1:8080: i/o timeout","address":"http://host.docker.internal:8080/","error":"auth-api: auth with api key failed return nil response, error: dial tcp 172.17.0.1:8080: i/o timeout"}

In my compose file I expose the localhost host IP into the container using

extra_hosts:
  - "host.docker.internal:host-gateway"

But it seems like crowdsec local API doesn't accept connection from docker container.

EDIT I fixed the issue by changing the server listening URL to 0.0.0.0 in crowdsec config.yaml file. That's a bit dirty, but I couldn't find another solution.

hslatman commented 10 months ago

With CrowdSec on the host, that fix makes sense. Alternatively, listening just on the Docker network interface/IP might also work?

If you don't require CrowdSec on the host, but are also OK with running it as a container, it should be a matter of attaching to the same Docker network.