#!/bin/bash set -e set -o pipefail if [ -z "${WILD_INSTANCE}" ]; then echo "ERROR: WILD_INSTANCE is not set" exit 1 fi if [ -z "${WILD_API_DATA_DIR}" ]; then echo "ERROR: WILD_API_DATA_DIR is not set" exit 1 fi if [ -z "${KUBECONFIG}" ]; then echo "ERROR: KUBECONFIG is not set" exit 1 fi INSTANCE_DIR="${WILD_API_DATA_DIR}/instances/${WILD_INSTANCE}" CROWDSEC_DIR="${INSTANCE_DIR}/apps/crowdsec" SECRETS_FILE="${INSTANCE_DIR}/secrets.yaml" echo "=== Setting up CrowdSec Security Engine ===" echo "" echo "Verifying Traefik is ready (required for CrowdSec bouncer)..." kubectl wait --for=condition=Available deployment/traefik -n traefik --timeout=60s 2>/dev/null || { echo "WARNING: Traefik not ready, but continuing with CrowdSec installation" echo "Note: CrowdSec bouncer will not work until Traefik is available" } echo "Using pre-compiled CrowdSec templates..." if [ ! -f "${CROWDSEC_DIR}/kustomization.yaml" ]; then echo "ERROR: Compiled templates not found at ${CROWDSEC_DIR}" echo "Templates should be compiled before deployment." exit 1 fi echo "Deploying CrowdSec..." kubectl apply -k ${CROWDSEC_DIR}/ echo "Creating CrowdSec agent secret..." AGENT_PASSWORD=$(yq '.apps.crowdsec.agentPassword' "$SECRETS_FILE" 2>/dev/null | tr -d '"') if [ -z "$AGENT_PASSWORD" ] || [ "$AGENT_PASSWORD" = "null" ]; then echo "Generating new agent password..." AGENT_PASSWORD=$(openssl rand -base64 32) echo "WARNING: Agent password not found in secrets.yaml" echo "Using generated password - you may want to persist this" fi kubectl create secret generic crowdsec-agent-secret \ --namespace crowdsec \ --from-literal=password="${AGENT_PASSWORD}" \ --dry-run=client -o yaml | kubectl apply -f - echo "Waiting for CrowdSec agent to be ready..." kubectl rollout status deployment/crowdsec -n crowdsec --timeout=120s echo "Registering bouncer with CrowdSec agent..." BOUNCER_API_KEY=$(yq '.apps.crowdsec.bouncerApiKey' "$SECRETS_FILE" 2>/dev/null | tr -d '"') if [ -z "$BOUNCER_API_KEY" ] || [ "$BOUNCER_API_KEY" = "null" ]; then echo "Generating new bouncer API key from CrowdSec agent..." kubectl exec -n crowdsec deploy/crowdsec -- cscli bouncers delete traefik-bouncer 2>/dev/null || true BOUNCER_API_KEY=$(kubectl exec -n crowdsec deploy/crowdsec -- cscli bouncers add traefik-bouncer -o raw) echo "Generated bouncer API key - you may want to persist this in secrets.yaml" fi kubectl create secret generic crowdsec-bouncer-secret \ --namespace crowdsec \ --from-literal=api-key="${BOUNCER_API_KEY}" \ --dry-run=client -o yaml | kubectl apply -f - echo "Copying bouncer secret to traefik namespace..." kubectl create secret generic crowdsec-bouncer-secret \ --namespace traefik \ --from-literal=api-key="${BOUNCER_API_KEY}" \ --dry-run=client -o yaml | kubectl apply -f - echo "Cleaning up old bouncer deployment..." kubectl delete deployment traefik-crowdsec-bouncer -n crowdsec --ignore-not-found kubectl delete service traefik-crowdsec-bouncer -n crowdsec --ignore-not-found echo "Restarting Traefik to load CrowdSec plugin..." kubectl rollout restart deployment/traefik -n traefik kubectl rollout status deployment/traefik -n traefik --timeout=120s echo "Configuring Traefik to use CrowdSec security chain by default..." kubectl patch deployment traefik -n traefik --type='json' -p='[ { "op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--entryPoints.websecure.http.middlewares=crowdsec-security-chain@kubernetescrd" } ]' 2>/dev/null || { echo "Note: Traefik may already have middleware configured or patch failed" echo "You can manually configure default middleware if needed" } echo "" echo "CrowdSec installed successfully (using Traefik plugin)" echo "" echo "All ingresses are now protected by default with:" echo " - Threat detection (CrowdSec Traefik plugin, stream mode)" echo " - Rate limiting (100 req/min)" echo " - Security headers (HSTS, XSS protection, etc.)" echo "" echo "To verify the installation:" echo " kubectl get pods -n crowdsec" echo " kubectl get pods -n traefik" echo " kubectl exec -n crowdsec deploy/crowdsec -- cscli bouncers list" echo " kubectl exec -n crowdsec deploy/crowdsec -- cscli decisions list" echo "" echo "To opt-out a specific ingress from CrowdSec protection:" echo " Add annotation: traefik.ingress.kubernetes.io/router.middlewares: \"\"" echo ""