diff --git a/apps/api/src/agent-scripts/mikrotik-install.rsc b/apps/api/src/agent-scripts/mikrotik-install.rsc index 211f56d..7a0e1f1 100644 --- a/apps/api/src/agent-scripts/mikrotik-install.rsc +++ b/apps/api/src/agent-scripts/mikrotik-install.rsc @@ -49,7 +49,7 @@ :set token ("evofw_" . [:tostr [/system clock get time]] . [:tostr [/system resource get cpu-load]] . [:tostr [/system resource get free-memory]] . [:tostr [:rndnum from=100000 to=999999]]) } - :local body ("{\"name\":\"" . $EvofwName . "\",\"hostname\":\"" . [/system identity get name] . "\",\"platform\":\"mikrotik\",\"token\":\"" . $token . "\",\"client_version\":\"rsc/5\"") + :local body ("{\"name\":\"" . $EvofwName . "\",\"hostname\":\"" . [/system identity get name] . "\",\"platform\":\"mikrotik\",\"token\":\"" . $token . "\",\"client_version\":\"rsc/6\"") :if ([:typeof $EvofwInstallLinkId] != "nothing" && [:len $EvofwInstallLinkId] > 0) do={ :set body ($body . ",\"install_link_id\":\"" . $EvofwInstallLinkId . "\"") } @@ -67,15 +67,38 @@ :set EvofwLastHash "" -# Filter rules (idempotent by comment) +# Filter rules (idempotent by comment) — always at the top of each chain. # Deny path: hit (add-src → EVOFW_HITS) then drop. Allow/default unchanged. :do { /ip firewall filter remove [find comment~"^evofw-"] } on-error={} -/ip firewall filter add chain=input action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-input disabled=no -/ip firewall filter add chain=input action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-input disabled=no -/ip firewall filter add chain=forward action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-forward disabled=no -/ip firewall filter add chain=forward action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-forward disabled=no -/ip firewall filter add chain=forward action=accept src-address-list=EVOFW_ALLOW comment=evofw-allow-accept-forward disabled=no -/ip firewall filter add chain=forward action=drop comment=evofw-default-drop-forward disabled=yes + +:local inputFirst [/ip firewall filter find where chain=input] +:local inputPb "" +:if ([:len $inputFirst] > 0) do={ :set inputPb ($inputFirst->0) } + +:local forwardFirst [/ip firewall filter find where chain=forward] +:local forwardPb "" +:if ([:len $forwardFirst] > 0) do={ :set forwardPb ($forwardFirst->0) } + +# place-before same anchor repeatedly → earlier adds stay above later ones. +:if ([:len $inputPb] > 0) do={ + /ip firewall filter add chain=input action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-input disabled=no place-before=$inputPb + /ip firewall filter add chain=input action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-input disabled=no place-before=$inputPb +} else={ + /ip firewall filter add chain=input action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-input disabled=no + /ip firewall filter add chain=input action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-input disabled=no +} + +:if ([:len $forwardPb] > 0) do={ + /ip firewall filter add chain=forward action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-forward disabled=no place-before=$forwardPb + /ip firewall filter add chain=forward action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-forward disabled=no place-before=$forwardPb + /ip firewall filter add chain=forward action=accept src-address-list=EVOFW_ALLOW comment=evofw-allow-accept-forward disabled=no place-before=$forwardPb + /ip firewall filter add chain=forward action=drop comment=evofw-default-drop-forward disabled=yes place-before=$forwardPb +} else={ + /ip firewall filter add chain=forward action=add-src-to-address-list address-list=EVOFW_HITS address-list-timeout=1h src-address-list=EVOFW_DENY comment=evofw-deny-hit-forward disabled=no + /ip firewall filter add chain=forward action=drop src-address-list=EVOFW_DENY comment=evofw-deny-drop-forward disabled=no + /ip firewall filter add chain=forward action=accept src-address-list=EVOFW_ALLOW comment=evofw-allow-accept-forward disabled=no + /ip firewall filter add chain=forward action=drop comment=evofw-default-drop-forward disabled=yes +} # Build sync body as a template script, then prepend baked credentials → one script :do { /system script remove [find name="evofw-sync-body"] } on-error={} diff --git a/docs/agents.md b/docs/agents.md index c5df52b..c8376d1 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -79,7 +79,7 @@ IPv6 skipped. Install RSC: 1. Enroll (с `install_link_id` → агент Invited → Pending). -2. Создаёт filter-правила `evofw-*` и address-list `EVOFW_DENY` / `EVOFW_ALLOW` / dynamic **`EVOFW_HITS`**. +2. Создаёт filter-правила `evofw-*` **в начале** цепочек `input`/`forward` (`place-before`) и address-list `EVOFW_DENY` / `EVOFW_ALLOW` / dynamic **`EVOFW_HITS`**. 3. Scheduler `evofw-sync` каждую минуту: `GET /v1/agent/policy` (JSON) → rebuild deny/allow + report (+ `ip_hits` из HITS). Не использует `/import` огромного `.rsc`. Лог: `/log print where message~"evofw"`. Ручной sync: `/system script run evofw-sync`.