diff --git a/apps/api/src/agent-scripts/evofw-firewall.sh b/apps/api/src/agent-scripts/evofw-firewall.sh index 68e660f..50f923f 100644 --- a/apps/api/src/agent-scripts/evofw-firewall.sh +++ b/apps/api/src/agent-scripts/evofw-firewall.sh @@ -43,9 +43,13 @@ curl_policy() { return 0 } -if ! curl_policy "$POLICY_FILE"; then - rc=$? - [[ "$rc" == "2" ]] && exit 0 +# Do not use `if ! cmd; rc=$?` — after `!`, $? is 0, not the real status. +policy_rc=0 +curl_policy "$POLICY_FILE" || policy_rc=$? +if [[ "$policy_rc" -eq 2 ]]; then + exit 0 +fi +if [[ "$policy_rc" -ne 0 ]]; then exit 1 fi diff --git a/apps/api/src/agent-scripts/install.sh b/apps/api/src/agent-scripts/install.sh index bd9f236..a96afe5 100644 --- a/apps/api/src/agent-scripts/install.sh +++ b/apps/api/src/agent-scripts/install.sh @@ -178,13 +178,18 @@ fi mkdir -p "$CONF_DIR" chmod 700 "$CONF_DIR" -# Quote all values — names with spaces must not break `source agent.conf`. +# 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=%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" + 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" @@ -207,8 +212,15 @@ else echo "no supported firewall backend" >&2 exit 1 fi -sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=$(printf '%q' "$BACKEND")/" "$CONF_FILE" 2>/dev/null || \ - printf 'KERNEL_BACKEND=%q\n' "$BACKEND" >>"$CONF_FILE" +# 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 diff --git a/docs/agents.md b/docs/agents.md index 4a5afb0..4ba000d 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -36,7 +36,7 @@ curl -fsSL https:///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. Значения в `agent.conf` пишутся через `printf %q` (имена с пробелами безопасны). +Install сам ставит зависимости через apt/dnf/yum/apk: `curl`, `jq` (или `python3`), `nftables`/`iptables`(+`ipset`). Планировщик: **systemd timer** если есть `/run/systemd/system`, иначе ставит `cron`/`cronie` и пишет crontab. Значения в `agent.conf` всегда в single quotes (имена с пробелами безопасны). Sync при статусе pending завершается с exit 0 (`pending approval`), чтобы systemd timer не был failed. **Uninstall (Linux):** ```bash