feat(api): enhance install script for dependency management and systemd integration
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 1m52s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped

- Refactored `install.sh` to improve package installation logic, supporting multiple package managers (apt, dnf, yum, apk).
- Added functions to ensure required packages (`curl`, `jq`, `python3`, `nftables`, `iptables`, `ipset`, `cron`) are installed only if missing.
- Implemented systemd timer support for scheduling, with fallback to cron if systemd is unavailable.
- Updated documentation to reflect changes in dependency installation and scheduling mechanisms.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-07-21 19:35:34 +07:00
co-authored by Cursor
parent d516a9a093
commit d44f1113df
2 changed files with 101 additions and 9 deletions
+99 -9
View File
@@ -7,13 +7,103 @@ if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
exit 1
fi
for cmd in curl bash; do
command -v "$cmd" >/dev/null 2>&1 || { echo "missing $cmd" >&2; exit 1; }
done
need_cmd() { command -v "$1" >/dev/null 2>&1; }
if ! command -v jq >/dev/null 2>&1 && ! command -v python3 >/dev/null 2>&1; then
if command -v apt-get >/dev/null 2>&1; then
apt-get update -qq && apt-get install -y -qq jq || true
pkg_install() {
# $@ = package names (distro-specific callers pass the right names)
if need_cmd apt-get; then
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq "$@"
elif need_cmd dnf; then
dnf install -y -q "$@"
elif need_cmd yum; then
yum install -y -q "$@"
elif need_cmd apk; then
apk add --no-cache "$@"
else
echo "evofw install: no supported package manager (apt/dnf/yum/apk)" >&2
return 1
fi
}
ensure_pkg() {
# $1 = command to check; remaining = package name(s) to install if missing
local bin=$1
shift
if need_cmd "$bin"; then
return 0
fi
echo "evofw install: installing $* (need $bin)..."
pkg_install "$@" || {
echo "evofw install: failed to install $* — install manually and retry" >&2
return 1
}
need_cmd "$bin"
}
# curl is required to fetch this script in the first place, but re-check for pipe/bash edge cases.
ensure_pkg curl curl || exit 1
need_cmd bash || { echo "missing bash" >&2; exit 1; }
# JSON parse for enroll; python3 is an acceptable fallback in sync script.
if ! need_cmd jq && ! need_cmd python3; then
ensure_pkg jq jq || ensure_pkg python3 python3 || {
echo "evofw install: need jq or python3" >&2
exit 1
}
fi
# Firewall tools: never reinstall/replace if already present.
if need_cmd nft; then
echo "evofw install: nft already present — skip firewall packages"
elif need_cmd iptables; then
echo "evofw install: iptables already present — skip nftables/iptables install"
if ! need_cmd ipset; then
echo "evofw install: installing ipset (optional companion for iptables)..."
pkg_install ipset 2>/dev/null || true
fi
else
echo "evofw install: no nft/iptables — installing firewall backend..."
if need_cmd apt-get; then
pkg_install nftables || pkg_install iptables || true
elif need_cmd dnf || need_cmd yum; then
pkg_install nftables || pkg_install iptables || true
elif need_cmd apk; then
pkg_install nftables || pkg_install iptables || true
fi
if need_cmd iptables && ! need_cmd nft && ! need_cmd ipset; then
pkg_install ipset 2>/dev/null || true
fi
fi
HAS_SYSTEMD=0
if need_cmd systemctl && [[ -d /run/systemd/system ]]; then
HAS_SYSTEMD=1
fi
# Cron only when systemd timer is unavailable.
if [[ "$HAS_SYSTEMD" -ne 1 ]]; then
if ! need_cmd crontab; then
echo "evofw install: no systemd — installing cron..."
if need_cmd apt-get; then
pkg_install cron || pkg_install cronie || true
elif need_cmd dnf || need_cmd yum; then
pkg_install cronie || true
elif need_cmd apk; then
pkg_install cronie || pkg_install dcron || true
fi
fi
if ! need_cmd crontab; then
echo "evofw install: crontab missing and could not be installed (need systemd or cron)" >&2
exit 1
fi
# Ensure cron daemon is running when we fall back to crontab.
if need_cmd systemctl; then
systemctl enable --now cron 2>/dev/null || \
systemctl enable --now crond 2>/dev/null || true
elif need_cmd service; then
service cron start 2>/dev/null || service crond start 2>/dev/null || true
fi
fi
@@ -113,7 +203,7 @@ sed -i "s/^KERNEL_BACKEND=.*/KERNEL_BACKEND=${BACKEND}/" "$CONF_FILE" 2>/dev/nul
echo "KERNEL_BACKEND=${BACKEND}" >>"$CONF_FILE"
INTERVAL="${EVOFW_SYNC_INTERVAL:-1min}"
if command -v systemctl >/dev/null 2>&1; then
if [[ "$HAS_SYSTEMD" -eq 1 ]]; then
cat >/etc/systemd/system/evofw-firewall.service <<'UNIT'
[Unit]
Description=EvoFirewall sync
@@ -143,9 +233,9 @@ UNIT
# 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; echo "*/1 * * * * $SYNC_SCRIPT") | crontab -
(crontab -l 2>/dev/null | grep -v evofw-firewall || true; echo "*/1 * * * * $SYNC_SCRIPT") | crontab -
"$SYNC_SCRIPT" || true
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 "If still offline after Approve, run: $SYNC_SCRIPT"
+2
View File
@@ -36,6 +36,8 @@ 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.
Backend auto-detect: nft → ipset → iptables.
Whitelist: nft chain policy drop + allow set. Blacklist: policy accept + deny set.