feat(api): add uninstall script and enhance install script functionality
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 1m45s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped

- Introduced an uninstall script for agents, allowing users to easily remove the agent with a single command.
- Updated `install.sh` to quote configuration values for safety, ensuring compatibility with names containing spaces.
- Enhanced the installation process to include a warning if the uninstall script cannot be downloaded.
- Updated documentation to reflect the new uninstall functionality and changes in configuration file handling.
This commit is contained in:
Denozordec
2026-07-21 22:53:28 +07:00
parent d44f1113df
commit 38f7a8296e
5 changed files with 77 additions and 10 deletions
+18 -9
View File
@@ -178,17 +178,25 @@ fi
mkdir -p "$CONF_DIR"
chmod 700 "$CONF_DIR"
cat >"$CONF_FILE" <<EOF
EVOFW_CP_URL=${CP_URL}
CLIENT_ID=${CLIENT_ID}
CLIENT_TOKEN=${CLIENT_TOKEN}
CLIENT_NAME=${EVOFW_CLIENT_NAME}
KERNEL_BACKEND=auto
EOF
# Quote all values — names with spaces must not break `source agent.conf`.
{
printf 'EVOFW_CP_URL=%q\n' "$CP_URL"
printf 'CLIENT_ID=%q\n' "$CLIENT_ID"
printf 'CLIENT_TOKEN=%q\n' "$CLIENT_TOKEN"
printf 'CLIENT_NAME=%q\n' "$EVOFW_CLIENT_NAME"
printf 'KERNEL_BACKEND=%q\n' "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
@@ -199,8 +207,8 @@ else
echo "no supported firewall backend" >&2
exit 1
fi
sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=${BACKEND}/" "$CONF_FILE" 2>/dev/null || \
echo "KERNEL_BACKEND=${BACKEND}" >>"$CONF_FILE"
sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=$(printf '%q' "$BACKEND")/" "$CONF_FILE" 2>/dev/null || \
printf 'KERNEL_BACKEND=%q\n' "$BACKEND" >>"$CONF_FILE"
INTERVAL="${EVOFW_SYNC_INTERVAL:-1min}"
if [[ "$HAS_SYSTEMD" -eq 1 ]]; then
@@ -239,3 +247,4 @@ fi
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 "Uninstall: $UNINSTALL_SCRIPT (or: curl -fsSL ${CP_URL}/v1/agent/uninstall.sh | bash)"
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# EvoFirewall Linux agent uninstall
set -euo pipefail
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
echo "evofw uninstall: run as root" >&2
exit 1
fi
echo "evofw uninstall: stopping timer/service..."
if command -v systemctl >/dev/null 2>&1; then
systemctl disable --now evofw-firewall.timer 2>/dev/null || true
systemctl stop evofw-firewall.service 2>/dev/null || true
rm -f /etc/systemd/system/evofw-firewall.timer \
/etc/systemd/system/evofw-firewall.service
systemctl daemon-reload 2>/dev/null || true
systemctl reset-failed evofw-firewall.service 2>/dev/null || true
systemctl reset-failed evofw-firewall.timer 2>/dev/null || true
fi
if command -v crontab >/dev/null 2>&1; then
crontab -l 2>/dev/null | grep -v evofw-firewall | crontab - 2>/dev/null || true
fi
echo "evofw uninstall: removing files..."
rm -f /usr/local/sbin/evofw-firewall.sh
rm -f /usr/local/sbin/evofw-uninstall.sh
rm -rf /etc/evofw /var/lib/evofw
rm -f /var/log/evofw-firewall.log
echo "evofw uninstall: removing nft table (if any)..."
if command -v nft >/dev/null 2>&1; then
nft delete table inet evofw 2>/dev/null || true
fi
if command -v iptables >/dev/null 2>&1; then
iptables -D INPUT -m set --match-set evofw_deny_v4 src -j DROP 2>/dev/null || true
iptables -D INPUT -m set --match-set evofw_allow_v4 src -j ACCEPT 2>/dev/null || true
fi
if command -v ipset >/dev/null 2>&1; then
ipset destroy evofw_deny_v4 2>/dev/null || true
ipset destroy evofw_allow_v4 2>/dev/null || true
fi
echo "evofw uninstall: done (revoke/delete agent in EvoFirewall UI if needed)."
+1
View File
@@ -50,6 +50,7 @@ function isPublicPath(url: string): boolean {
if (path.startsWith('/v1/agent/enroll')) return true
if (path.startsWith('/v1/agent/install')) return true
if (path.startsWith('/v1/agent/sync-script')) return true
if (path.startsWith('/v1/agent/uninstall')) return true
if (path.startsWith('/v1/agent/mikrotik')) return true
return false
}
+5
View File
@@ -44,6 +44,11 @@ export const agentRoutes: FastifyPluginAsync<{ config: AppConfig }> = async (
return reply.type('text/x-shellscript').send(body)
})
app.get('/v1/agent/uninstall.sh', async (_req, reply) => {
const body = readFileSync(join(scriptsDir, 'uninstall.sh'), 'utf-8')
return reply.type('text/x-shellscript').send(body)
})
app.get('/v1/agent/mikrotik-install.rsc', async (_req, reply) => {
const body = readFileSync(
join(scriptsDir, 'mikrotik-install.rsc'),
+8 -1
View File
@@ -36,7 +36,14 @@ curl -fsSL https://<cp>/v1/agent/install.sh | \
Файлы: `/etc/evofw/agent.conf`, `/usr/local/sbin/evofw-firewall.sh`, timer `evofw-firewall.timer` (default 1min).
Install сам ставит зависимости через apt/dnf/yum/apk: `curl`, `jq` (или `python3`), `nftables`/`iptables`(+`ipset`). Планировщик: **systemd timer** если есть `/run/systemd/system`, иначе ставит `cron`/`cronie` и пишет crontab.
Install сам ставит зависимости через apt/dnf/yum/apk: `curl`, `jq` (или `python3`), `nftables`/`iptables`(+`ipset`). Планировщик: **systemd timer** если есть `/run/systemd/system`, иначе ставит `cron`/`cronie` и пишет crontab. Значения в `agent.conf` пишутся через `printf %q` (имена с пробелами безопасны).
**Uninstall (Linux):**
```bash
curl -fsSL https://<cp>/v1/agent/uninstall.sh | bash
# или локально после install:
sudo /usr/local/sbin/evofw-uninstall.sh
```
Backend auto-detect: nft → ipset → iptables.