When the api key contains a '/' character, if the yaml field is not quoted it will include the comment as well. fix: quote the field and remove the comment with the bouncer name. PR: 276096 MFH: 2024Q1
102 lines
3.0 KiB
Bash
102 lines
3.0 KiB
Bash
#!/bin/sh
|
|
#
|
|
# PROVIDE: crowdsec_firewall
|
|
# REQUIRE: LOGIN DAEMON NETWORKING
|
|
# KEYWORD: shutdown
|
|
#
|
|
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
|
|
# to enable this service:
|
|
#
|
|
# crowdsec_firewall_enable (bool): Set it to YES to enable crowdsec firewall.
|
|
# Default is "NO"
|
|
# crowdsec_firewall_config (str): Set the bouncer config path.
|
|
# Default is "%%ETCDIR%%/crowdsec-firewall-bouncer.yaml"
|
|
# crowdsec_firewall_name (str): Name of the bouncer to register.
|
|
# Default is dynamically generated.
|
|
# crowdsec_firewall_flags (str): extra flags to run bouncer.
|
|
# Default is ""
|
|
|
|
. /etc/rc.subr
|
|
|
|
name=crowdsec_firewall
|
|
desc="Crowdsec Firewall"
|
|
rcvar=crowdsec_firewall_enable
|
|
|
|
load_rc_config "$name"
|
|
|
|
: "${crowdsec_firewall_enable:=NO}"
|
|
: "${crowdsec_firewall_config:=%%ETCDIR%%/crowdsec-firewall-bouncer.yaml}"
|
|
: "${crowdsec_firewall_name:=cs-firewall-bouncer-$(date +%s)}"
|
|
: "${crowdsec_firewall_flags:=}"
|
|
|
|
pidfile=/var/run/${name}.pid
|
|
required_files="$crowdsec_firewall_config"
|
|
command="%%PREFIX%%/bin/crowdsec-firewall-bouncer"
|
|
start_cmd="${name}_start"
|
|
stop_cmd="${name}_stop"
|
|
start_precmd="${name}_precmd"
|
|
configtest_cmd="${name}_configtest"
|
|
extra_commands="configtest"
|
|
|
|
crowdsec_firewall_precmd() {
|
|
CSCLI=%%PREFIX%%/bin/cscli
|
|
# there might be quotes
|
|
orig_line="api_key: .*\${API_KEY}.*"
|
|
# IF the bouncer is not configured
|
|
if grep -q "^${orig_line}" "${crowdsec_firewall_config}"; then
|
|
# AND crowdsec is installed..
|
|
if command -v "$CSCLI" >/dev/null; then
|
|
# THEN, register it to the local API
|
|
API_KEY=$($CSCLI bouncers add "${crowdsec_firewall_name}" -o raw)
|
|
if [ -n "$API_KEY" ]; then
|
|
sed -i "" "s|^${orig_line}|api_key: '${API_KEY}'|" "${crowdsec_firewall_config}"
|
|
echo "Registered: ${crowdsec_firewall_name}"
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
crowdsec_firewall_stop()
|
|
{
|
|
if [ ! -f "$pidfile" ]; then
|
|
echo "${name} is not running."
|
|
return
|
|
fi
|
|
pid=$(cat "$pidfile")
|
|
if kill -0 "$pid" >/dev/null 2>&1; then
|
|
echo "Stopping ${name}."
|
|
kill -s TERM "$pid" >/dev/null 2>&1
|
|
# shellcheck disable=SC2034
|
|
for i in $(seq 1 20); do
|
|
sleep 1
|
|
if ! kill -0 "$pid" >/dev/null 2>&1; then
|
|
rm -f "$pidfile"
|
|
return
|
|
fi
|
|
done
|
|
echo "Timeout, terminating ${name} with SIGKILL."
|
|
kill -s KILL "$pid" >/dev/null 2>&1
|
|
rm -f "$pidfile"
|
|
else
|
|
echo "${name} is not running."
|
|
fi
|
|
}
|
|
|
|
crowdsec_firewall_start() {
|
|
# ensure we have a backend if the config file was not patched
|
|
export BACKEND=pf
|
|
# shellcheck disable=SC2086
|
|
/usr/sbin/daemon -f -p "$pidfile" -t "$desc" -- \
|
|
"$command" -c "$crowdsec_firewall_config" ${crowdsec_firewall_flags}
|
|
}
|
|
|
|
crowdsec_firewall_configtest()
|
|
{
|
|
echo "Performing sanity check on ${name} configuration."
|
|
if "$command" -c "$crowdsec_firewall_config" -t; then
|
|
echo "Configuration test OK"
|
|
fi
|
|
}
|
|
|
|
run_rc_command "$1"
|