mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-11 20:36:12 +02:00
Docker refactoring, tls setup (#1869)
This commit is contained in:
parent
c5079ac15e
commit
fde9640364
5 changed files with 377 additions and 156 deletions
|
@ -1,21 +1,60 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Set the crowdsec config file
|
||||
CS_CONFIG_FILE="/etc/crowdsec/config.yaml"
|
||||
if [ "$CONFIG_FILE" != "" ]; then
|
||||
CS_CONFIG_FILE="$CONFIG_FILE"
|
||||
fi
|
||||
# shellcheck disable=SC2292 # allow [ test ] syntax
|
||||
# shellcheck disable=SC2310 # allow "if function..." syntax with -e
|
||||
|
||||
# TLS defaults
|
||||
CERT_FILE="${CERT_FILE:-/etc/ssl/cert.pem}"
|
||||
KEY_FILE="${KEY_FILE:-/etc/ssl/key.pem}"
|
||||
set -e
|
||||
shopt -s inherit_errexit
|
||||
|
||||
# Plugins directory default
|
||||
PLUGIN_DIR="${PLUGIN_DIR:-/usr/local/lib/crowdsec/plugins/}"
|
||||
#- HELPER FUNCTIONS ----------------#
|
||||
|
||||
# Check & prestage databases
|
||||
istrue() {
|
||||
case "$(echo "$1" | tr '[:upper:]' '[:lower:]')" in
|
||||
true) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
isfalse() {
|
||||
if istrue "$1"; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# generate a yaml list from a comma-separated string of values
|
||||
csv2yaml() {
|
||||
[ -z "$1" ] && return
|
||||
echo "$1" | sed 's/,/\n- /g;s/^/- /g'
|
||||
}
|
||||
|
||||
# wrap cscli with the correct config file location
|
||||
cscli() {
|
||||
command cscli -c "$CONFIG_FILE" "$@"
|
||||
}
|
||||
|
||||
conf_get() {
|
||||
if [ $# -ge 2 ]; then
|
||||
yq e "$1" "$2"
|
||||
else
|
||||
yq e "$1" "$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
conf_set() {
|
||||
if [ $# -ge 2 ]; then
|
||||
yq e "$1" -i "$2"
|
||||
else
|
||||
yq e "$1" -i "$CONFIG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
#-----------------------------------#
|
||||
|
||||
# Check and prestage databases
|
||||
for geodb in GeoLite2-ASN.mmdb GeoLite2-City.mmdb; do
|
||||
# We keep the pre-populated geoib databases in /staging instead of /var,
|
||||
# We keep the pre-populated geoip databases in /staging instead of /var,
|
||||
# because if the data directory is bind-mounted from the host, it will be
|
||||
# empty and the files will be out of reach, requiring a runtime download.
|
||||
# We link to them to save about 80Mb compared to cp/mv.
|
||||
|
@ -25,132 +64,158 @@ for geodb in GeoLite2-ASN.mmdb GeoLite2-City.mmdb; do
|
|||
fi
|
||||
done
|
||||
|
||||
#Check & prestage /etc/crowdsec
|
||||
# Check and prestage /etc/crowdsec
|
||||
if [ ! -e "/etc/crowdsec/local_api_credentials.yaml" ] && [ ! -e "/etc/crowdsec/config.yaml" ]; then
|
||||
mkdir -p /etc/crowdsec
|
||||
cp -r /staging/etc/* /etc/
|
||||
echo "Populating configuration directory..."
|
||||
# don't overwrite existing configuration files, which may come
|
||||
# from bind-mount or even be read-only (configmaps)
|
||||
if [ -e /staging/etc/crowdsec ]; then
|
||||
mkdir -p /etc/crowdsec/
|
||||
# if you change this, check that it still works
|
||||
# under alpine and k8s, with and without tls
|
||||
cp -an /staging/etc/crowdsec/* /etc/crowdsec/
|
||||
fi
|
||||
fi
|
||||
|
||||
# regenerate local agent credentials (ignore if agent is disabled)
|
||||
if [ "$DISABLE_AGENT" == "" ] ; then
|
||||
echo "Regenerate local agent credentials"
|
||||
cscli -c "$CS_CONFIG_FILE" machines delete "${CUSTOM_HOSTNAME:-localhost}"
|
||||
if [ "$LOCAL_API_URL" != "" ] ; then
|
||||
cscli -c "$CS_CONFIG_FILE" machines add "${CUSTOM_HOSTNAME:-localhost}" --auto --url "$LOCAL_API_URL"
|
||||
else
|
||||
cscli -c "$CS_CONFIG_FILE" machines add "${CUSTOM_HOSTNAME:-localhost}" --auto
|
||||
if isfalse "$DISABLE_AGENT"; then
|
||||
if isfalse "$DISABLE_LOCAL_API"; then
|
||||
echo "Regenerate local agent credentials"
|
||||
cscli machines delete "$CUSTOM_HOSTNAME"
|
||||
# shellcheck disable=SC2086
|
||||
cscli machines add "$CUSTOM_HOSTNAME" --auto --url "$LOCAL_API_URL"
|
||||
fi
|
||||
if [ "$AGENT_USERNAME" != "" ] && [ "$AGENT_PASSWORD" != "" ] && [ "$LOCAL_API_URL" != "" ] ; then
|
||||
echo "set up lapi credentials for agent"
|
||||
CONFIG_PATH=$(yq eval '.api.client.credentials_path' "$CS_CONFIG_FILE" )
|
||||
echo "url: $LOCAL_API_URL" > "$CONFIG_PATH"
|
||||
echo "login: $AGENT_USERNAME" >> "$CONFIG_PATH"
|
||||
echo "password: $AGENT_PASSWORD" >> "$CONFIG_PATH"
|
||||
|
||||
lapi_credentials_path=$(conf_get '.api.client.credentials_path')
|
||||
|
||||
if istrue "$USE_TLS"; then
|
||||
install -m 0600 /dev/null "$lapi_credentials_path"
|
||||
conf_set '
|
||||
.url = strenv(LOCAL_API_URL) |
|
||||
.ca_cert_path = strenv(CACERT_FILE) |
|
||||
.key_path = strenv(KEY_FILE) |
|
||||
.cert_path = strenv(CERT_FILE)
|
||||
' "$lapi_credentials_path"
|
||||
elif [ "$AGENT_USERNAME" != "" ]; then
|
||||
install -m 0600 /dev/null "$lapi_credentials_path"
|
||||
conf_set '
|
||||
.url = strenv(LOCAL_API_URL) |
|
||||
.login = strenv(AGENT_USERNAME) |
|
||||
.password = strenv(AGENT_PASSWORD)
|
||||
' "$lapi_credentials_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if lapi needs to automatically register an agent
|
||||
echo "Check if lapi need to register automatically an agent"
|
||||
if [ "$DISABLE_LOCAL_API" == "" ] && [ "$AGENT_USERNAME" != "" ] && [ "$AGENT_PASSWORD" != "" ] ; then
|
||||
if [ "$LOCAL_API_URL" != "" ] ; then
|
||||
cscli -c "$CS_CONFIG_FILE" machines add "$AGENT_USERNAME" --password "$AGENT_PASSWORD" --url "$LOCAL_API_URL"
|
||||
else
|
||||
cscli -c "$CS_CONFIG_FILE" machines add "$AGENT_USERNAME" --password "$AGENT_PASSWORD"
|
||||
if isfalse "$DISABLE_LOCAL_API"; then
|
||||
echo "Check if lapi needs to automatically register an agent"
|
||||
|
||||
# pre-registration is not needed with TLS
|
||||
if isfalse "$USE_TLS" && [ "$AGENT_USERNAME" != "" ] && [ "$AGENT_PASSWORD" != "" ] ; then
|
||||
# shellcheck disable=SC2086
|
||||
cscli machines add "$AGENT_USERNAME" --password "$AGENT_PASSWORD" --url "$LOCAL_API_URL"
|
||||
echo "Agent registered to lapi"
|
||||
fi
|
||||
echo "Agent registered to lapi"
|
||||
fi
|
||||
|
||||
# registration to online API for signal push
|
||||
if [ "${DISABLE_ONLINE_API,,}" != "true" ] && [ "$CONFIG_FILE" == "" ] ; then
|
||||
CONFIG_EXIST=$(yq eval '.api.server.online_client | has("credentials_path")' "$CS_CONFIG_FILE")
|
||||
if [ "$CONFIG_EXIST" != "true" ]; then
|
||||
yq eval '.api.server.online_client = {"credentials_path": "/etc/crowdsec/online_api_credentials.yaml"}' "$CS_CONFIG_FILE" > /etc/crowdsec/config2.yaml
|
||||
mv /etc/crowdsec/config2.yaml "$CS_CONFIG_FILE"
|
||||
cscli -c "$CS_CONFIG_FILE" capi register > /etc/crowdsec/online_api_credentials.yaml
|
||||
echo "registration to online API done"
|
||||
if isfalse "$DISABLE_ONLINE_API" && [ "$CONFIG_FILE" == "/etc/crowdsec/config.yaml" ] ; then
|
||||
config_exists=$(conf_get '.api.server.online_client | has("credentials_path")')
|
||||
if isfalse "$config_exists"; then
|
||||
conf_set '.api.server.online_client = {"credentials_path": "/etc/crowdsec/online_api_credentials.yaml"}'
|
||||
cscli capi register > /etc/crowdsec/online_api_credentials.yaml
|
||||
echo "Registration to online API done"
|
||||
fi
|
||||
fi
|
||||
|
||||
## Enroll instance if enroll key is provided
|
||||
if [ "${DISABLE_ONLINE_API,,}" != "true" ] && [ "$ENROLL_KEY" != "" ] ; then
|
||||
# Enroll instance if enroll key is provided
|
||||
if isfalse "$DISABLE_ONLINE_API" && [ "$ENROLL_KEY" != "" ]; then
|
||||
enroll_args=""
|
||||
if [ "$ENROLL_INSTANCE_NAME" != "" ] ; then
|
||||
if [ "$ENROLL_INSTANCE_NAME" != "" ]; then
|
||||
enroll_args="--name $ENROLL_INSTANCE_NAME"
|
||||
fi
|
||||
if [ "$ENROLL_TAGS" != "" ] ; then
|
||||
#shellcheck disable=SC2086
|
||||
for tag in ${ENROLL_TAGS}
|
||||
do
|
||||
if [ "$ENROLL_TAGS" != "" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
for tag in ${ENROLL_TAGS}; do
|
||||
enroll_args="$enroll_args --tags $tag"
|
||||
done
|
||||
fi
|
||||
#shellcheck disable=SC2086
|
||||
# shellcheck disable=SC2086
|
||||
cscli console enroll $enroll_args "$ENROLL_KEY"
|
||||
fi
|
||||
|
||||
# crowdsec sqlite database permissions
|
||||
if [ "$GID" != "" ]; then
|
||||
IS_SQLITE=$(yq eval '.db_config.type == "sqlite"' "$CS_CONFIG_FILE")
|
||||
DB_PATH=$(yq eval '.db_config.db_path' "$CS_CONFIG_FILE")
|
||||
if [ "$IS_SQLITE" == "true" ]; then
|
||||
chown ":$GID" "$DB_PATH"
|
||||
if istrue "$(conf_get '.db_config.type == "sqlite"')"; then
|
||||
chown ":$GID" "$(conf_get '.db_config.db_path')"
|
||||
echo "sqlite database permissions updated"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${USE_TLS,,}" == "true" ]; 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"
|
||||
if istrue "$USE_TLS"; then
|
||||
agents_allowed_yaml=$(csv2yaml "$AGENTS_ALLOWED_OU") \
|
||||
bouncers_allowed_yaml=$(csv2yaml "$BOUNCERS_ALLOWED_OU") \
|
||||
conf_set '
|
||||
.api.server.tls.ca_cert_path = strenv(CACERT_FILE) |
|
||||
.api.server.tls.cert_file = strenv(CERT_FILE) |
|
||||
.api.server.tls.key_file = strenv(KEY_FILE) |
|
||||
.api.server.tls.bouncers_allowed_ou = env(bouncers_allowed_yaml) |
|
||||
.api.server.tls.agents_allowed_ou = env(agents_allowed_yaml) |
|
||||
... comments=""
|
||||
'
|
||||
fi
|
||||
|
||||
if [ "$PLUGIN_DIR" != "/usr/local/lib/crowdsec/plugins/" ]; then
|
||||
yq -i eval ".config_paths.plugin_dir = \"$PLUGIN_DIR\"" "$CS_CONFIG_FILE"
|
||||
fi
|
||||
conf_set ".config_paths.plugin_dir = strenv(PLUGIN_DIR)"
|
||||
|
||||
## Install collections, parsers, scenarios & postoverflows
|
||||
cscli -c "$CS_CONFIG_FILE" hub update
|
||||
cscli -c "$CS_CONFIG_FILE" collections upgrade crowdsecurity/linux || true
|
||||
cscli -c "$CS_CONFIG_FILE" parsers upgrade crowdsecurity/whitelists || true
|
||||
cscli -c "$CS_CONFIG_FILE" parsers install crowdsecurity/docker-logs || true
|
||||
cscli hub update
|
||||
cscli collections upgrade crowdsecurity/linux || true
|
||||
cscli parsers upgrade crowdsecurity/whitelists || true
|
||||
cscli parsers install crowdsecurity/docker-logs || true
|
||||
|
||||
if [ "$COLLECTIONS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" collections install $COLLECTIONS
|
||||
# shellcheck disable=SC2086
|
||||
cscli collections install $COLLECTIONS
|
||||
fi
|
||||
|
||||
if [ "$PARSERS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" parsers install $PARSERS
|
||||
# shellcheck disable=SC2086
|
||||
cscli parsers install $PARSERS
|
||||
fi
|
||||
|
||||
if [ "$SCENARIOS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" scenarios install $SCENARIOS
|
||||
# shellcheck disable=SC2086
|
||||
cscli scenarios install $SCENARIOS
|
||||
fi
|
||||
|
||||
if [ "$POSTOVERFLOWS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" postoverflows install $POSTOVERFLOWS
|
||||
# shellcheck disable=SC2086
|
||||
cscli postoverflows install $POSTOVERFLOWS
|
||||
fi
|
||||
|
||||
## Remove collections, parsers, scenarios & postoverflows
|
||||
if [ "$DISABLE_COLLECTIONS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" collections remove $DISABLE_COLLECTIONS
|
||||
fi
|
||||
if [ "$DISABLE_PARSERS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" parsers remove $DISABLE_PARSERS
|
||||
fi
|
||||
if [ "$DISABLE_SCENARIOS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" scenarios remove $DISABLE_SCENARIOS
|
||||
fi
|
||||
if [ "$DISABLE_POSTOVERFLOWS" != "" ]; then
|
||||
#shellcheck disable=SC2086
|
||||
cscli -c "$CS_CONFIG_FILE" postoverflows remove $DISABLE_POSTOVERFLOWS
|
||||
# shellcheck disable=SC2086
|
||||
cscli collections remove $DISABLE_COLLECTIONS
|
||||
fi
|
||||
|
||||
function register_bouncer {
|
||||
if ! cscli -c "$CS_CONFIG_FILE" bouncers list -o json | sed '/^ *"name"/!d;s/^ *"name": "\(.*\)",/\1/' | grep -q "^${NAME}$"; then
|
||||
if cscli -c "$CS_CONFIG_FILE" bouncers add "${NAME}" -k "${KEY}" > /dev/null; then
|
||||
if [ "$DISABLE_PARSERS" != "" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
cscli parsers remove $DISABLE_PARSERS
|
||||
fi
|
||||
|
||||
if [ "$DISABLE_SCENARIOS" != "" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
cscli scenarios remove $DISABLE_SCENARIOS
|
||||
fi
|
||||
|
||||
if [ "$DISABLE_POSTOVERFLOWS" != "" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
cscli postoverflows remove $DISABLE_POSTOVERFLOWS
|
||||
fi
|
||||
|
||||
register_bouncer() {
|
||||
if ! cscli bouncers list -o json | sed '/^ *"name"/!d;s/^ *"name": "\(.*\)",/\1/' | grep -q "^${NAME}$"; then
|
||||
if cscli bouncers add "${NAME}" -k "${KEY}" > /dev/null; then
|
||||
echo "Registered bouncer for ${NAME}"
|
||||
else
|
||||
echo "Failed to register bouncer for ${NAME}"
|
||||
|
@ -182,6 +247,7 @@ ARGS=""
|
|||
if [ "$CONFIG_FILE" != "" ]; then
|
||||
ARGS="-c $CONFIG_FILE"
|
||||
fi
|
||||
|
||||
if [ "$DSN" != "" ]; then
|
||||
ARGS="$ARGS -dsn ${DSN}"
|
||||
fi
|
||||
|
@ -189,24 +255,32 @@ fi
|
|||
if [ "$TYPE" != "" ]; then
|
||||
ARGS="$ARGS -type $TYPE"
|
||||
fi
|
||||
if [ "${TEST_MODE,,}" == "true" ]; then
|
||||
|
||||
if istrue "$TEST_MODE"; then
|
||||
ARGS="$ARGS -t"
|
||||
fi
|
||||
if [ "${DISABLE_AGENT,,}" == "true" ]; then
|
||||
|
||||
if istrue "$DISABLE_AGENT"; then
|
||||
ARGS="$ARGS -no-cs"
|
||||
fi
|
||||
if [ "${DISABLE_LOCAL_API,,}" == "true" ]; then
|
||||
|
||||
if istrue "$DISABLE_LOCAL_API"; then
|
||||
ARGS="$ARGS -no-api"
|
||||
fi
|
||||
if [ "${LEVEL_TRACE,,}" == "true" ]; then
|
||||
|
||||
if istrue "$LEVEL_TRACE"; then
|
||||
ARGS="$ARGS -trace"
|
||||
fi
|
||||
if [ "${LEVEL_DEBUG,,}" == "true" ]; then
|
||||
|
||||
if istrue "$LEVEL_DEBUG"; then
|
||||
ARGS="$ARGS -debug"
|
||||
fi
|
||||
if [ "${LEVEL_INFO,,}" == "true" ]; then
|
||||
|
||||
if istrue "$LEVEL_INFO"; then
|
||||
ARGS="$ARGS -info"
|
||||
fi
|
||||
|
||||
#shellcheck disable=SC2086
|
||||
conf_set '.prometheus.listen_port=env(METRICS_PORT)'
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
exec crowdsec $ARGS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue