feat(api, web): enhance agent traffic statistics and update installation scripts
- Improved the collection and reporting of agent traffic statistics, including total packets dropped and accepted, to provide a more comprehensive view of agent performance. - Updated the `evofw-firewall.sh` script to capture and report traffic statistics before chain recreation, ensuring accurate data retention. - Enhanced the installation script to support updates on already-installed agents, allowing for script and timer refresh without re-enrollment, while preserving existing credentials. - Refactored UI components to utilize new traffic statistics, improving clarity and user experience in displaying agent performance metrics. These changes enhance the overall functionality and usability of the agent management system, providing better insights and easier updates for users.
This commit is contained in:
1 parent
1b7d301153
commit
69e903aa1b
14 files changed
+293
-140
No files matched your search
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# EvoFirewall Linux install one-liner
|
||||
# Re-run on an already-installed host updates scripts/timer and keeps credentials
|
||||
# (unless EVOFW_INSTALL_FORCE=1 → full re-enroll).
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
|
||||
@@ -114,12 +116,19 @@ fi
|
||||
CONF_DIR=/etc/evofw
|
||||
CONF_FILE="${CONF_DIR}/agent.conf"
|
||||
SYNC_SCRIPT=/usr/local/sbin/evofw-firewall.sh
|
||||
UNINSTALL_SCRIPT=/usr/local/sbin/evofw-uninstall.sh
|
||||
PLATFORM="${EVOFW_PLATFORM:-linux}"
|
||||
# Capture CP from install-link / env before any `source` of agent.conf.
|
||||
CP_URL="${EVOFW_CP_URL%/}"
|
||||
LINK_CP_URL="$CP_URL"
|
||||
CLIENT_NAME_FROM_LINK="$EVOFW_CLIENT_NAME"
|
||||
|
||||
if [[ -f "$CONF_FILE" && "${EVOFW_INSTALL_FORCE:-}" != "1" ]]; then
|
||||
echo "Already installed ($CONF_FILE). Set EVOFW_INSTALL_FORCE=1 to reinstall." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Always single-quote values so names with spaces are safe under `source`.
|
||||
shell_quote() {
|
||||
local s=$1
|
||||
s=${s//\'/\'\\\'\'}
|
||||
printf "'%s'" "$s"
|
||||
}
|
||||
|
||||
gen_token() {
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
@@ -129,23 +138,132 @@ gen_token() {
|
||||
fi
|
||||
}
|
||||
|
||||
CLIENT_TOKEN="$(gen_token)"
|
||||
HOSTNAME="$(hostname -f 2>/dev/null || hostname)"
|
||||
CP_URL="${EVOFW_CP_URL%/}"
|
||||
detect_backend() {
|
||||
if command -v nft >/dev/null 2>&1; then
|
||||
echo nft
|
||||
elif command -v ipset >/dev/null 2>&1 && command -v iptables >/dev/null 2>&1; then
|
||||
echo ipset
|
||||
elif command -v iptables >/dev/null 2>&1; then
|
||||
echo iptables
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
write_conf() {
|
||||
local client_id=$1 client_token=$2 client_name=$3 backend=$4
|
||||
mkdir -p "$CONF_DIR"
|
||||
chmod 700 "$CONF_DIR"
|
||||
{
|
||||
printf 'EVOFW_CP_URL=%s\n' "$(shell_quote "$CP_URL")"
|
||||
printf 'CLIENT_ID=%s\n' "$(shell_quote "$client_id")"
|
||||
printf 'CLIENT_TOKEN=%s\n' "$(shell_quote "$client_token")"
|
||||
printf 'CLIENT_NAME=%s\n' "$(shell_quote "$client_name")"
|
||||
printf 'KERNEL_BACKEND=%s\n' "$(shell_quote "$backend")"
|
||||
} >"$CONF_FILE"
|
||||
chmod 600 "$CONF_FILE"
|
||||
}
|
||||
|
||||
install_sync_and_uninstall() {
|
||||
local sync_tmp=$1
|
||||
install -m 755 "$sync_tmp" "$SYNC_SCRIPT"
|
||||
if curl -fsSL "${CP_URL}/v1/agent/uninstall.sh" -o "$UNINSTALL_SCRIPT" 2>/dev/null; then
|
||||
chmod 755 "$UNINSTALL_SCRIPT"
|
||||
else
|
||||
echo "evofw install: warning — could not download uninstall.sh (optional)" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
enable_scheduler_and_run() {
|
||||
local interval="${EVOFW_SYNC_INTERVAL:-1min}"
|
||||
if [[ "$HAS_SYSTEMD" -eq 1 ]]; then
|
||||
cat >/etc/systemd/system/evofw-firewall.service <<'UNIT'
|
||||
[Unit]
|
||||
Description=EvoFirewall sync
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/evofw-firewall.sh
|
||||
UNIT
|
||||
cat >/etc/systemd/system/evofw-firewall.timer <<UNIT
|
||||
[Unit]
|
||||
Description=EvoFirewall sync timer
|
||||
|
||||
[Timer]
|
||||
OnBootSec=30s
|
||||
OnUnitActiveSec=${interval}
|
||||
AccuracySec=5s
|
||||
Persistent=true
|
||||
Unit=evofw-firewall.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
UNIT
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now evofw-firewall.timer
|
||||
# First/updated run now (pending → log "pending approval"; after Approve → empty policy is OK).
|
||||
systemctl start evofw-firewall.service || true
|
||||
else
|
||||
(crontab -l 2>/dev/null | grep -v evofw-firewall || true; echo "*/1 * * * * $SYNC_SCRIPT") | crontab -
|
||||
"$SYNC_SCRIPT" || true
|
||||
fi
|
||||
}
|
||||
|
||||
download_sync_script() {
|
||||
local out=$1
|
||||
if ! curl -fsSL "${CP_URL}/v1/agent/sync-script" -o "$out"; then
|
||||
echo "failed to download sync script from ${CP_URL}/v1/agent/sync-script" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! head -n1 "$out" | grep -q '^#!'; then
|
||||
echo "sync script is not a shell script (CP returned unexpected body)" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Fail fast: pull sync script before enroll so we never leave a DB agent without a local agent.
|
||||
SYNC_TMP=$(mktemp)
|
||||
ENROLL_TMP=$(mktemp)
|
||||
trap 'rm -f "$SYNC_TMP" "$ENROLL_TMP"' EXIT
|
||||
if ! curl -fsSL "${CP_URL}/v1/agent/sync-script" -o "$SYNC_TMP"; then
|
||||
echo "failed to download sync script from ${CP_URL}/v1/agent/sync-script" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! head -n1 "$SYNC_TMP" | grep -q '^#!'; then
|
||||
echo "sync script is not a shell script (CP returned unexpected body)" >&2
|
||||
exit 1
|
||||
|
||||
# --- Update path: agent already installed ---
|
||||
if [[ -f "$CONF_FILE" && "${EVOFW_INSTALL_FORCE:-}" != "1" ]]; then
|
||||
echo "evofw update: existing install at $CONF_FILE — refreshing scripts (credentials kept)"
|
||||
# shellcheck disable=SC1090
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$CONF_FILE"
|
||||
set +a
|
||||
if [[ -z "${CLIENT_ID:-}" || -z "${CLIENT_TOKEN:-}" ]]; then
|
||||
echo "evofw update: $CONF_FILE incomplete (need CLIENT_ID + CLIENT_TOKEN). Set EVOFW_INSTALL_FORCE=1 to re-enroll." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Prefer CP URL from this install link / env (stashed before source).
|
||||
CP_URL="${LINK_CP_URL%/}"
|
||||
CLIENT_NAME="${CLIENT_NAME_FROM_LINK:-${CLIENT_NAME:-unknown}}"
|
||||
BACKEND="$(detect_backend)"
|
||||
if [[ -z "$BACKEND" ]]; then
|
||||
echo "no supported firewall backend" >&2
|
||||
exit 1
|
||||
fi
|
||||
download_sync_script "$SYNC_TMP" || exit 1
|
||||
write_conf "$CLIENT_ID" "$CLIENT_TOKEN" "$CLIENT_NAME" "$BACKEND"
|
||||
install_sync_and_uninstall "$SYNC_TMP"
|
||||
enable_scheduler_and_run
|
||||
echo "Updated. Client id=${CLIENT_ID}. Sync script + timer refreshed."
|
||||
echo "Force sync: $SYNC_SCRIPT"
|
||||
echo "Uninstall: $UNINSTALL_SCRIPT (or: curl -fsSL ${CP_URL}/v1/agent/uninstall.sh | bash)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- Fresh install (or EVOFW_INSTALL_FORCE=1) ---
|
||||
CLIENT_TOKEN="$(gen_token)"
|
||||
HOSTNAME="$(hostname -f 2>/dev/null || hostname)"
|
||||
|
||||
# Fail fast: pull sync script before enroll so we never leave a DB agent without a local agent.
|
||||
download_sync_script "$SYNC_TMP" || exit 1
|
||||
|
||||
if [[ -n "${EVOFW_INSTALL_LINK_ID:-}" ]]; then
|
||||
ENROLL_BODY=$(printf '{"name":"%s","hostname":"%s","platform":"%s","token":"%s","client_version":"install.sh/1","install_link_id":"%s"}' \
|
||||
"$EVOFW_CLIENT_NAME" "$HOSTNAME" "$PLATFORM" "$CLIENT_TOKEN" "$EVOFW_INSTALL_LINK_ID")
|
||||
@@ -176,87 +294,17 @@ if [[ -z "$CLIENT_ID" || "$CLIENT_ID" == "null" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$CONF_DIR"
|
||||
chmod 700 "$CONF_DIR"
|
||||
# Always single-quote values so names with spaces are safe under `source`.
|
||||
shell_quote() {
|
||||
local s=$1
|
||||
s=${s//\'/\'\\\'\'}
|
||||
printf "'%s'" "$s"
|
||||
}
|
||||
{
|
||||
printf 'EVOFW_CP_URL=%s\n' "$(shell_quote "$CP_URL")"
|
||||
printf 'CLIENT_ID=%s\n' "$(shell_quote "$CLIENT_ID")"
|
||||
printf 'CLIENT_TOKEN=%s\n' "$(shell_quote "$CLIENT_TOKEN")"
|
||||
printf 'CLIENT_NAME=%s\n' "$(shell_quote "$EVOFW_CLIENT_NAME")"
|
||||
printf 'KERNEL_BACKEND=%s\n' "$(shell_quote "auto")"
|
||||
} >"$CONF_FILE"
|
||||
chmod 600 "$CONF_FILE"
|
||||
|
||||
install -m 755 "$SYNC_TMP" "$SYNC_SCRIPT"
|
||||
|
||||
UNINSTALL_SCRIPT=/usr/local/sbin/evofw-uninstall.sh
|
||||
if curl -fsSL "${CP_URL}/v1/agent/uninstall.sh" -o "$UNINSTALL_SCRIPT" 2>/dev/null; then
|
||||
chmod 755 "$UNINSTALL_SCRIPT"
|
||||
else
|
||||
echo "evofw install: warning — could not download uninstall.sh (optional)" >&2
|
||||
fi
|
||||
|
||||
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
|
||||
BACKEND="$(detect_backend)"
|
||||
if [[ -z "$BACKEND" ]]; then
|
||||
echo "no supported firewall backend" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Replace KERNEL_BACKEND line without breaking other quoted values.
|
||||
if grep -q '^KERNEL_BACKEND=' "$CONF_FILE"; then
|
||||
grep -v '^KERNEL_BACKEND=' "$CONF_FILE" >"${CONF_FILE}.tmp"
|
||||
printf 'KERNEL_BACKEND=%s\n' "$(shell_quote "$BACKEND")" >>"${CONF_FILE}.tmp"
|
||||
mv "${CONF_FILE}.tmp" "$CONF_FILE"
|
||||
chmod 600 "$CONF_FILE"
|
||||
else
|
||||
printf 'KERNEL_BACKEND=%s\n' "$(shell_quote "$BACKEND")" >>"$CONF_FILE"
|
||||
fi
|
||||
|
||||
INTERVAL="${EVOFW_SYNC_INTERVAL:-1min}"
|
||||
if [[ "$HAS_SYSTEMD" -eq 1 ]]; then
|
||||
cat >/etc/systemd/system/evofw-firewall.service <<'UNIT'
|
||||
[Unit]
|
||||
Description=EvoFirewall sync
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/sbin/evofw-firewall.sh
|
||||
UNIT
|
||||
cat >/etc/systemd/system/evofw-firewall.timer <<UNIT
|
||||
[Unit]
|
||||
Description=EvoFirewall sync timer
|
||||
|
||||
[Timer]
|
||||
OnBootSec=30s
|
||||
OnUnitActiveSec=${INTERVAL}
|
||||
AccuracySec=5s
|
||||
Persistent=true
|
||||
Unit=evofw-firewall.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
UNIT
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now evofw-firewall.timer
|
||||
# First run now (pending → log "pending approval"; after Approve → empty policy is OK).
|
||||
systemctl start evofw-firewall.service || true
|
||||
else
|
||||
(crontab -l 2>/dev/null | grep -v evofw-firewall || true; echo "*/1 * * * * $SYNC_SCRIPT") | crontab -
|
||||
"$SYNC_SCRIPT" || true
|
||||
fi
|
||||
write_conf "$CLIENT_ID" "$CLIENT_TOKEN" "$EVOFW_CLIENT_NAME" "$BACKEND"
|
||||
install_sync_and_uninstall "$SYNC_TMP"
|
||||
enable_scheduler_and_run
|
||||
|
||||
echo "Installed. Client id=${CLIENT_ID}. Approve in EvoFirewall UI (rules optional — can assign later)."
|
||||
echo "If still offline after Approve, run: $SYNC_SCRIPT"
|
||||
echo "Re-run the same install URL to update scripts without re-enroll."
|
||||
echo "Uninstall: $UNINSTALL_SCRIPT (or: curl -fsSL ${CP_URL}/v1/agent/uninstall.sh | bash)"
|
||||
Reference in new issue
Block a user