CI / changes (push) Successful in 11s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 29s
CI / web (push) Successful in 58s
CI / go (push) Successful in 1m20s
CI / bird2 (push) Successful in 18s
CI / release (push) Successful in 4m37s
Updated the firewall scripts to improve blocklist handling by introducing a new method for fetching and parsing blocklist data using either `jq` or `python3`. Enhanced the installation script to ensure the presence of required dependencies and provided user guidance for post-approval actions. Additionally, improved logging for applied prefixes and total counts, ensuring better visibility into the firewall's operational status.
130 lines
3.7 KiB
Bash
130 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
|
echo "evobgp-firewall install: run as root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
for cmd in curl bash; do
|
|
command -v "$cmd" >/dev/null 2>&1 || { echo "missing $cmd" >&2; exit 1; }
|
|
done
|
|
|
|
if ! command -v jq >/dev/null 2>&1 && ! command -v python3 >/dev/null 2>&1; then
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update -qq && apt-get install -y -qq jq
|
|
fi
|
|
fi
|
|
if ! command -v jq >/dev/null 2>&1 && ! command -v python3 >/dev/null 2>&1; then
|
|
echo "evobgp-firewall install: install jq or python3 for blocklist JSON parsing" >&2
|
|
exit 1
|
|
fi
|
|
|
|
: "${EVOBGP_CP_URL:?EVOBGP_CP_URL required}"
|
|
: "${EVOBGP_SEED:?EVOBGP_SEED required}"
|
|
: "${EVOBGP_CLIENT_NAME:?EVOBGP_CLIENT_NAME required}"
|
|
|
|
CONF_DIR=/etc/evobgp
|
|
CONF_FILE="${CONF_DIR}/firewall.conf"
|
|
SYNC_SCRIPT=/usr/local/sbin/evobgp-firewall.sh
|
|
|
|
if [[ -f "$CONF_FILE" && "${EVOBGP_INSTALL_FORCE:-}" != "1" ]]; then
|
|
echo "Already installed ($CONF_FILE). Set EVOBGP_INSTALL_FORCE=1 to reinstall." >&2
|
|
exit 1
|
|
fi
|
|
|
|
gen_token() {
|
|
if command -v openssl >/dev/null 2>&1; then
|
|
echo -n "evobgp_fw_$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')"
|
|
else
|
|
echo -n "evobgp_fw_$(head -c 32 /dev/urandom | base64 | tr '+/' '-_' | tr -d '=\n')"
|
|
fi
|
|
}
|
|
|
|
CLIENT_TOKEN="$(gen_token)"
|
|
HOSTNAME="$(hostname -f 2>/dev/null || hostname)"
|
|
CP_URL="${EVOBGP_CP_URL%/}"
|
|
|
|
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","client_token":"%s","client_version":"install.sh/1"}' \
|
|
"$EVOBGP_CLIENT_NAME" "$HOSTNAME" "$CLIENT_TOKEN")
|
|
|
|
ENROLL_TMP=$(mktemp)
|
|
trap 'rm -f "$ENROLL_TMP"' EXIT
|
|
ENROLL_CODE=$(curl -sS -o "$ENROLL_TMP" -w "%{http_code}" -X POST "${CP_URL}/v1/firewall/enroll" \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
|
-d "$ENROLL_BODY")
|
|
if [[ "$ENROLL_CODE" != "201" ]]; then
|
|
echo "evobgp-firewall enroll failed: HTTP ${ENROLL_CODE} from ${CP_URL}/v1/firewall/enroll" >&2
|
|
cat "$ENROLL_TMP" >&2
|
|
exit 1
|
|
fi
|
|
RESP=$(cat "$ENROLL_TMP")
|
|
|
|
CLIENT_ID=""
|
|
if command -v jq >/dev/null 2>&1; then
|
|
CLIENT_ID=$(echo "$RESP" | jq -r '.client_id')
|
|
else
|
|
CLIENT_ID=$(echo "$RESP" | sed -n 's/.*"client_id"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
fi
|
|
|
|
mkdir -p "$CONF_DIR"
|
|
chmod 700 "$CONF_DIR"
|
|
cat >"$CONF_FILE" <<EOF
|
|
EVOBGP_CP_URL=${CP_URL}
|
|
CLIENT_ID=${CLIENT_ID}
|
|
CLIENT_TOKEN=${CLIENT_TOKEN}
|
|
CLIENT_NAME=${EVOBGP_CLIENT_NAME}
|
|
KERNEL_BACKEND=auto
|
|
EOF
|
|
chmod 600 "$CONF_FILE"
|
|
|
|
curl -fsSL "${CP_URL}/v1/firewall/sync-script" -o "$SYNC_SCRIPT"
|
|
chmod 755 "$SYNC_SCRIPT"
|
|
|
|
if command -v nft >/dev/null 2>&1; then
|
|
BACKEND=nft
|
|
elif command -v ipset >/dev/null 2>&1 && command -v iptables >/dev/null 2>&1; then
|
|
BACKEND=ipset
|
|
elif command -v iptables >/dev/null 2>&1; then
|
|
BACKEND=iptables
|
|
else
|
|
echo "no supported firewall backend (nft/ipset/iptables)" >&2
|
|
exit 1
|
|
fi
|
|
sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=${BACKEND}/" "$CONF_FILE" 2>/dev/null || \
|
|
echo "KERNEL_BACKEND=${BACKEND}" >>"$CONF_FILE"
|
|
|
|
INTERVAL="${EVOBGP_SYNC_INTERVAL:-5min}"
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
cat >/etc/systemd/system/evobgp-firewall.service <<'UNIT'
|
|
[Unit]
|
|
Description=EvoBGP firewall blocklist sync
|
|
After=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/evobgp-firewall.sh
|
|
UNIT
|
|
cat >/etc/systemd/system/evobgp-firewall.timer <<UNIT
|
|
[Unit]
|
|
Description=EvoBGP firewall sync timer
|
|
|
|
[Timer]
|
|
OnBootSec=2min
|
|
OnUnitActiveSec=${INTERVAL}
|
|
Unit=evobgp-firewall.service
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
UNIT
|
|
systemctl daemon-reload
|
|
systemctl enable --now evobgp-firewall.timer
|
|
echo "Tip: after UI approve, run: rm -f /var/lib/evobgp-firewall/last_hash && ${SYNC_SCRIPT}"
|
|
else
|
|
echo "*/5 * * * * root ${SYNC_SCRIPT}" >/etc/cron.d/evobgp-firewall
|
|
fi
|
|
|
|
echo "Client ID: ${CLIENT_ID}"
|
|
echo "Status: pending — approve in EvoBGP UI → Firewall → Запросы"
|