From ef0398bc6bfdc639c6732571b67896323b8ddace Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Sun, 21 Jun 2026 12:07:08 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-06-21 12:06:23 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-21 12:06:23 --- .claude/skills/unifi-wifi/SKILL.md | 6 ++- .../skills/unifi-wifi/references/ROADMAP.md | 8 +++- .claude/skills/unifi-wifi/scripts/sites.sh | 45 +++++++++++++++++++ errorlog.md | 2 + 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/.claude/skills/unifi-wifi/SKILL.md b/.claude/skills/unifi-wifi/SKILL.md index 2de2e546..86162ce7 100644 --- a/.claude/skills/unifi-wifi/SKILL.md +++ b/.claude/skills/unifi-wifi/SKILL.md @@ -11,8 +11,10 @@ controller knows and making prioritized, validated changes. Built for any site; (77 APs, ~550 clients, brutal 2.4GHz) is the reference hard case. ## Multi-client (any UOS site) -**`scripts/sites.sh`** lists all ~49 sites (APs/switches/gateways) + per-client AP-cred readiness — the -entry point for pointing the skill at another client. **Controller-side** scripts (audit-site, +**`scripts/sites.sh`** lists all ~49 sites (APs/switches/gateways) + per-client AP-cred readiness + a +**site→gateway map** (each site classified UniFi-gateway vs pfSense/third-party, and which +`clients/*/pfsense-firewall` SSH creds are vaulted with host:port) — the entry point for pointing the +skill at another client. **Controller-side** scripts (audit-site, live-stats, model-rank, optimize-radios, apply-radio) work on ANY site with **zero per-client setup** (shared controller creds) — pass the site name/desc/id. **AP-side** collectors (neighbor/survey/dfs/ watch-ap) additionally need that client's `clients//unifi-ap-ssh` vaulted + L3 reach (site VPN); diff --git a/.claude/skills/unifi-wifi/references/ROADMAP.md b/.claude/skills/unifi-wifi/references/ROADMAP.md index 7fcc6142..69a79734 100644 --- a/.claude/skills/unifi-wifi/references/ROADMAP.md +++ b/.claude/skills/unifi-wifi/references/ROADMAP.md @@ -150,8 +150,12 @@ 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. -- [ ] **Site→gateway map:** record per-site gateway type + access (UOS site_id ↔ pfSense host/cred) so the - driver auto-selects. Could live alongside `sites.sh` output. +- [x] **Site→gateway map** (2026-06-21): `sites.sh` now prints a live gateway map — every UOS site + classified UniFi-gateway (model) vs no-UniFi-gateway (pfSense/third-party candidate), plus the list of + vaulted `clients/*/pfsense-firewall` creds with resolved host:port (SSH-backend-ready). Generated live + (always current), not a static file. Today: 12 UniFi-gw / 36 no-UniFi-gw sites; 1 pfSense cred (Cascades). + - [ ] **Auto-select from the map** (driver picks the pfSense cred for a site WITHOUT `--pfsense`): needs a + UOS-site-name→slug binding + the cred-path convention (PARKED on Mike's clients/ vs infrastructure/ answer). - [ ] **VPN convergence:** the "Deeper VPN — gateway-hosted VPN server" item (C) is *easier and better* on pfSense (WireGuard/OpenVPN) than on a USG — fold the Grabb-style "retire Windows RRAS PPTP → gateway VPN" play into the pfSense driver from the start. diff --git a/.claude/skills/unifi-wifi/scripts/sites.sh b/.claude/skills/unifi-wifi/scripts/sites.sh index 99470898..e666ee39 100644 --- a/.claude/skills/unifi-wifi/scripts/sites.sh +++ b/.claude/skills/unifi-wifi/scripts/sites.sh @@ -50,3 +50,48 @@ cat <<'EOF' 3) pass it as the script's vault-path arg, e.g.: bash .../neighbor-collect.sh clients//unifi-ap-ssh EOF + +# ---------- Site -> gateway map (which backend gw-audit/gw-control uses per site) ---------- +# A site with a UniFi gateway (ugw/uxg/udm/ucg) is driven via the UniFi REST path; a site with +# NO UniFi gateway (gw=0) is a pfSense/third-party gateway and is driven via the pfSense SSH backend +# (pfsense-ssh.sh) when a clients//pfsense-firewall cred is vaulted. UOS site name != client +# slug, so the dispatch takes --pfsense (or the slug as the site arg) to bind them. +echo "" +echo "[INFO] Site -> gateway map (gw-audit/gw-control backend per site):" +cat <<'JS' | bash "$UOS" 2>&1 | grep -viE 'WARNING|post-quantum|store now|upgraded|openssh' +var sites={}; +db.site.find({},{name:1,desc:1}).forEach(function(s){ sites[s._id.str]={name:(s.desc||s.name),gw:0,model:''}; }); +db.device.find({type:{$in:['ugw','uxg','udm','ucg']}},{site_id:1,model:1,type:1}).forEach(function(d){ + var s=sites[d.site_id]; if(!s)return; s.gw++; if(!s.model)s.model=(d.model||d.type); }); +var uni=[],third=[]; +Object.keys(sites).forEach(function(id){var s=sites[id]; (s.gw>0?uni:third).push(s);}); +function byname(a,b){return a.nameb.name?1:0);} +print(""); +print(" UniFi-gateway sites ("+uni.length+") -> UniFi REST backend (no extra setup):"); +uni.sort(byname).forEach(function(s){ print(" [UniFi "+(s.model||"gw")+"] "+s.name); }); +print(""); +print(" No UniFi gateway ("+third.length+") -> pfSense/third-party -> SSH backend (needs a vaulted cred + --pfsense ):"); +third.sort(byname).forEach(function(s){ print(" [3rd-party?] "+s.name); }); +JS + +# pfSense SSH creds that are vaulted -> the SSH backend can reach these now (with resolved host:port) +echo "" +echo " pfSense SSH creds vaulted (clients/*/pfsense-firewall) -> SSH backend ready:" +if [ -d "$VROOT" ]; then + any=0 + while IFS= read -r f; do + [ -n "$f" ] || continue + slug=$(printf '%s' "$f" | sed -E 's#.*/clients/([^/]+)/.*#\1#') + host=$(bash "$REPO/.claude/scripts/vault.sh" get-field "clients/$slug/pfsense-firewall" host 2>/dev/null || true) + port=$(bash "$REPO/.claude/scripts/vault.sh" get-field "clients/$slug/pfsense-firewall" port 2>/dev/null || true) + case "$port" in ""|null) port=22;; esac + case "$host" in ""|null) host="(host?)";; esac + echo " [ready] clients/$slug/pfsense-firewall ($host:$port)" + any=1 + done < <(find "$VROOT/clients" -name 'pfsense-firewall.sops.yaml' 2>/dev/null | sort) + [ "$any" = 1 ] || echo " (none yet - vault clients//pfsense-firewall to enable the SSH backend for a site)" +else + echo " (vault not found at $VROOT - set VAULT_ROOT)" +fi +echo " Bind a no-UniFi-gateway site to its pfSense cred via --pfsense , e.g.:" +echo " bash .claude/skills/unifi-wifi/scripts/gw-audit.sh '' --pfsense " diff --git a/errorlog.md b/errorlog.md index feb1032f..de4622e7 100644 --- a/errorlog.md +++ b/errorlog.md @@ -17,6 +17,8 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure · +2026-06-21 | Howard-Home | guruscan/whitelist-design | [correction] over-engineered whitelist as dynamic service-discovery; correct approach is a simple static hard list of install folders (scanners that support exclude-lists ignore listed folders; RKill won't, accepted) + 2026-06-21 | Howard-Home | bitdefender | GravityZone API error [policies.getPolicyDetails]: Invalid value for 'policyId' parameter. [ctx: cmd=policy] 2026-06-21 | Howard-Home | bitdefender | GravityZone API error [network.getManagedEndpointDetails]: Invalid value for 'endpointId' parameter. Expected format: 24-char hex ID [ctx: cmd=endpoint]