diff --git a/containers/crowdsec/scripts/crowdsec_install_host.sh b/containers/crowdsec/scripts/crowdsec_install_host.sh index 795d780..ec3e18a 100644 --- a/containers/crowdsec/scripts/crowdsec_install_host.sh +++ b/containers/crowdsec/scripts/crowdsec_install_host.sh @@ -165,11 +165,14 @@ installCrowdsecHost() # the Traefik container read-only; the plugin reads it via # crowdsecLapiKeyFile. /etc/crowdsec/ is outside the framework's # sourceScanFiles sweep so a bare key file is safe here. - # 2) ${configs_dir}security/security_crowdsec — CFG_CROWDSEC_TRAEFIK_LAPI_KEY - # line, sourced by the framework and visible on the config page. - # Editing the CFG var manually does not re-register the bouncer - # (use the rotate Tools action for that); this is a visibility - # surface, not the auth source of truth. + # 2) the deployed crowdsec.config — CFG_CROWDSEC_TRAEFIK_LAPI_KEY line, + # sourced by the framework and visible on the config page. Editing + # the CFG var manually does not re-register the bouncer; this is a + # visibility surface, not the auth source of truth. + # This used to point at ${configs_dir}security/security_crowdsec, + # which no template ever shipped — so the file never existed, the + # -f guard always failed, and the key was never mirrored. The key + # is declared in crowdsec.config, so that is where it belongs. # The helper handles cscli + tee + chown + chmod atomically. local init_result init_result=$(runCrowdsec bouncer-traefik-init 2>&1) @@ -181,13 +184,15 @@ installCrowdsecHost() # Mirror the key into the live config file so it's visible / # editable via the framework's config page like any other CFG_* - # setting. configs/ is manager-owned, so runInstallOp suffices. - local cfg_file="${configs_dir}security/security_crowdsec" + # setting. updateConfigOption rather than a hand-rolled sed: it + # escapes the value, routes the write through the user that owns + # the containers tree, and re-sources so the new key is live in + # this same run. + local cfg_file="${containers_dir}crowdsec/crowdsec.config" if [[ -f "$cfg_file" ]]; then - runInstallOp sed -i "s|^CFG_CROWDSEC_TRAEFIK_LAPI_KEY=.*|CFG_CROWDSEC_TRAEFIK_LAPI_KEY=${bouncer_key}|" "$cfg_file" - checkSuccess "Key mirrored to CFG_CROWDSEC_TRAEFIK_LAPI_KEY" + updateConfigOption "CFG_CROWDSEC_TRAEFIK_LAPI_KEY" "$bouncer_key" "$cfg_file" else - isNotice "Live config not present yet — key applied on next install." + isNotice "crowdsec.config not deployed yet — key applied on next install." fi else isNotice "Failed to generate bouncer key: $init_result" diff --git a/scripts/config/core/config_update_option.sh b/scripts/config/core/config_update_option.sh index 4a21973..bb06613 100755 --- a/scripts/config/core/config_update_option.sh +++ b/scripts/config/core/config_update_option.sh @@ -55,7 +55,18 @@ updateConfigOption() else $_write_op sed -i "s${DELIM}^${config_option}=.*${DELIM}${config_option}=\"${escaped_value}\"${DELIM}" "$config_file" fi - checkSuccess "Updated $config_option to $config_value" + # Never echo the value of a credential. checkSuccess prints its message + # and appends it to the docker log, so "Updated CFG_X_ADMIN_PASSWORD to + # hunter2" puts a live password in a file on disk — for every admin + # password the auth adapters persist, every generated token, every key. + # Non-secret settings keep showing their value, which is what makes the + # log useful for tracing a config change. + case "$config_option" in + *PASSWORD*|*PASS|*SECRET*|*TOKEN*|*_KEY|*_KEY_[0-9]*|*APIKEY*) + checkSuccess "Updated $config_option" ;; + *) + checkSuccess "Updated $config_option to $config_value" ;; + esac source "$config_file" else isNotice "Unable to find $config_option with value in $config_file"