From 1c8fc09590ae8e1bd54e4f2655ab8e838c98255b Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Sun, 21 Jun 2026 13:32:50 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-06-21 13:31:49 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-21 13:31:49 --- .../feedback_rmm_longops_fire_and_forget.md | 20 +++++++++++++++++++ .claude/skills/unifi-wifi/SKILL.md | 8 +++++--- .../skills/unifi-wifi/references/ROADMAP.md | 18 ++++++++++------- wiki/systems/pfsense.md | 5 +++-- 4 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 .claude/memory/feedback_rmm_longops_fire_and_forget.md diff --git a/.claude/memory/feedback_rmm_longops_fire_and_forget.md b/.claude/memory/feedback_rmm_longops_fire_and_forget.md new file mode 100644 index 00000000..88d8ddfe --- /dev/null +++ b/.claude/memory/feedback_rmm_longops_fire_and_forget.md @@ -0,0 +1,20 @@ +--- +name: feedback_rmm_longops_fire_and_forget +description: Long-running RMM endpoint ops (software installs, big downloads) must be fire-and-forget, not live-monitored +metadata: + type: feedback +--- + +Long-running endpoint operations via RMM (software installs, large downloads, +BD/AV deployment) must run **unattended** — dispatched fire-and-forget, NOT +babysat with live polling loops. Howard's directive (2026-06-21): "this needs to +happen without us monitoring it." + +**How to apply:** run the long op under the endpoint's **Task Scheduler** as +SYSTEM (`schtasks /Create ... /RU SYSTEM /RL HIGHEST /SC ONCE /F` then +`schtasks /Run`), or a detached process that logs its own result to a file. The +RMM command returns immediately. **Verify later by OUTCOME** (e.g. the endpoint +appearing in GravityZone inventory, a result/log file, a service check) on a +separate check — never sit in a poll loop for minutes. This mirrors how Syncro / +real RMM deployments work: fire the job, walk away, check status afterward. +See [[feedback_bitdefender_unattended_install]]. diff --git a/.claude/skills/unifi-wifi/SKILL.md b/.claude/skills/unifi-wifi/SKILL.md index a0069b52..7ce32f58 100644 --- a/.claude/skills/unifi-wifi/SKILL.md +++ b/.claude/skills/unifi-wifi/SKILL.md @@ -60,9 +60,11 @@ path is Cascades — override with the script's vault-path arg per client. - **Writes (DRY-RUN default; add `--apply` to commit — `write_config` + `filter_configure`):** `fw-disable|fw-enable `, `block-ips|unblock [--if wan]` (easyrule) — both **live-validated**; `pf-disable|pf-enable|pf-delete `, `pf-set-ports []`, - `pf-set-src ` (port-forwards + associated filter rule) — built, **live-verify pending** (no - box with forwards available yet). Filter rules match by `tracker` (the `id` field is empty on 25.07) or - exact `descr`. Each write backs up `config.xml` first; writes drive `scripts/pfsense-gwc.php`. + `pf-set-src ` (port-forwards + associated filter rule) — **live-validated 2026-06-21** (full + create→list→set-ports→set-src→enable→disable→delete cycle on a temp source-locked forward on Cascades; + `pf-delete` removes the associated filter rule too). Filter rules match by `tracker` (the `id` field is + empty on 25.07) or exact `descr`; NAT rules have no `tracker` → match by `descr` or index. Each write backs + up `config.xml` first; writes drive `scripts/pfsense-gwc.php`. - **Dispatch + auto-select:** `gw-audit.sh`/`gw-control.sh` route the SAME verbs to this SSH backend three ways: (1) explicit `--pfsense `; (2) the site arg is itself a client slug with a vaulted cred; (3) **auto-select** — the resolved UOS site is bound in `references/site-gateways.tsv`, so no diff --git a/.claude/skills/unifi-wifi/references/ROADMAP.md b/.claude/skills/unifi-wifi/references/ROADMAP.md index a93a9451..44071226 100644 --- a/.claude/skills/unifi-wifi/references/ROADMAP.md +++ b/.claude/skills/unifi-wifi/references/ROADMAP.md @@ -125,15 +125,19 @@ with VPN + SSH we can read the same data and make changes." Confirmed: Cascades straight to a shell** (no menu gotcha). So the upgrade/package blocker is **MOOT** and the layer is **OFF HOLD**. -**STATUS (2026-06-21): SSH backend control verbs DONE — reads + filter toggles + blocking validated -live on Cascades; NAT (pf-*) built but live-verify pending.** +**STATUS (2026-06-21): SSH backend control verbs DONE + ALL live-verified on Cascades (reads, filter +toggles, blocking, AND the NAT pf-* verbs).** Reads (no gate): `audit`, `dhcp`, `pf-list`, `fw-list`, `showblock [--if wan]`, `run ""`. Writes (DRY-RUN default; `--apply` to commit — `write_config` + `filter_configure`): - `fw-disable|fw-enable ` — toggle a filter rule (match by `tracker` or exact `descr`). **[x] live-validated.** - `block-ips|unblock [--if wan]` — `easyrule block/unblock`. **[x] live-validated** (block→showblock→unblock cycle on a TEST-NET IP). - `pf-disable|pf-enable|pf-delete `, `pf-set-ports []`, `pf-set-src ` — port-forwards - (+ the associated filter rule). **[~] built against the documented NAT schema; Cascades has 0 forwards so NOT yet - live-verified — confirm field names on the first box that has port-forwards before trusting `--apply`.** + (+ the associated filter rule). **[x] live-validated 2026-06-21**: full cycle on Cascades against a temporary + source-locked (TEST-NET) disabled forward — create → pf-list parse → set-ports (dst+local) → set-src → + enable → disable → delete (NAT + associated filter rule both removed, box back to baseline). NAT rules have no + `tracker`, so match by `descr` or index. (Verified the verb mechanics + the documented NAT schema fields + `destination.network/port`, `target`, `local-port`, `associated-rule-id`, `disabled`; a GUI-created forward + would be a belt-and-suspenders schema spot-check but the fields rendered/round-tripped correctly.) - How it works: `pfsense-ssh.sh` ships `scripts/pfsense-gwc.php` to the box (base64 over the wire) and runs it under `php`, which bootstraps `$config` via `config.inc` (do NOT re-require util/functions/filter — "cannot redeclare" fatal). Each write backs up `/cf/conf/config.xml` to `/tmp` first; `write_config()` also keeps pfSense's own @@ -149,9 +153,9 @@ Writes (DRY-RUN default; `--apply` to commit — `write_config` + `filter_config `clients//pfsense-firewall`) and route the same verbs to it; dispatch runs BEFORE UOS site resolution so a pfSense-only slug works. REST path is the dormant fallback. -**Remaining (SSH backend):** [ ] live-verify the `pf-*` NAT verbs on a box that has port-forwards (e.g. once a -client's pfSense with a real forward is reachable); [ ] optional `pf-add`/create verbs if we ever need to *add* -forwards (today we only need to close/scope existing exposure). +**Remaining (SSH backend):** [x] pf-* live-verified (2026-06-21, above). [ ] optional: spot-check pf-* against a +GUI-created forward when one is reachable (schema belt-and-suspenders); [ ] optional `pf-add`/create verbs if we +ever need to *add* forwards (today we only need to close/scope existing exposure). **Superseded/optional:** the REST `pfsense-backend.sh` + `clients//pfsense-api` path stays in-tree as a dormant alternative (works if a site ever installs the pkg) but is no longer the plan. diff --git a/wiki/systems/pfsense.md b/wiki/systems/pfsense.md index eed4569f..524eec5e 100644 --- a/wiki/systems/pfsense.md +++ b/wiki/systems/pfsense.md @@ -91,8 +91,9 @@ The REST backend (`pfsense-backend.sh`, `clients//pfsense-api`) is a dorma - `fw-disable|fw-enable ` — toggle a filter rule. **Validated live.** - `block-ips|unblock [--if wan]` — via `easyrule`. **Validated live.** - `pf-disable|pf-enable|pf-delete `, `pf-set-ports []`, - `pf-set-src ` — port-forwards (+ associated filter rule). **Built; live-verify - pending** (needs a box that has port-forwards). + `pf-set-src ` — port-forwards (+ associated filter rule). **Validated live** (2026-06-21, + full cycle on Cascades against a temp source-locked forward; `pf-delete` removes the associated + filter rule too). NAT rules have no `tracker` → match by `descr` or index. - Filter rules are matched by `tracker` (the `id` field is empty on pf25.07) or exact `descr`. **Dispatch:** `gw-audit.sh` / `gw-control.sh` prefer this SSH backend (keyed on the