CI / changes (push) Successful in 10s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 57s
CI / go (push) Successful in 1m11s
CI / bird2 (push) Successful in 15s
CI / release (push) Successful in 4m16s
Added a community selection feature to the firewall rules management UI, allowing users to specify BGP communities for block/accept policies. Updated the backend to support reading firewall scripts from a specified directory, improving script management. Enhanced documentation to clarify the new community functionality and its implications for firewall rules. Additionally, introduced tests for the firewall script endpoints to ensure proper functionality.
111 lines
3.0 KiB
Bash
111 lines
3.0 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
|
|
|
|
: "${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")
|
|
|
|
RESP=$(curl -fsS -X POST "${CP_URL}/v1/firewall/enroll" \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-EvoBGP-Seed: ${EVOBGP_SEED}" \
|
|
-d "$ENROLL_BODY")
|
|
|
|
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
|
|
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 → Запросы"
|