feat(api): unify policy handling with default action updates
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 1m53s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped

- Updated `evofw-firewall.sh` and related scripts to replace `policy_mode` with `default_action`, enhancing clarity and consistency in policy management.
- Adjusted agent routes and evaluation logic to accommodate the new default action structure, ensuring backward compatibility with legacy modes.
- Enhanced tests to validate the new default action behavior and its integration within the agent policy framework.
- Refactored related components in the web interface to align with the updated policy handling, improving user experience and reducing confusion around policy modes.
This commit is contained in:
Denozordec
2026-07-23 10:52:28 +07:00
parent a6eb21a10d
commit 1f7273f38d
30 changed files with 1469 additions and 621 deletions
+27 -14
View File
@@ -57,7 +57,12 @@ parse_policy() {
local f="$1"
if command -v jq >/dev/null 2>&1; then
HASH=$(jq -r '.hash // empty' "$f")
MODE=$(jq -r '.policy_mode // "blacklist"' "$f")
DEFAULT_ACTION=$(jq -r '.default_action // empty' "$f")
if [[ -z "$DEFAULT_ACTION" ]]; then
local legacy
legacy=$(jq -r '.policy_mode // "blacklist"' "$f")
if [[ "$legacy" == "whitelist" ]]; then DEFAULT_ACTION=drop; else DEFAULT_ACTION=accept; fi
fi
mapfile -t DENY < <(jq -r '.deny_cidrs[]? // empty' "$f")
mapfile -t ALLOW < <(jq -r '.allow_cidrs[]? // empty' "$f")
return 0
@@ -67,7 +72,10 @@ parse_policy() {
import json,sys
d=json.load(open(sys.argv[1],encoding="utf-8"))
print(f'HASH={d.get("hash") or ""}')
print(f'MODE={d.get("policy_mode") or "blacklist"}')
da=d.get("default_action") or ""
if not da:
da="drop" if d.get("policy_mode")=="whitelist" else "accept"
print(f'DEFAULT_ACTION={da}')
print("DENY=("+" ".join(json.dumps(x) for x in (d.get("deny_cidrs") or []))+")")
print("ALLOW=("+" ".join(json.dumps(x) for x in (d.get("allow_cidrs") or []))+")")
PY
@@ -78,12 +86,12 @@ PY
exit 1
}
HASH=""; MODE=blacklist; DENY=(); ALLOW=()
HASH=""; DEFAULT_ACTION=accept; DENY=(); ALLOW=()
parse_policy "$POLICY_FILE"
# Empty deny/allow is valid — agent may have no rule sets yet.
DENY=("${DENY[@]+"${DENY[@]}"}")
ALLOW=("${ALLOW[@]+"${ALLOW[@]}"}")
log "mode=$MODE deny=${#DENY[@]} allow=${#ALLOW[@]} hash=$HASH"
log "default_action=$DEFAULT_ACTION deny=${#DENY[@]} allow=${#ALLOW[@]} hash=$HASH"
PACKETS_DROPPED=0
PACKETS_ACCEPTED=0
@@ -148,15 +156,19 @@ apply_nft() {
((${#batch[@]})) && nft_add_chunk "$table" "$name" allow_v4 "${batch[@]}"
nft delete chain "$table" "$name" input 2>/dev/null || true
if [[ "$MODE" == "whitelist" ]]; then
# Unified chain: deny → allow → default_action
if [[ "$DEFAULT_ACTION" == "drop" ]]; then
nft add chain "$table" "$name" input '{ type filter hook input priority 0; policy drop; }'
nft add rule "$table" "$name" input ct state established,related counter accept
nft add rule "$table" "$name" input iif lo counter accept
nft add rule "$table" "$name" input ip saddr @allow_v4 counter accept
nft add rule "$table" "$name" input counter drop
else
nft add chain "$table" "$name" input '{ type filter hook input priority 0; policy accept; }'
nft add rule "$table" "$name" input ip saddr @deny_v4 counter drop
fi
nft add rule "$table" "$name" input ct state established,related counter accept
nft add rule "$table" "$name" input iif lo counter accept
nft add rule "$table" "$name" input ip saddr @deny_v4 counter drop
nft add rule "$table" "$name" input ip saddr @allow_v4 counter accept
if [[ "$DEFAULT_ACTION" == "drop" ]]; then
nft add rule "$table" "$name" input counter drop
else
nft add rule "$table" "$name" input counter accept
fi
KERNEL_METHOD=nft
@@ -173,11 +185,12 @@ apply_ipset() {
for p in "${ALLOW[@]+"${ALLOW[@]}"}"; do [[ "$p" == *:* ]] && continue; ipset add "$aset" "$p" -exist; n=$((n+1)); done
iptables -D INPUT -m set --match-set "$dset" src -j DROP 2>/dev/null || true
iptables -D INPUT -m set --match-set "$aset" src -j ACCEPT 2>/dev/null || true
if [[ "$MODE" == "whitelist" ]]; then
iptables -I INPUT -m set --match-set "$aset" src -j ACCEPT
iptables -D INPUT -j DROP 2>/dev/null || true
# Unified: deny first, then allow, then optional default drop
iptables -I INPUT -m set --match-set "$dset" src -j DROP
iptables -I INPUT 2 -m set --match-set "$aset" src -j ACCEPT
if [[ "$DEFAULT_ACTION" == "drop" ]]; then
iptables -A INPUT -j DROP 2>/dev/null || true
else
iptables -I INPUT -m set --match-set "$dset" src -j DROP
fi
KERNEL_METHOD=ipset
APPLIED=$n