feat(api): add uninstall script and enhance install script functionality
- 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:
@@ -178,17 +178,25 @@ fi
|
|||||||
|
|
||||||
mkdir -p "$CONF_DIR"
|
mkdir -p "$CONF_DIR"
|
||||||
chmod 700 "$CONF_DIR"
|
chmod 700 "$CONF_DIR"
|
||||||
cat >"$CONF_FILE" <<EOF
|
# Quote all values — names with spaces must not break `source agent.conf`.
|
||||||
EVOFW_CP_URL=${CP_URL}
|
{
|
||||||
CLIENT_ID=${CLIENT_ID}
|
printf 'EVOFW_CP_URL=%q\n' "$CP_URL"
|
||||||
CLIENT_TOKEN=${CLIENT_TOKEN}
|
printf 'CLIENT_ID=%q\n' "$CLIENT_ID"
|
||||||
CLIENT_NAME=${EVOFW_CLIENT_NAME}
|
printf 'CLIENT_TOKEN=%q\n' "$CLIENT_TOKEN"
|
||||||
KERNEL_BACKEND=auto
|
printf 'CLIENT_NAME=%q\n' "$EVOFW_CLIENT_NAME"
|
||||||
EOF
|
printf 'KERNEL_BACKEND=%q\n' "auto"
|
||||||
|
} >"$CONF_FILE"
|
||||||
chmod 600 "$CONF_FILE"
|
chmod 600 "$CONF_FILE"
|
||||||
|
|
||||||
install -m 755 "$SYNC_TMP" "$SYNC_SCRIPT"
|
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
|
if command -v nft >/dev/null 2>&1; then
|
||||||
BACKEND=nft
|
BACKEND=nft
|
||||||
elif command -v ipset >/dev/null 2>&1 && command -v iptables >/dev/null 2>&1; then
|
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
|
echo "no supported firewall backend" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=${BACKEND}/" "$CONF_FILE" 2>/dev/null || \
|
sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=$(printf '%q' "$BACKEND")/" "$CONF_FILE" 2>/dev/null || \
|
||||||
echo "KERNEL_BACKEND=${BACKEND}" >>"$CONF_FILE"
|
printf 'KERNEL_BACKEND=%q\n' "$BACKEND" >>"$CONF_FILE"
|
||||||
|
|
||||||
INTERVAL="${EVOFW_SYNC_INTERVAL:-1min}"
|
INTERVAL="${EVOFW_SYNC_INTERVAL:-1min}"
|
||||||
if [[ "$HAS_SYSTEMD" -eq 1 ]]; then
|
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 "Installed. Client id=${CLIENT_ID}. Approve in EvoFirewall UI (rules optional — can assign later)."
|
||||||
echo "If still offline after Approve, run: $SYNC_SCRIPT"
|
echo "If still offline after Approve, run: $SYNC_SCRIPT"
|
||||||
|
echo "Uninstall: $UNINSTALL_SCRIPT (or: curl -fsSL ${CP_URL}/v1/agent/uninstall.sh | bash)"
|
||||||
|
|||||||
@@ -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)."
|
||||||
@@ -50,6 +50,7 @@ function isPublicPath(url: string): boolean {
|
|||||||
if (path.startsWith('/v1/agent/enroll')) return true
|
if (path.startsWith('/v1/agent/enroll')) return true
|
||||||
if (path.startsWith('/v1/agent/install')) return true
|
if (path.startsWith('/v1/agent/install')) return true
|
||||||
if (path.startsWith('/v1/agent/sync-script')) 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
|
if (path.startsWith('/v1/agent/mikrotik')) return true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ export const agentRoutes: FastifyPluginAsync<{ config: AppConfig }> = async (
|
|||||||
return reply.type('text/x-shellscript').send(body)
|
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) => {
|
app.get('/v1/agent/mikrotik-install.rsc', async (_req, reply) => {
|
||||||
const body = readFileSync(
|
const body = readFileSync(
|
||||||
join(scriptsDir, 'mikrotik-install.rsc'),
|
join(scriptsDir, 'mikrotik-install.rsc'),
|
||||||
|
|||||||
+8
-1
@@ -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).
|
Файлы: `/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.
|
Backend auto-detect: nft → ipset → iptables.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user