feat(api): implement self-update mechanism for Linux agents
- Added a `maybe_self_update` function in `evofw-firewall.sh` to allow agents to pull the latest version of the sync script from the server, enhancing the agent's ability to stay updated. - Updated the `/v1/agent/sync-script` endpoint to return ETag and script SHA256 headers, enabling efficient caching and conditional requests. - Modified the agent policy response to include `script_sha256`, providing visibility into the current version of the sync script. - Enhanced tests to verify the self-update functionality and ensure correct behavior of the sync script endpoint. These changes improve the maintainability and reliability of Linux agents by enabling automatic updates of critical scripts.
This commit is contained in:
@@ -24,9 +24,81 @@ source "$CONF_FILE"
|
||||
CLIENT_TOKEN="${CLIENT_TOKEN//$'\r'/}"
|
||||
CLIENT_TOKEN="${CLIENT_TOKEN//$'\n'/}"
|
||||
BACKEND="${KERNEL_BACKEND:-auto}"
|
||||
SYNC_SCRIPT=/usr/local/sbin/evofw-firewall.sh
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
file_sha256() {
|
||||
local f=$1
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha256sum "$f" 2>/dev/null | awk '{print $1}'
|
||||
elif command -v openssl >/dev/null 2>&1; then
|
||||
openssl dgst -sha256 "$f" 2>/dev/null | awk '{print $NF}'
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Pull a newer sync script from CP before policy (pending agents too).
|
||||
# Errors must not abort this run — keep the current script.
|
||||
maybe_self_update() {
|
||||
if [[ "${EVOFW_SKIP_SELF_UPDATE:-}" == "1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ ! -f "$SYNC_SCRIPT" ]]; then
|
||||
return 0
|
||||
fi
|
||||
local local_sha tmp code remote_sha
|
||||
local_sha=$(file_sha256 "$SYNC_SCRIPT")
|
||||
tmp=$(mktemp "${STATE_DIR}/sync-script.XXXXXX") || return 0
|
||||
if [[ -n "$local_sha" ]]; then
|
||||
code=$(curl -sS -o "$tmp" -w '%{http_code}' \
|
||||
-H "If-None-Match: \"${local_sha}\"" \
|
||||
"${EVOFW_CP_URL%/}/v1/agent/sync-script") || code="000"
|
||||
else
|
||||
code=$(curl -sS -o "$tmp" -w '%{http_code}' \
|
||||
"${EVOFW_CP_URL%/}/v1/agent/sync-script") || code="000"
|
||||
fi
|
||||
if [[ "$code" == "304" ]]; then
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
if [[ "$code" != "200" ]]; then
|
||||
log "self-update: sync-script HTTP ${code} — keep current"
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
if ! head -n1 "$tmp" | grep -q '^#!'; then
|
||||
log "self-update: sync-script is not a shell script — keep current"
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
remote_sha=$(file_sha256 "$tmp")
|
||||
if [[ -z "$remote_sha" ]]; then
|
||||
log "self-update: cannot hash download — keep current"
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "$local_sha" && "$remote_sha" == "$local_sha" ]]; then
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
if ! install -m 755 "$tmp" "$SYNC_SCRIPT"; then
|
||||
log "self-update: install failed — keep current"
|
||||
rm -f "$tmp"
|
||||
return 0
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
rm -f "$HASH_FILE"
|
||||
log "self-update: installed script sha256=${remote_sha} — re-exec"
|
||||
exec env EVOFW_SKIP_SELF_UPDATE=1 "$SYNC_SCRIPT" || {
|
||||
log "self-update: exec failed — continue current"
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
maybe_self_update
|
||||
|
||||
curl_policy() {
|
||||
local dest="$1"
|
||||
local code
|
||||
|
||||
Reference in New Issue
Block a user