Add full caddy installation (Coraza WAF + Crowdsec)

- Remove security issue when exposing ports in a docker container: Use
intranet instead
- Modify install_caddy to use new template
This commit is contained in:
2025-01-26 01:35:59 -03:00
parent f352126e56
commit 3d9bdc04b2
9 changed files with 149 additions and 10 deletions

View File

@@ -0,0 +1,23 @@
# Build stage with xcaddy
FROM caddy:builder AS builder
# Install xcaddy and build Caddy with plugins
RUN xcaddy build \
--with github.com/corazawaf/coraza-caddy \
--with github.com/hslatman/caddy-crowdsec-bouncer/http
# Stage to download OWASP CRS
FROM alpine:latest AS crs
RUN apk add --no-cache git && \
git clone --depth 1 --branch v4.0.0 \
https://github.com/coreruleset/coreruleset.git /coreruleset && \
mv /coreruleset/crs-setup.conf.example /coreruleset/crs-setup.conf
# Final stage
FROM caddy:latest
# Copy custom Caddy binary
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
# Copy OWASP CRS from the crs stage
COPY --from=crs /coreruleset /etc/caddy/coreruleset

View File

@@ -0,0 +1 @@
CROWDSEC_API_KEY=${CROWDSEC_API_KEY}

View File

@@ -0,0 +1,39 @@
{
# Put Coraza in front of every request
order coraza_waf first
# Logging
log {
level DEBUG
format console
}
# Allow CrowdSec globally
crowdsec {
api_url http://crowdsec:8080
api_key {$CROWDSEC_API_KEY}
}
}
# Example static
static.example.com {
coraza_waf {
directives `
Include /etc/caddy/coraza.conf
`
}
root * /src/static/test
file_server
}
api.example.com {
coraza_waf {
directives `
Include /etc/caddy/coraza.conf
`
}
reverse_proxy * http://{CONTAINER_NAME}:{CONTAINER_PORT}
}

View File

@@ -0,0 +1,15 @@
# OWASP CRS rules
Include /etc/caddy/coreruleset/crs-setup.conf.example
Include /etc/caddy/coreruleset/rules/*.conf
# Custom rules
SecRuleEngine On
# Block SQLi
SecRule ARGS "@detectSQLi" \
"id:1000,\
phase:2,\
deny,\
status:403,\
msg:'SQL Injection Detected'"

View File

@@ -0,0 +1,6 @@
# Parse Caddy JSON logs
filenames:
- /var/log/caddy/access.log
labels:
type: caddy

View File

@@ -0,0 +1,43 @@
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
volumes:
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
- ./crowdsec/data:/var/lib/crowdsec/data
- ./caddy/logs:/var/log/caddy:ro
environment:
- COLLECTIONS=crowdsecurity/caddy crowdsecurity/whitelist-good-actors crowdsecurity/http-cve
- BOUNCER_KEY_CADDY=${CROWDSEC_API_KEY}
networks:
- caddy_net
restart: unless-stopped
caddy:
image: ghcr.io/elagala/server-initializer/caddy-waf-crowdsec:latest
container_name: caddy
ports:
- "80:80"
- "443:443"
environment:
- CROWDSEC_API_KEY=${CROWDSEC_API_KEY}
volumes:
- ../static:/src/static # Your static files location
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/coraza/coraza.conf:/etc/caddy/coraza.conf
- ./caddy/logs:/var/log/caddy
- caddy_data:/data
- caddy_config:/config
networks:
- caddy_net
depends_on:
- crowdsec
restart: unless-stopped
volumes:
caddy_data:
caddy_config:
networks:
caddy_net:
external: true

View File

@@ -1,22 +1,20 @@
services:
# PORT 9090
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: always
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- monitoring_net
- caddy_net
# PORT 3000
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=YOUR_PASSWORD
- GE_SERVER_ROOT_URL=YOUR_URL
@@ -24,17 +22,19 @@ services:
- prometheus
networks:
- monitoring_net
- caddy_net
# PORT 9100
node_exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: always
ports:
- "9100:9100"
networks:
- monitoring_net
networks:
monitoring_net:
driver: bridge
caddy_net:
external: true

View File

@@ -1,4 +1,5 @@
services:
# PORT 9099
prometheus:
image: prom/prometheus:latest
container_name: prometheus
@@ -9,6 +10,7 @@ services:
- monitoring_net
- caddy_net
# PORT 9100
node_exporter:
image: prom/node-exporter:latest
container_name: node-exporter

View File

@@ -3,14 +3,24 @@
function install_caddy() {
REPO_URL="https://raw.githubusercontent.com/elAgala/server-initializer/master"
TEMPLATE_PATH="/templates/caddy"
TEMPLATE_PATH="/templates/caddy/full"
username="$1"
caddy_dir="/home/$username/caddy"
caddy_dir="/home/$username/web-server"
echo "[ WEB ]: Starting Caddy setup"
mkdir -p "$caddy_dir"
mkdir -p "$caddy_dir/settings"
mkdir -p "$caddy_dir/crowdsec"
mkdir -p "$caddy_dir/caddy"
mkdir -p "$caddy_dir/caddy/coraza"
wget "$REPO_URL/$TEMPLATE_PATH/docker-compose.yml" -O "$caddy_dir/docker-compose.yml"
wget "$REPO_URL/$TEMPLATE_PATH/Caddyfile" -O "$caddy_dir/settings/Caddyfile"
wget "$REPO_URL/$TEMPLATE_PATH/caddy/Caddyfile" -O "$caddy_dir/caddy/Caddyfile"
wget "$REPO_URL/$TEMPLATE_PATH/caddy/coraza/coraza_rules.conf" -O "$caddy_dir/caddy/coraza/coraza_rules.conf"
wget "$REPO_URL/$TEMPLATE_PATH/crowdsec/acquis.yaml" -O "$caddy_dir/crowdsec/acquis.yaml"
echo "[ WEB ]: Caddy setup succesfully. You can find the Caddyfile under /home/$username/caddy/settings"
echo "[ WEB ]: Do not forget to update the .env file located under $caddy_dir"
docker network create caddy_net
echo "[ WEB ]: Created caddy intranet 'caddy_net'"
}