From 33ef6eaea62714f119f11936f392bbdcab73b03f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 4 Apr 2022 09:18:44 +0100 Subject: [PATCH] Register bouncers on container init (#1341) * Register bounces on init --- Dockerfile | 2 +- Dockerfile.debian | 1 + docker/README.md | 11 +++++++++++ docker/docker_start.sh | 38 ++++++++++++++++++++++++++++++++++---- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 47380404d..dfdb0828a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN SYSTEM="docker" make release RUN cd crowdsec-v* && ./wizard.sh --docker-mode && cd - RUN cscli hub update && cscli collections install crowdsecurity/linux && cscli parsers install crowdsecurity/whitelists FROM alpine:latest -RUN apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community tzdata yq bash && \ +RUN apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community tzdata yq jq bash && \ mkdir -p /staging/etc/crowdsec && \ mkdir -p /staging/var/lib/crowdsec COPY --from=build /etc/crowdsec /staging/etc/crowdsec diff --git a/Dockerfile.debian b/Dockerfile.debian index 421f99d39..544d20ac6 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -23,6 +23,7 @@ RUN apt-get install -y -q --install-recommends --no-install-suggests \ iproute2 \ ca-certificates \ bash \ + jq \ tzdata && \ mkdir -p /staging/etc/crowdsec && \ mkdir -p /staging/var/lib/crowdsec diff --git a/docker/README.md b/docker/README.md index e2a4faf0e..869b08768 100644 --- a/docker/README.md +++ b/docker/README.md @@ -104,6 +104,16 @@ https://hub.crowdsec.net/browse/#bouncers https://docs.crowdsec.net/docs/user_guides/bouncers_configuration/ +### Automatic Bouncer Registration + +You can automatically register bouncers with the crowdsec container on startup using environment variables or Docker secrets. You cannot use this process to update an existing bouncer without first deleting it. + +To use environment variables, they should be in the format `BOUNCER_KEY_=`. e.g. `BOUNCER_KEY_nginx=mysecretkey12345`. + +To use Docker secrets, the secret should be named `bouncer_key_` with a content of ``. e.g. `bouncer_key_nginx` with a content of `mysecretkey12345`. + +A bouncer key can be any string but we recommend an alphanumeric value to keep consistent with crowdsec-generated keys and avoid problems with escaping special characters. + ## Console We provide a web based interface to get more from Crowdsec: https://docs.crowdsec.net/docs/console @@ -142,6 +152,7 @@ Using binds rather than named volumes ([more explanation here](https://docs.dock * `DISABLE_SCENARIOS` - Scenarios to remove from the [hub](https://hub.crowdsec.net/browse/#configurations), separated by space : `-e DISABLE_SCENARIOS="crowdsecurity/http-bad-user-agent crowdsecurity/http-xss-probing"` * `DISABLE_POSTOVERFLOWS` - Postoverflows to remove from the [hub](https://hub.crowdsec.net/browse/#configurations), separated by space : `-e DISABLE_POSTOVERFLOWS="crowdsecurity/cdn-whitelist crowdsecurity/seo-bots-whitelist"` * `PLUGIN_DIR` - Directory for plugins (default: `/usr/local/lib/crowdsec/plugins/`) : `-e PLUGIN_DIR=""` +* `BOUNCER_KEY_` - Register a bouncer with the name `` and a key equal to the value of the environment variable. ## Volumes diff --git a/docker/docker_start.sh b/docker/docker_start.sh index 35a29119f..b049c6994 100755 --- a/docker/docker_start.sh +++ b/docker/docker_start.sh @@ -76,13 +76,13 @@ if [ "$GID" != "" ]; then fi if [ "$USE_TLS" != "" ]; then - yq -i eval ".api.server.tls.cert_file = \"$CERT_FILE\"" "$CS_CONFIG_FILE" - yq -i eval ".api.server.tls.key_file = \"$KEY_FILE\"" "$CS_CONFIG_FILE" - yq -i eval '... comments=""' "$CS_CONFIG_FILE" + yq -i eval ".api.server.tls.cert_file = \"$CERT_FILE\"" "$CS_CONFIG_FILE" + yq -i eval ".api.server.tls.key_file = \"$KEY_FILE\"" "$CS_CONFIG_FILE" + yq -i eval '... comments=""' "$CS_CONFIG_FILE" fi if [ "$PLUGIN_DIR" != "/usr/local/lib/crowdsec/plugins/" ]; then - yq -i eval ".config_paths.plugin_dir = \"$PLUGIN_DIR\"" "$CS_CONFIG_FILE" + yq -i eval ".config_paths.plugin_dir = \"$PLUGIN_DIR\"" "$CS_CONFIG_FILE" fi ## Install collections, parsers, scenarios & postoverflows @@ -117,6 +117,36 @@ if [ "$DISABLE_POSTOVERFLOWS" != "" ]; then cscli -c "$CS_CONFIG_FILE" postoverflows remove $DISABLE_POSTOVERFLOWS fi +function register_bouncer { + if ! cscli -c "$CS_CONFIG_FILE" bouncers list -o json | jq -r .[].name | grep -q "${NAME}"; then + if cscli -c "$CS_CONFIG_FILE" bouncers add "${NAME}" -k "${KEY}" > /dev/null; then + echo "Registered bouncer for ${NAME}" + else + echo "Failed to register bouncer for ${NAME}" + fi + fi +} + +## Register bouncers via env +for BOUNCER in $(compgen -A variable | grep -i BOUNCER_KEY); do + KEY=$(printf '%s' "${!BOUNCER}") + NAME=$(printf '%s' "$BOUNCER" | cut -d_ -f2-) + if [[ -n $KEY ]] && [[ -n $NAME ]]; then + register_bouncer + fi +done + +## Register bouncers via secrets +shopt -s nullglob extglob +for BOUNCER in /run/secrets/@(bouncer_key|BOUNCER_KEY)* ; do + KEY=$(cat "${BOUNCER}") + NAME=$(echo "${BOUNCER}" | awk -F "/" '{printf $NF}' | cut -d_ -f2-) + if [[ -n $KEY ]] && [[ -n $NAME ]]; then + register_bouncer + fi +done +shopt -u nullglob extglob + ARGS="" if [ "$CONFIG_FILE" != "" ]; then ARGS="-c $CONFIG_FILE"