788 lines
23 KiB
Bash
Executable file
788 lines
23 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
# allow calling functions in an "if" statement
|
|
#shellcheck disable=SC2310
|
|
|
|
set -e
|
|
|
|
checkroot() {
|
|
#shellcheck disable=SC2312
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
log_err "Please run the wizard as root or with sudo"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
interactive() {
|
|
if [ ! -t 0 ] || [ "$SILENT" = "true" ]; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
SILENT="false"
|
|
DOCKER_MODE="false"
|
|
|
|
CROWDSEC_LIB_DIR="/var/lib/crowdsec"
|
|
CROWDSEC_USR_DIR="/usr/local/lib/crowdsec"
|
|
CROWDSEC_DATA_DIR="${CROWDSEC_LIB_DIR}/data"
|
|
CROWDSEC_DB_PATH="${CROWDSEC_DATA_DIR}/crowdsec.db"
|
|
CROWDSEC_PATH="/etc/crowdsec"
|
|
CROWDSEC_CONFIG_PATH="$CROWDSEC_PATH"
|
|
CROWDSEC_LOG_FILE="/var/log/crowdsec.log"
|
|
LAPI_LOG_FILE="/var/log/crowdsec_api.log"
|
|
|
|
CROWDSEC_BIN="./cmd/crowdsec/crowdsec"
|
|
CSCLI_BIN="./cmd/crowdsec-cli/cscli"
|
|
|
|
CLIENT_SECRETS="local_api_credentials.yaml"
|
|
LAPI_SECRETS="online_api_credentials.yaml"
|
|
|
|
BIN_INSTALL_PATH="/usr/local/bin"
|
|
CROWDSEC_BIN_INSTALLED="${BIN_INSTALL_PATH}/crowdsec"
|
|
|
|
if [ -f "/usr/bin/cscli" ]; then
|
|
CSCLI_BIN_INSTALLED="/usr/bin/cscli"
|
|
else
|
|
CSCLI_BIN_INSTALLED="${BIN_INSTALL_PATH}/cscli"
|
|
fi
|
|
|
|
ACQUIS_DIR="${CROWDSEC_CONFIG_PATH}/acquis.d"
|
|
ACQUIS_YAML="${CROWDSEC_CONFIG_PATH}/acquis.yaml"
|
|
|
|
SYSTEMD_PATH_FILE="/etc/systemd/system/crowdsec.service"
|
|
|
|
PATTERNS_FOLDER="config/patterns"
|
|
PATTERNS_PATH="${CROWDSEC_CONFIG_PATH}/patterns/"
|
|
|
|
ACTION=""
|
|
|
|
DEBUG_MODE="false"
|
|
FORCE_MODE="false"
|
|
|
|
PLUGIN_CONFIGURATION_SRC="./plugins/notifications"
|
|
PLUGIN_CONFIGURATION_DEST="/etc/crowdsec/notifications"
|
|
PLUGIN_BINARIES_SRC="./plugins/notifications"
|
|
PLUGIN_BINARIES_DEST="${CROWDSEC_USR_DIR}/plugins"
|
|
|
|
# XXX WTH should remove it later
|
|
BACKUP_DIR=$(mktemp -d)
|
|
rm -rf -- "$BACKUP_DIR"
|
|
|
|
set_colors() {
|
|
#shellcheck disable=SC2034
|
|
if [ ! -t 0 ]; then
|
|
# terminal is not interactive; no colors
|
|
FG_RED=""
|
|
FG_GREEN=""
|
|
FG_YELLOW=""
|
|
FG_BLUE=""
|
|
FG_MAGENTA=""
|
|
FG_CYAN=""
|
|
FG_WHITE=""
|
|
BOLD=""
|
|
RESET=""
|
|
elif tput sgr0 >/dev/null; then
|
|
# terminfo
|
|
FG_RED=$(tput setaf 1)
|
|
FG_GREEN=$(tput setaf 2)
|
|
FG_YELLOW=$(tput setaf 3)
|
|
FG_BLUE=$(tput setaf 4)
|
|
FG_MAGENTA=$(tput setaf 5)
|
|
FG_CYAN=$(tput setaf 6)
|
|
FG_WHITE=$(tput setaf 7)
|
|
BOLD=$(tput bold)
|
|
RESET=$(tput sgr0)
|
|
else
|
|
FG_RED=$(printf '%b' '\033[31m')
|
|
FG_GREEN=$(printf '%b' '\033[32m')
|
|
FG_YELLOW=$(printf '%b' '\033[33m')
|
|
FG_BLUE=$(printf '%b' '\033[34m')
|
|
FG_MAGENTA=$(printf '%b' '\033[35m')
|
|
FG_CYAN=$(printf '%b' '\033[36m')
|
|
FG_WHITE=$(printf '%b' '\033[37m')
|
|
BOLD=$(printf '%b' '\033[1m')
|
|
RESET=$(printf '%b' '\033[0m')
|
|
fi
|
|
}
|
|
|
|
#XXX logging is not consistent
|
|
log_info() {
|
|
msg=$1
|
|
date=$(date +%x:%X)
|
|
echo "${FG_BLUE}INFO${RESET}[${date}] crowdsec_wizard: ${msg}"
|
|
}
|
|
|
|
log_fatal() {
|
|
msg=$1
|
|
date=$(date +%x:%X)
|
|
echo "${FG_RED}FATA${RESET}[${date}] crowdsec_wizard: ${msg}" >&2
|
|
exit 1
|
|
}
|
|
|
|
log_warn() {
|
|
msg=$1
|
|
date=$(date +%x:%X)
|
|
echo "${FG_YELLOW}WARN${RESET}[${date}] crowdsec_wizard: ${msg}"
|
|
}
|
|
|
|
log_err() {
|
|
msg=$1
|
|
date=$(date +%x:%X)
|
|
echo "${FG_RED}ERR${RESET}[${date}] crowdsec_wizard: ${msg}" >&2
|
|
}
|
|
|
|
log_dbg() {
|
|
if [ "$DEBUG_MODE" = "true" ]; then
|
|
msg=$1
|
|
date=$(date +%x:%X)
|
|
echo "[${date}][${FG_YELLOW}DBG${RESET}] crowdsec_wizard: ${msg}" >&2
|
|
fi
|
|
}
|
|
|
|
crowdsec_service_stop() {
|
|
if command -v systemctl >/dev/null && systemctl is-active --quiet crowdsec; then
|
|
systemctl stop crowdsec.service
|
|
fi
|
|
}
|
|
|
|
crowdsec_service_disable() {
|
|
if command -v systemctl >/dev/null && systemctl is-enabled --quiet crowdsec; then
|
|
systemctl disable crowdsec.service
|
|
fi
|
|
}
|
|
|
|
crowdsec_service_restart() {
|
|
if command -v systemctl >/dev/null; then
|
|
systemctl restart crowdsec
|
|
fi
|
|
}
|
|
|
|
|
|
detect_cs_install() {
|
|
if [ -f "$CROWDSEC_BIN_INSTALLED" ]; then
|
|
log_warn "Crowdsec is already installed!"
|
|
echo ""
|
|
echo "We recommend to upgrade: sudo $0 --upgrade "
|
|
echo "If you want to install it anyway, please use '--force'."
|
|
echo ""
|
|
echo "Run: sudo $0 -i --force"
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_cs_version() {
|
|
CURRENT_CS_VERSION=$(crowdsec -version 2>&1 | grep version | grep -Eio 'v[0-9]+.[0-9]+.[0-9]+' | cut -c 2-)
|
|
NEW_CS_VERSION=$("$CROWDSEC_BIN" -version 2>&1 | grep version | grep -Eio 'v[0-9]+.[0-9]+.[0-9]+' | cut -c 2-)
|
|
CURRENT_MAJOR_VERSION=$(echo "$CURRENT_CS_VERSION" | cut -d'.' -f1)
|
|
CURRENT_MINOR_VERSION=$(echo "$CURRENT_CS_VERSION" | cut -d'.' -f2)
|
|
CURRENT_PATCH_VERSION=$(echo "$CURRENT_CS_VERSION" | cut -d'.' -f3)
|
|
NEW_MAJOR_VERSION=$(echo "$NEW_CS_VERSION" | cut -d'.' -f1)
|
|
NEW_MINOR_VERSION=$(echo "$NEW_CS_VERSION" | cut -d'.' -f2)
|
|
NEW_PATCH_VERSION=$(echo "$NEW_CS_VERSION" | cut -d'.' -f3)
|
|
|
|
if [ "$NEW_MAJOR_VERSION" -gt "$CURRENT_MAJOR_VERSION" ]; then
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
log_warn "new version (${NEW_CS_VERSION}) is a major, please follow the documentation to upgrade!"
|
|
echo ""
|
|
exit 1
|
|
fi
|
|
elif [ "$NEW_MINOR_VERSION" -gt "$CURRENT_MINOR_VERSION" ]; then
|
|
log_warn "new version (${NEW_CS_VERSION}) is a minor upgrade!"
|
|
if [ "$ACTION" != "upgrade" ]; then
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
echo ""
|
|
echo "We recommend to upgrade with: sudo $0 --upgrade"
|
|
echo "If you want to ${ACTION} anyway, please use '--force'."
|
|
echo ""
|
|
echo "Run: sudo $0 --${ACTION} --force"
|
|
exit 1
|
|
fi
|
|
fi
|
|
elif [ "$NEW_PATCH_VERSION" -gt "$CURRENT_PATCH_VERSION" ]; then
|
|
log_warn "new version (${NEW_CS_VERSION}) is a patch !"
|
|
if [ "$ACTION" != "binupgrade" ]; then
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
echo ""
|
|
echo "We recommend to upgrade binaries only: sudo $0 --binupgrade"
|
|
echo "If you want to ${ACTION} anyway, please use '--force'."
|
|
echo ""
|
|
echo "Run: sudo $0 --${ACTION} --force"
|
|
exit 1
|
|
fi
|
|
fi
|
|
elif [ "$NEW_MINOR_VERSION" -eq "$CURRENT_MINOR_VERSION" ]; then
|
|
log_warn "new version (${NEW_CS_VERSION}) is same as current version (${CURRENT_CS_VERSION})!"
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
echo ""
|
|
echo "We recommend to ${ACTION} only if it's an higher version."
|
|
echo "If it's an RC version (vX.X.X-rc) you can upgrade it using '--force'."
|
|
echo ""
|
|
echo "Run: sudo $0 --${ACTION} --force"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
install_crowdsec() {
|
|
mkdir -p "$CROWDSEC_DATA_DIR"
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/collections"
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/parsers"
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/patterns"
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/postoverflows"
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/scenarios"
|
|
(cd config && find patterns -maxdepth 1 -type f -exec install -m 0644 "{}" "${CROWDSEC_CONFIG_PATH}/{}" \; && cd ../)
|
|
|
|
install -m 0600 "./config/$CLIENT_SECRETS" "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0600 "./config/$LAPI_SECRETS" "$CROWDSEC_CONFIG_PATH"
|
|
|
|
install -m 0600 ./config/config.yaml "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0644 ./config/dev.yaml "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0644 ./config/user.yaml "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0644 ./config/profiles.yaml "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0644 ./config/simulation.yaml "$CROWDSEC_CONFIG_PATH"
|
|
install -m 0644 ./config/console.yaml "$CROWDSEC_CONFIG_PATH"
|
|
|
|
mkdir -p "$CROWDSEC_CONFIG_PATH/hub"
|
|
install -m 0644 ./config/detect.yaml "${CROWDSEC_CONFIG_PATH}/hub"
|
|
|
|
#shellcheck disable=SC2016
|
|
DATA=${CROWDSEC_DATA_DIR} CFG=${CROWDSEC_CONFIG_PATH} envsubst '$CFG $DATA' <./config/user.yaml >"${CROWDSEC_CONFIG_PATH}/user.yaml" || log_fatal "unable to generate user configuration file"
|
|
if [ "$DOCKER_MODE" = "false" ]; then
|
|
#shellcheck disable=SC2016
|
|
CFG=${CROWDSEC_CONFIG_PATH} BIN=${CROWDSEC_BIN_INSTALLED} envsubst '$CFG $BIN' <./config/crowdsec.service >"$SYSTEMD_PATH_FILE" || log_fatal "unable to generate systemd file"
|
|
fi
|
|
install_bins
|
|
|
|
if [ "$DOCKER_MODE" = "false" ]; then
|
|
systemctl daemon-reload
|
|
fi
|
|
}
|
|
|
|
update_bins() {
|
|
log_info "Only upgrading binaries"
|
|
delete_bins
|
|
install_bins
|
|
log_info "Upgrade finished"
|
|
systemctl restart crowdsec || log_fatal "unable to restart crowdsec with systemctl"
|
|
}
|
|
|
|
update_full() {
|
|
if [ ! -f "$CROWDSEC_BIN" ]; then
|
|
log_err "Crowdsec binary '${CROWDSEC_BIN}' not found. Please build it with 'make build'"
|
|
exit
|
|
fi
|
|
if [ ! -f "$CSCLI_BIN" ]; then
|
|
log_err "Cscli binary '${CSCLI_BIN}' not found. Please build it with 'make build'"
|
|
exit
|
|
fi
|
|
|
|
log_info "Backing up existing configuration"
|
|
"$CSCLI_BIN_INSTALLED" config backup "$BACKUP_DIR"
|
|
log_info "Saving default database content if exist"
|
|
if [ -f "/var/lib/crowdsec/data/crowdsec.db" ]; then
|
|
cp /var/lib/crowdsec/data/crowdsec.db "${BACKUP_DIR}/crowdsec.db"
|
|
fi
|
|
log_info "Cleanup existing crowdsec configuration"
|
|
uninstall_crowdsec
|
|
log_info "Installing crowdsec"
|
|
install_crowdsec
|
|
log_info "Restoring configuration"
|
|
"$CSCLI_BIN_INSTALLED" hub update
|
|
"$CSCLI_BIN_INSTALLED" config restore "$BACKUP_DIR"
|
|
log_info "Restoring saved database if exist"
|
|
if [ -f "${BACKUP_DIR}/crowdsec.db" ]; then
|
|
cp "${BACKUP_DIR}/crowdsec.db" /var/lib/crowdsec/data/crowdsec.db
|
|
fi
|
|
log_info "Finished, restarting"
|
|
crowdsec_service_restart || log_fatal "Failed to restart crowdsec"
|
|
}
|
|
|
|
install_bins() {
|
|
log_dbg "Installing crowdsec binaries"
|
|
install -m 0755 "$CROWDSEC_BIN" "$CROWDSEC_BIN_INSTALLED" >/dev/null
|
|
install -m 0755 "$CSCLI_BIN" "$CSCLI_BIN_INSTALLED" >/dev/null
|
|
|
|
crowdsec_service_stop
|
|
install_plugins
|
|
symlink_bins
|
|
}
|
|
|
|
symlink_bins() {
|
|
if echo "$PATH" | grep -q "$BIN_INSTALL_PATH"; then
|
|
log_dbg "${BIN_INSTALL_PATH} found in PATH"
|
|
else
|
|
ln -s "$CSCLI_BIN_INSTALLED" /usr/bin/cscli
|
|
ln -s "$CROWDSEC_BIN_INSTALLED" /usr/bin/crowdsec
|
|
fi
|
|
}
|
|
|
|
delete_bins() {
|
|
log_info "Removing crowdsec binaries"
|
|
rm -f -- "$CROWDSEC_BIN_INSTALLED"
|
|
rm -f -- "$CSCLI_BIN_INSTALLED"
|
|
}
|
|
|
|
delete_plugins() {
|
|
rm -rf -- "$PLUGIN_BINARIES_DEST"
|
|
}
|
|
|
|
detect_only() {
|
|
"$CSCLI_BIN_INSTALLED" setup detect --yaml
|
|
}
|
|
|
|
edit_file() {
|
|
editor="$VISUAL"
|
|
if [ "$editor" = "" ]; then
|
|
#shellcheck disable=SC2153
|
|
editor="$EDITOR"
|
|
fi
|
|
if [ "$editor" = "" ]; then
|
|
if command -v nano >/dev/null; then
|
|
editor="nano"
|
|
elif command -v nano-tiny >/dev/null; then
|
|
editor="nano-tiny"
|
|
elif command -v vi >/dev/null; then
|
|
editor="vi"
|
|
else
|
|
echo "No editor found"
|
|
exit 1
|
|
fi
|
|
fi
|
|
"$editor" "$1"
|
|
}
|
|
|
|
detect_edit_validate() {
|
|
setup_yaml_path="$1"
|
|
while true; do
|
|
cat <<-EOT >"$setup_yaml_path"
|
|
#
|
|
# XXX detection timestamp, how to edit
|
|
# blah blah blah
|
|
#
|
|
# Out of safety, we recommend installing the parser 'crowdsecurity/whitelists'.
|
|
# It will prevent private IP addresses from being banned. It's an anti-lockout measure,
|
|
# feel free to remove it any time.
|
|
#
|
|
|
|
EOT
|
|
|
|
echo
|
|
"$CSCLI_BIN_INSTALLED" setup detect --yaml | tee -a "$setup_yaml_path"
|
|
|
|
#
|
|
# If the user asked for --unattended, or the script is not interactive,
|
|
# we use the detected setup without changes.
|
|
#
|
|
if ! interactive; then
|
|
return 0
|
|
fi
|
|
|
|
printf '%s ' "Crowdsec has detected these services. Do you want to edit the list now? (Y/n)"
|
|
read -r confirm
|
|
|
|
if echo "$confirm" | grep -q '^[Nn]'; then
|
|
return 0
|
|
fi
|
|
|
|
while true; do
|
|
edit_file "$setup_yaml_path"
|
|
|
|
if ! errors=$("$CSCLI_BIN_INSTALLED" setup validate "$setup_yaml_path" 2>/dev/null); then
|
|
echo
|
|
echo "The setup file has errors:"
|
|
echo
|
|
|
|
if [ "$errors" = "EOF" ]; then
|
|
errors="The file is empty. A 'setup:' section is required, even if it has no items."
|
|
fi
|
|
|
|
echo "$errors"
|
|
echo
|
|
printf '%s ' "[E]dit, [D]etect again, [Q]uit configuration? (E/d/q)"
|
|
|
|
read -r confirm
|
|
|
|
if echo "$confirm" | grep -q '^[Dd]'; then
|
|
break
|
|
fi
|
|
|
|
if echo "$confirm" | grep -q '^[Qq]'; then
|
|
rm -f "$setup_yaml_path"
|
|
return 1
|
|
fi
|
|
else
|
|
return 0
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
# Pause until the user types <enter>
|
|
# unless the script is run in non-interactive mode.
|
|
ask_press_enter() {
|
|
if ! interactive; then
|
|
return 0
|
|
fi
|
|
|
|
printf "%s " "Press Enter to continue:" >&2
|
|
read -r key
|
|
}
|
|
|
|
# Check if we can proceed with the automatic detection and hub + acquisition configuration.
|
|
# If the script is interactive, we ask the user for confirmation when it makes sense.
|
|
#
|
|
# arguments: none
|
|
# return: 0 if we can proceed with the configuration, 1 if we should skip it.
|
|
safe_to_configure() {
|
|
# if "wizard.sh" is in ACQUIS_YAML, never detect
|
|
if grep -q 'wizard.sh' "$ACQUIS_YAML" 2>/dev/null; then
|
|
cat <<-EOT >&2
|
|
|
|
A previous version of Crowdsec has detected the running services and put
|
|
datasource configuration in the file $ACQUIS_YAML.
|
|
|
|
In this version, the same information goes in $ACQUIS_DIR, one
|
|
file per service.
|
|
|
|
If you want to run the automated service detection again, please remove the
|
|
relevant sections from $ACQUIS_YAML or rename the file, and run "$0 --configure"
|
|
again.
|
|
|
|
EOT
|
|
|
|
ask_press_enter
|
|
return 1
|
|
fi
|
|
|
|
# if acquis.yaml exists but has no wizard.sh, ask for confirmation (if
|
|
# interactive) before detecting
|
|
if [ -f "$ACQUIS_YAML" ]; then
|
|
|
|
if ! interactive; then
|
|
echo "Skipping automatic detection because $ACQUIS_YAML already exists." >&2
|
|
echo "Run \"$0 --configure\" to detect the services again." >&2
|
|
return 1
|
|
fi
|
|
|
|
cat <<-EOT >&2
|
|
|
|
A previous version of Crowdsec was already configured.
|
|
|
|
If you run the automated service detection now, it will create new acquisition
|
|
directives in $ACQUIS_DIR, in addition to the ones already in $ACQUIS_YAML.
|
|
|
|
When the configuration is done, please check the content of these files
|
|
to avoid duplicate log locations.
|
|
|
|
EOT
|
|
|
|
printf '%s ' "Do you want to run the service detection now? (y/N)"
|
|
read -r confirm
|
|
|
|
if echo "$confirm" | grep -q '^[Nn]'; then
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
detect_and_install_hub() {
|
|
if ! safe_to_configure; then
|
|
return 1
|
|
fi
|
|
|
|
tmp_dir=$(mktemp -d)
|
|
tmp_file="$tmp_dir/setup.yaml"
|
|
|
|
if ! detect_edit_validate "$tmp_file"; then
|
|
echo
|
|
echo "Exiting crowdsec configuration, you can run it again with '$0 --configure'" >&2
|
|
ask_press_enter
|
|
|
|
rm -f "$tmp_file"
|
|
rmdir "$tmp_dir"
|
|
return 1
|
|
fi
|
|
|
|
echo "Installing hub objects...."
|
|
"$CSCLI_BIN_INSTALLED" setup install-hub "$tmp_file"
|
|
|
|
mkdir -p "$ACQUIS_DIR"
|
|
|
|
echo "Generating acquisition files..."
|
|
"$CSCLI_BIN_INSTALLED" setup datasources "$tmp_file" --to-dir "$ACQUIS_DIR"
|
|
|
|
if [ ! -f "$ACQUIS_YAML" ]; then
|
|
cat <<-EOT >"$ACQUIS_YAML"
|
|
---
|
|
# Your datasource configuration goes here.
|
|
EOT
|
|
fi
|
|
|
|
echo "Done"
|
|
|
|
rm -f "$tmp_file"
|
|
rmdir "$tmp_dir"
|
|
}
|
|
|
|
install_plugins() {
|
|
for plugin in email http slack splunk; do
|
|
mkdir -p "$PLUGIN_BINARIES_DEST"
|
|
install -m 0755 "$PLUGIN_BINARIES_SRC/$plugin/notification-$plugin" "$PLUGIN_BINARIES_DEST/"
|
|
|
|
if [ "$DOCKER_MODE" = "false" ]; then
|
|
if [ -f "$PLUGIN_CONFIGURATION_DEST/$plugin/$plugin.yaml" ]; then
|
|
chmod 0600 "$PLUGIN_CONFIGURATION_DEST/$plugin/$plugin.yaml"
|
|
else
|
|
mkdir -p "$PLUGIN_CONFIGURATION_DEST/$plugin"
|
|
install -m 0600 "$PLUGIN_CONFIGURATION_SRC/$plugin/$plugin.yaml" "$PLUGIN_CONFIGURATION_DEST/$plugin/$plugin.yaml"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_running_bouncers() {
|
|
# when uninstalling, check if the user still has bouncers
|
|
BOUNCERS_COUNT=$("$CSCLI_BIN" bouncers list -o=raw | tail -n +2 | wc -l)
|
|
if [ "$BOUNCERS_COUNT" -gt 0 ]; then
|
|
if [ "$FORCE_MODE" = "false" ]; then
|
|
echo "WARNING: You have at least one bouncer registered (cscli bouncers list)."
|
|
echo "WARNING: Uninstalling crowdsec with a running bouncer will leave it in an unpredictable state."
|
|
echo "WARNING: If you want to uninstall crowdsec, you should first uninstall the bouncers."
|
|
echo "Specify --force to bypass this restriction."
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# uninstall crowdsec and cscli
|
|
uninstall_crowdsec() {
|
|
crowdsec_service_stop
|
|
crowdsec_service_disable
|
|
# there is no way to know if the dashboard exists, so we have to ignore errors.
|
|
log_info "Removing dashboard..."
|
|
if "$CSCLI_BIN" dashboard remove -f -y; then
|
|
log_info "...done."
|
|
else
|
|
log_warn "...dashboard removal failed."
|
|
fi
|
|
delete_bins
|
|
|
|
rm -f -- "$CROWDSEC_LOG_FILE" "$LAPI_LOG_FILE" "$CROWDSEC_DB_PATH" "$SYSTEMD_PATH_FILE"
|
|
rm -rf -- "$CROWDSEC_LIB_DIR" "$CROWDSEC_USR_DIR"
|
|
log_info "crowdsec successfully uninstalled"
|
|
}
|
|
|
|
show_links() {
|
|
cat <<-EOT
|
|
|
|
Useful links to start with Crowdsec:
|
|
|
|
- Documentation : ${BOLD}https://doc.crowdsec.net/docs/getting_started/crowdsec_tour${RESET}
|
|
- Crowdsec Hub : ${BOLD}https://hub.crowdsec.net/${RESET}
|
|
- Open issues : https://github.com/crowdsecurity/crowdsec/issues
|
|
|
|
Useful commands to start with Crowdsec:
|
|
|
|
- sudo cscli metrics : https://doc.crowdsec.net/docs/observability/cscli
|
|
- sudo cscli decisions list : https://doc.crowdsec.net/docs/user_guides/decisions_mgmt
|
|
- sudo cscli hub list : https://doc.crowdsec.net/docs/user_guides/hub_mgmt
|
|
|
|
Next step: visualize all your alerts and explore our community CTI - ${BOLD}https://app.crowdsec.net${RESET}
|
|
|
|
CrowdSec alone will ${FG_YELLOW}${BOLD}not${RESET} block any IP address. If you want to block them, you must use a bouncer.
|
|
You can find them on ${BOLD}https://hub.crowdsec.net/browse/#bouncers${RESET}
|
|
|
|
EOT
|
|
}
|
|
|
|
main() {
|
|
if [ "$1" = "install" ] || [ "$1" = "configure" ] || [ "$1" = "detect" ]; then
|
|
if ! command -v envsubst >/dev/null; then
|
|
log_fatal "envsubst binary is needed to use do a full install with the wizard, exiting..."
|
|
fi
|
|
fi
|
|
|
|
if [ "$1" = "binupgrade" ]; then
|
|
checkroot
|
|
check_cs_version
|
|
update_bins
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "upgrade" ]; then
|
|
checkroot
|
|
check_cs_version
|
|
update_full
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "configure" ]; then
|
|
checkroot
|
|
"$CSCLI_BIN_INSTALLED" hub update
|
|
detect_and_install_hub
|
|
crowdsec_service_restart
|
|
show_links
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "noop" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "uninstall" ]; then
|
|
checkroot
|
|
check_running_bouncers
|
|
uninstall_crowdsec
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "bininstall" ]; then
|
|
checkroot
|
|
log_info "checking existing crowdsec install"
|
|
detect_cs_install
|
|
log_info "installing crowdsec"
|
|
install_crowdsec
|
|
|
|
show_links
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "install" ]; then
|
|
checkroot
|
|
log_info "checking if crowdsec is installed"
|
|
detect_cs_install
|
|
|
|
# Run "make release" before installing (as non-root) in order to have the binary and then install crowdsec as root
|
|
|
|
log_info "installing crowdsec"
|
|
install_crowdsec
|
|
log_dbg "configuring ${CSCLI_BIN_INSTALLED}"
|
|
|
|
if ! "$CSCLI_BIN_INSTALLED" hub update >/dev/null 2>&1; then
|
|
log_err "fail to update crowdsec hub. exiting"
|
|
exit 1
|
|
fi
|
|
|
|
"$CSCLI_BIN_INSTALLED" hub update
|
|
|
|
# install patterns/ folder
|
|
log_dbg "Installing patterns"
|
|
mkdir -p "$PATTERNS_PATH"
|
|
cp "./${PATTERNS_FOLDER}/"* "${PATTERNS_PATH}/"
|
|
|
|
# register api
|
|
"$CSCLI_BIN_INSTALLED" machines add --force "$(cat /etc/machine-id)" -a -f "${CROWDSEC_CONFIG_PATH}/${CLIENT_SECRETS}" || log_fatal "unable to add machine to the local API"
|
|
log_dbg "Crowdsec LAPI registered"
|
|
|
|
"$CSCLI_BIN_INSTALLED" capi register || log_fatal "unable to register to the Central API"
|
|
log_dbg "Crowdsec CAPI registered"
|
|
|
|
detect_and_install_hub
|
|
|
|
systemctl enable -q crowdsec >/dev/null || log_fatal "unable to enable crowdsec"
|
|
systemctl start crowdsec >/dev/null || log_fatal "unable to start crowdsec"
|
|
log_info "enabling and starting crowdsec daemon"
|
|
|
|
show_links
|
|
return 0
|
|
fi
|
|
|
|
if [ "$1" = "detect" ]; then
|
|
detect_only
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
echo "Usage:"
|
|
echo " ./wizard.sh -h Display this help message."
|
|
echo " ./wizard.sh -c|--configure Detect running services and install hub objects + acquis files"
|
|
echo " ./wizard.sh -d|--detect Detect running services and print the result"
|
|
echo " ./wizard.sh -i|--install Assisted installation of crowdsec/cscli and hub objects"
|
|
echo " ./wizard.sh --bininstall Install binaries and empty config, no wizard."
|
|
echo " ./wizard.sh --uninstall Uninstall crowdsec/cscli"
|
|
echo " ./wizard.sh --binupgrade Upgrade crowdsec/cscli binaries"
|
|
echo " ./wizard.sh --upgrade Perform a full upgrade and try to migrate configs"
|
|
echo " ./wizard.sh --unattended Install in unattended mode, no question will be asked and defaults will be followed"
|
|
echo " ./wizard.sh --docker-mode Will install crowdsec without systemd and generate random machine-id"
|
|
echo " ./wizard.sh -n|--noop Do nothing"
|
|
}
|
|
|
|
if [ $# -eq 0 ]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
while [ $# -gt 0 ]; do
|
|
key="${1}"
|
|
case ${key} in
|
|
--uninstall)
|
|
ACTION="uninstall"
|
|
shift #past argument
|
|
;;
|
|
--binupgrade)
|
|
ACTION="binupgrade"
|
|
shift #past argument
|
|
;;
|
|
--upgrade)
|
|
ACTION="upgrade"
|
|
shift #past argument
|
|
;;
|
|
-i | --install)
|
|
ACTION="install"
|
|
shift # past argument
|
|
;;
|
|
--bininstall)
|
|
ACTION="bininstall"
|
|
shift # past argument
|
|
;;
|
|
--docker-mode)
|
|
DOCKER_MODE="true"
|
|
ACTION="bininstall"
|
|
shift # past argument
|
|
;;
|
|
-c | --configure)
|
|
ACTION="configure"
|
|
shift # past argument
|
|
;;
|
|
-d | --detect)
|
|
ACTION="detect"
|
|
shift # past argument
|
|
;;
|
|
-n | --noop)
|
|
ACTION="noop"
|
|
shift # past argument
|
|
;;
|
|
--unattended)
|
|
SILENT="true"
|
|
ACTION="install"
|
|
shift
|
|
;;
|
|
-f | --force)
|
|
FORCE_MODE="true"
|
|
shift
|
|
;;
|
|
-v | --verbose)
|
|
DEBUG_MODE="true"
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*) # unknown option
|
|
log_err "Unknown argument ${key}."
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
set_colors
|
|
main "$ACTION"
|
|
exit 0
|