diff --git a/wiki/clients/internal-infrastructure.md b/wiki/clients/internal-infrastructure.md index 3b33709..7a3f5cb 100644 --- a/wiki/clients/internal-infrastructure.md +++ b/wiki/clients/internal-infrastructure.md @@ -75,6 +75,7 @@ Work on **GuruRMM** (development, deployment) lives in `projects/msp-tools/guru- | Jupiter | 172.16.3.20 | Unraid NAS — all VMs + Docker | SSH port 22, root. NPM, Gitea, Seafile, cloudflared (GuruRMM VM decommissioned 2026-06-12) | | GuruRMM | 172.16.3.30 | **Physical box** (Lenovo ThinkCentre M83, Ubuntu 26.04), NOT a VM — replaced the Jupiter VM at this IP 2026-06-11 | GuruRMM server, ClaudeTools API, MariaDB, PostgreSQL, Coord API | | Pluto | 172.16.3.36 | Windows Server 2019 VM on Jupiter | **Fallback** MSI build host for GuruRMM agents (Beast/GURU-BEAST-ROG is primary) | +| UOS Server | 172.16.3.29 | UniFi OS Server — self-hosted UniFi controller, ~49 sites | virsh "Unifi" VM on Jupiter; Rocky 9. Web/API on **:11443** (NPM `unifi.azcomputerguru.com`; 8443/443 closed). Root SSH key access; query the `ace` Mongo via `.claude/scripts/uos-mongo.sh`. See [[uos-server]] | | Uranus | 172.16.3.21 | OwnCloud additional storage | NOT a proxy | | IX Web Server | 172.16.3.10 | cPanel/WHM web hosting | 87 WordPress sites, CloudLinux 9.7 | | Neptune Exchange | 172.16.3.11 | Exchange Server 2016 | Physically at Dataforth D2 — NOT ACG office LAN | diff --git a/wiki/systems/jupiter.md b/wiki/systems/jupiter.md index 019a26b..d7fd8da 100644 --- a/wiki/systems/jupiter.md +++ b/wiki/systems/jupiter.md @@ -46,7 +46,7 @@ Not documented. iDRAC available at 172.16.1.73 (DHCP) for OOB management. | ~~GuruRMM~~ | ~~172.16.3.30~~ | **decommissioned 2026-06-12** | Former GuruRMM VM — migrated to a physical box that took the .30 IP (2026-06-11); virsh domain destroyed + disk deleted 2026-06-12. No longer on Jupiter. | | Claude-Builder (Pluto) | 172.16.3.36 | running | Windows Server 2019 — MSI + cargo builds | | OwnCloud | 172.16.3.22 | running | OwnCloud file sync VM (cloud.acghosting.com) | -| Unifi | (IP not documented) | running | UniFi Network controller | +| Unifi | 172.16.3.29 | running | **UOS Server** — self-hosted UniFi OS controller (~49 sites). Rocky 9; app+Mongo in rootless podman `uosserver`. Access + DB query: [[uos-server]] | | Windows 7 | — | shut off | — | | Windows Server 2016 | (none — APIPA) | running | Windows guest `ACG-DWP-X-BB`; e1000 NIC `vnet8` on br0, DHCP not leasing — see Known Issues | | Windows Server 2016_Template | — | shut off | — | @@ -70,7 +70,7 @@ Not documented. iDRAC available at 172.16.1.73 (DHCP) for OOB management. | emby.azcomputerguru.com | 172.16.2.99:8096 | Emby media server | | git.azcomputerguru.com | 172.16.3.20:3000 | Gitea (Cloudflare-fronted — blocks direct curl; use http://172.16.3.20:3000 internally) | | rmm-api.azcomputerguru.com | 172.16.3.20:3001 | **STALE** — actual GuruRMM API is on 172.16.3.30:3001; update this in NPM admin | -| unifi.azcomputerguru.com | 172.16.3.28:8443 | UniFi controller | +| unifi.azcomputerguru.com | 172.16.3.29:11443 | **UOS Server** (UniFi OS). Verified from NPM API 2026-06-15 — earlier `.28:8443` was stale. The real HTTPS port is **11443** (8443/443 are closed). See [[uos-server]]. | | sync.azcomputerguru.com | 172.16.3.20:8082 | Seafile Pro | | plexrequest.azcomputerguru.com | 172.16.3.31:5055 | Plex request manager | diff --git a/wiki/systems/uos-server.md b/wiki/systems/uos-server.md new file mode 100644 index 0000000..81601e0 --- /dev/null +++ b/wiki/systems/uos-server.md @@ -0,0 +1,75 @@ +--- +type: system +name: uos-server +display_name: UOS Server (UniFi OS Server) +last_compiled: 2026-06-15 +compiled_by: GURU-5070/claude-main +--- + +# UOS Server (UniFi OS Server) + +> ACG's self-hosted **UniFi OS Server** — one controller managing ~49 UniFi sites +> (Cascades, Khalsa, Quantum, Reliant, VWP, IMC, Cutting Edge, and many remote UDM/UCG +> consoles adopted into it). Runs as the virsh VM **"Unifi"** on Jupiter. This article is +> the single-shot access reference: how to reach it, and how to query its device/client DB +> directly (the cloud API and the local web UI both hide data this method exposes). + +## What / where it is + +- **Guest:** Rocky Linux 9.1, hostname-internal "UOS Server". Guest IP **`172.16.3.29`** (ACG internal LAN). +- **Hypervisor:** Jupiter (`172.16.3.20`, Unraid) — virsh domain **`Unifi`** (id 1). `virsh list` to confirm running. +- **App stack (inside guest):** UniFi Network = `ace.jar` (Java) + classic **MongoDB `ace`** on `127.0.0.1:27117`, plus `unifi-core` (Postgres) for UniFi-OS identity/integration. All of it runs **inside a rootless podman container `uosserver`** (host user `uosserver`, uid 1000) — so the app files and mongo are NOT on the guest rootfs. +- **ui.com cloud:** host id `2d6b654d-9b79-4eaa-b2e1-52062a5690ef` in the Site Manager account. + +## Reachability — the port gotcha + +It sits **behind NPM** (Nginx Proxy Manager on Jupiter, admin `http://172.16.3.20:7818`): + +| Public hostname | NPM target | +|---|---| +| `unifi.azcomputerguru.com` (443) | `https://172.16.3.29:`**`11443`** | + +So the UniFi-OS web/API HTTPS port is **`11443`**, not the classic `8443`. On `172.16.3.29` directly: **open** = `11443` (UniFi OS HTTPS), `8080` (inform/`/status`), `8880`, `6789`, `22` (SSH). **Closed** = `443`, `8443`, `8843`. Probing `:8443`/`:443` and concluding "unreachable" is the trap — use `:11443` (or the `unifi.azcomputerguru.com` hostname). + +## Access (the single-shot path) + +**SSH:** our standard key is already authorized as **root** on the guest. Direct, or jump via Jupiter: +```bash +ssh root@172.16.3.29 'id' # direct (office LAN or Tailscale subnet route) +ssh -J root@172.16.3.20 root@172.16.3.29 # via Jupiter +``` + +**Query the UniFi Network DB (`ace`) in one shot** — use the helper, which pipes Mongo JS +through `ssh -> su - uosserver -> podman exec -i uosserver mongo`: +```bash +# find any device/client by MAC suffix across ALL sites (infra + clients): +bash .claude/scripts/uos-mongo.sh --find-mac 36:c4 +bash .claude/scripts/uos-mongo.sh --sites # list site_id -> name +echo 'db.device.count()' | bash .claude/scripts/uos-mongo.sh +bash .claude/scripts/uos-mongo.sh < some-query.js +``` +Raw equivalent (no helper): +```bash +echo 'db.device.find({mac:/36:c4$/i}).count()' \ + | ssh root@172.16.3.29 'su - uosserver -c "XDG_RUNTIME_DIR=/run/user/1000 podman exec -i uosserver mongo --quiet --port 27117 ace"' +``` +There is **no mongo client on the guest host**; the shell is `/usr/bin/mongo` *inside* the +`uosserver` container. `guest-exec` via the QEMU agent is **disabled**, so drive it over SSH (above). + +## Keys / auth — what works and what doesn't + +- **SSH root key on `.29`** — the reliable way in (this is "the key" for UOS work). Gives root + Mongo + everything. +- **Cloud Site Manager API key** — vault `infrastructure/unifi-site-manager-api` (`X-API-Key` vs `https://api.ui.com`). Lists **adopted** devices/sites only (`/v1/devices`, `/ea/sites`, `/v1/hosts`). **Does NOT** authenticate the local integration API (401), even on localhost — it is a cloud key, not the local key. +- **Local Network integration key "Claude"** — exists in `ace.api_key` (count 1) for `https://172.16.3.29:11443/proxy/network/integration/v1/...`, but its value is **hashed/unrecoverable**. If the integration REST API is ever needed, generate a fresh key in the UniFi Network UI (Control Plane -> Integrations), use it once, and vault it. For reads, the Mongo path above is simpler and complete. + +## Querying notes (`ace` collections) + +- **`device`** — adopted infrastructure (APs/switches/gateways), all sites, keyed by `site_id`. MAC is lowercase colon form (`74:83:c2:75:e9:9f`). +- **`user`** — clients/stations (wired + wireless endpoints). +- **`site`** — `_id` (ObjectId; use `_id.str`) -> `desc`/`name`. Build a map to label results by site. +- **`rogue`** — neighbor/over-the-air BSSIDs seen by APs. **Not ACG gear** — a MAC hit here is someone else's WiFi, ignore it for device hunts. +- **Pending/unadopted devices:** the controller only persists a discovered device into `device` with `adopted:false`. If `db.device.count({adopted:false})` is `0`, there are **no** pending devices controller-wide — an "unadopted" device that returns nothing here simply has not reached this controller (not on a network it can discover, or managed by a different console). The cloud API and integration API show adopted gear only, so they cannot find it either; locating it then needs L2/DHCP/ARP on the gateway of the site it is physically cabled to. + +## Backlinks +- [[jupiter]] — hypervisor (virsh "Unifi" VM) + NPM (`172.16.3.20:7818`, the `:11443` proxy). +- [[internal-infrastructure]] — ACG internal infra index.