Skip to content

Added full docker-compose example #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@

This repository contains several examples for using [CrowdSec](https://www.crowdsec.net/) with [Caddy](https://caddyserver.com/) using the [Caddy CrowdSec Bouncer](https://github.com/hslatman/caddy-crowdsec-bouncer)

## Docker-compose

## Description

...

## Examples

..
A full example of a common setup is provided under the `docker-compose` folder.
5 changes: 5 additions & 0 deletions docker-compose/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CLOUDFLARE_API_TOKEN=
CLOUDFLARE_ZONE_ID=
CROWDSEC_LOCAL_API_KEY=
MY_DOMAIN=domain.com
[email protected]
31 changes: 31 additions & 0 deletions docker-compose/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Example with docker-compose

## Setup

1. Update variables in the `.env` file and define your `10.x.x.` subnet values in `docker-compose.yml`. Edit all `~/path` as relevant to your setup.
2. Add the Caddy bouncer, generating an API key with `docker-compose exec crowdsec cscli bouncers add caddy-bouncer`. Store that key in the `.env` file.
3. Run with `docker-compose up --build --force-recreate`.

## Run

## Background

This example shows how to use CrowdSec with Caddy with docker-compose and a common network topology (similar to [this](https://www.crowdsec.net/blog/secure-docker-compose-stacks-with-crowdsec)):

```
┌────────────┐ ┌──────────┐ ┌───────────┐
│ Cloudflare ├──►│ Caddy ├───►│ Web-app │
└────────────┘ └─────┬────┘ └─────┬─────┘
│ │
┌─────┴────┐ ┌─────┴─────┐
│ Crowdsec │ │ db │
└──────────┘ └───────────┘
```

This setups considers the following:

- Cloudflare manages the DNS records of your domain, redirecting (and obfuscating with the orange cloud) the traffic to your target ip where the caddy instance lives
- SSL certificates are automatically managed by caddy with the [caddy-dns/cloudflare](github.com/caddy-dns/cloudflare) module - you need to create an API token Zone Read and DNS Edit access ((see here)[https://github.com/libdns/cloudflare])
- The [crowdsec bouncer](github.com/hslatman/caddy-crowdsec-bouncer/http) module acts as a firewall for those domains that have the `crowdsec` directive in the Caddyfile, inspecting visitors ip and allowing or denying access.
- To increase security, the `docker-compose` setup uses different networks. On host machine only ports `80/443` are open. All other services live in a separate `frontend` network, accessed by caddy to proxy requests. If you have additional "proxy" services (e.g. cloudflared tunnel) you can add them to the `proxy` network.
- To monitor all access for a domain, set a `log {}` directive in the Caddyfile. This log file is mounted on the crowdsec docker instance and inspected with the `acquis.d/caddy.yaml` config. Alternatively, if you are using services with specific [collections](https://app.crowdsec.net/hub/collections), you might decide to use that as opposed to enabling access logging.
39 changes: 39 additions & 0 deletions docker-compose/caddy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
# either this or wrap crowdsec in route {} for each domain to ensure crowdsec is executed first
order crowdsec first

crowdsec {
api_url http://crowdsec:8080
api_key {$CROWDSEC_LOCAL_API_KEY}
}

email {$MY_EMAIL}

# allow the Docker IP range to act as a trusted proxy to set the right client ip https://github.com/hslatman/caddy-crowdsec-bouncer/issues/33
servers {
trusted_proxies static private_ranges
client_ip_headers Cf-Connecting-Ip
}
}

# Log accesses for crowdsec log analysis
(access_log) {
log {
output file /data/log/caddy.log
}
}

# Set SSL/TLS encription mode to Full (strict) https://dash.cloudflare.com/24215ba4f9e7d7664f1c6acbb31e0ec3/{$MY_DOMAIN}/ssl-tls
(cloudflare) {
tls {
dns cloudflare {$CLOUDFLARE_API_TOKEN}
resolvers 1.1.1.1
}
}

web-app.{$MY_DOMAIN} {
crowdsec
reverse_proxy web-app:8080
import cloudflare
import access_log
}
11 changes: 11 additions & 0 deletions docker-compose/caddy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM caddy:builder AS builder

RUN xcaddy build \
# Use Cloudflare for ACME DNS challenge
--with github.com/caddy-dns/cloudflare \
# for crowdsec bouncer
--with github.com/hslatman/caddy-crowdsec-bouncer/http

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy
Binary file added docker-compose/crowdsec/acquis.d/.DS_Store
Binary file not shown.
5 changes: 5 additions & 0 deletions docker-compose/crowdsec/acquis.d/caddy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source: file
filenames:
- /var/log/caddy/caddy.log
labels:
type: caddy
59 changes: 59 additions & 0 deletions docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
version: "3.8"

caddy:
container_name: caddy
image: caddy:latest
build:
context: ~/path/caddy
dockerfile: Dockerfile
volumes:
- ~/path/caddy:/data
- ~/path/caddy/config/Caddyfile:/etc/caddy/Caddyfile:ro
environment:
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CROWDSEC_LOCAL_API_KEY=${CROWDSEC_LOCAL_API_KEY}
- MY_DOMAIN=${MY_DOMAIN}
- MY_EMAIL=${MY_EMAIL}
ports:
- 80:80
- 443:443
depends_on:
- crowdsec
- web-app
networks:
- proxy
- frontend

crowdsec:
container_name: crowdsec
image: crowdsecurity/crowdsec
volumes:
- ~/path/crowdsec/data:/var/lib/crowdsec/data
- ~/path/crowdsec/config:/etc/crowdsec
- ~/path/crowdsec/acquis.d:/etc/crowdsec/acquis.d
- ~/path/caddy/log:/var/log/caddy:ro
environment:
- COLLECTIONS=crowdsecurity/caddy
networks:
- proxy

web-app:
container_name: web-app
depends_on:
- web-app-backend
networks:
- frontend
- backend

web-app-backend:
container_name: web-app-backend
networks:
- backend

networks:
proxy:
driver: bridge
frontend:
driver: bridge
backend:
driver: bridge