sync: auto-sync from HOWARD-HOME at 2026-06-21 18:27:49
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-21 18:27:49
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# Session — security.azcomputerguru.com: live deploy + smoke test (found/fixed prod auth bug)
|
||||
|
||||
## User
|
||||
- **User:** Howard Enos (howard)
|
||||
- **Machine:** Howard-Home
|
||||
- **Role:** tech
|
||||
|
||||
## Session Summary
|
||||
|
||||
Continued the security-assessment work (same HOWARD-HOME session; see the two companion logs from
|
||||
today). Howard requested: make UI elements slightly larger, test every field for usable info, and a
|
||||
big new multi-tenant client portal + ACG sales view. Did the unambiguous pieces, deferred the portal
|
||||
to a feature request, then (on Howard's "b" greenlight) deployed to the live IX host and functionally
|
||||
tested — which surfaced a production-breaking bug.
|
||||
|
||||
Bumped the wizard UI sizing ~10-12% (text, inputs, spacing, wider sheet, bigger buttons) and committed
|
||||
it. Built `app/fieldcheck.cjs` and audited every questions.json field: 59 fields / 25 scorable, all 25
|
||||
emit a usable finding on worst-case answers, no orphan/missing score keys, all findings complete, all 13
|
||||
requiredControls resolve — every field yields usable info. Captured the portal vision as FR-1 in
|
||||
`FEATURES.md` (personas, no-auto-sync guardrail, quote→active workflow, 3 auth options) and asked the
|
||||
foundational auth decision; Howard chose to defer it to a feature request and focus on testing. Added an
|
||||
executive summary + top-3 prioritized actions + ACG footer to the export (client = recommendations,
|
||||
internal = + ACG service).
|
||||
|
||||
Deployed to IX (172.16.3.10, cPanel account `azcomputerguru`, docroot
|
||||
`/home/azcomputerguru/public_html/security`, PHP 8.1.34) over SSH: backed up the live files, uploaded to
|
||||
`.new`, lint-gated (php -l + JSON validate), then atomic-swapped into place. `config.php` (live secrets)
|
||||
was never touched. The public URL was already live behind Cloudflare Access (a public hit returns CF
|
||||
Access 403), so this was an update, not first-time setup.
|
||||
|
||||
Smoke-testing on the server found a **production-breaking bug**: `api.php`'s allow-list check did a
|
||||
single `strcasecmp($email, ALLOWED_EMAIL)` against the WHOLE comma-separated list, so once a 2nd address
|
||||
(howard@) was added on Jun 19, every API call (lookup/save/load/list/export) returned `forbidden` — the
|
||||
live backend had been unusable. Fixed it to split + membership-check (matching index.php), redeployed,
|
||||
and re-verified: `action=list` reads the DB; internal export renders posture/exec-summary/findings/ACG-
|
||||
service/REQUIRED/captured-intake; client export renders posture+recommendations with zero upsell leaks
|
||||
and no raw intake. Inserted a weak-answer test row, exported both views, then deleted it — prod DB back
|
||||
to its 2 real rows. Committed everything to submodule `main` and advanced the claudetools pin so git
|
||||
matches the live server.
|
||||
|
||||
## Key Decisions
|
||||
- **Deploy via root SSH + base64 file upload, lint-gated atomic swap.** Backup → upload `.new` →
|
||||
`php -l`/JSON-validate → `mv` into place. Never overwrite `config.php`. Safe for a live site.
|
||||
- **Functional-test via PHP CLI + a shipped harness, not inline `php -r`.** Inline `ssh "php -r '...'"`
|
||||
mangled through nested quoting (printed PHP usage); a base64'd `.php` harness that includes api.php and
|
||||
drives `$_GET[action]` is reliable. Bypasses the Apache/Cloudflare vhost routing (origin-direct curl
|
||||
404'd — a vhost/SNI artifact, not a broken deploy).
|
||||
- **Test row written to the tool's own MySQL then deleted** — acceptable for a smoke test (its own DB,
|
||||
not Syncro/RMM), clearly tagged `ZZ-SMOKE-DELETE`, cleaned up.
|
||||
- **Portal deferred to FR-1** (Howard's call) rather than building a multi-tenant auth model speculatively.
|
||||
- **MSYS `ssh` for password+askpass**, not native Windows OpenSSH (which fails the .sh askpass) — matches
|
||||
the working pfsense-ssh.sh pattern.
|
||||
|
||||
## Problems Encountered
|
||||
- **PROD BUG — api.php 403 for everyone** (single strcasecmp vs comma list). Found via live smoke test;
|
||||
fixed + redeployed + verified. This is why "test every function" mattered.
|
||||
- **Native Windows OpenSSH askpass failed** `CreateProcessW error:193` (can't exec a .sh askpass) →
|
||||
used MSYS bare `ssh`. Logged --friction.
|
||||
- **Inline `php -r` over ssh mangled** (nested quote stripping) → shipped a base64'd .php harness.
|
||||
Logged --friction (ref `feedback_windows_quote_stripping`).
|
||||
- **Origin-direct curl 404'd** (vhost/SNI; CF proxies the real path) → tested via PHP CLI instead.
|
||||
- **Submodule reset to old scaffold** earlier (stale gitlink + a concurrent submodule-update) → restored
|
||||
to origin/main and advanced the claudetools pin to stop the churn.
|
||||
|
||||
## Configuration Changes
|
||||
security-assessment submodule (all on `main`, pushed; claudetools pin advanced each time):
|
||||
- `app/index.php` — UI sizing bump (`66eb7cb`).
|
||||
- `app/api.php` — export exec-summary/top-3/footer (`3e3a9ab`); **allow-list auth fix** (`f246091`).
|
||||
- `FEATURES.md` (new) — FR-1 portal request; `app/fieldcheck.cjs` (new) — field-audit dev tool (`3a2301b`).
|
||||
- Local scratch `app/_deploytest.php` + `app/_smoke.php` created for testing, removed after (not committed).
|
||||
Live IX server: `index.php`, `api.php`, `questions.json` updated in the docroot (backups `.bak-20260621-181744`); `config.php` untouched.
|
||||
ClaudeTools: this session log + `errorlog.md` (2 friction entries).
|
||||
|
||||
## Credentials & Secrets
|
||||
None created/discovered. Used existing vault `infrastructure/ix-server` (root SSH 172.16.3.10:22, password
|
||||
field `credentials.password`; also a WHM API token `credentials.whm-api-token` = full-access root). DB creds
|
||||
live in the server's `config.php` (vault `msp-tools/security-assessment-db`). No secrets printed/committed.
|
||||
|
||||
## Infrastructure & Servers
|
||||
- IX server 172.16.3.10 (ext 72.194.62.5), Rocky Linux WHM/cPanel, PHP 8.1.34 (ea-php81), root SSH :22.
|
||||
- Site docroot: `/home/azcomputerguru/public_html/security` (cPanel acct `azcomputerguru`, sub of azcomputerguru.com, vhost 172.16.3.10:80/:443).
|
||||
- security.azcomputerguru.com behind Cloudflare Access (Zero Trust app `8ce5f31c-...`; allow mike@ + howard@). Origin answers via CF; origin-direct curl needs `--resolve`/Host and still 404'd (CF-proxied path is the working one).
|
||||
- Live DB (acgsec_assess): 2 real rows (id 1 Darrell Delphen, id 2 empty) after test cleanup.
|
||||
|
||||
## Commands & Outputs
|
||||
```
|
||||
# find docroot
|
||||
ssh root@172.16.3.10 'grep -i security.azcomputerguru.com /etc/userdatadomains'
|
||||
# -> azcomputerguru==root==sub==azcomputerguru.com==/home/azcomputerguru/public_html/security==...ea-php81
|
||||
# deploy pattern: backup -> base64 upload to .new -> php -l -> chown user -> mv (atomic)
|
||||
base64 local.php | ssh root@ix "base64 -d > docroot/file.new"
|
||||
# functional test (bypasses Apache/CF): shipped harness includes api.php
|
||||
php _deploytest.php list # {"items":[{id:2...},{id:1,...}]} (after the auth fix)
|
||||
php _deploytest.php export <id> internal # posture/exec/findings/ACG service/Captured intake
|
||||
php _deploytest.php export <id> client # posture/recommendations, 0 ACG-service, no Captured intake
|
||||
# BUG before fix: php _deploytest.php list -> {"error":"forbidden"}
|
||||
```
|
||||
|
||||
## Pending / Incomplete Tasks
|
||||
- **Live browser UI click-through** (through Cloudflare Access) — the only thing not tested; needs a human
|
||||
logged into https://security.azcomputerguru.com (look up a client, answer fields, watch posture, Export
|
||||
both views). Backend fully verified server-side.
|
||||
- **#1 GuruRMM endpoint prefill** — deferred (infra: no Syncro→RMM mapping, no reachable RMM API from IX).
|
||||
- **FR-1 multi-tenant portal** — filed in FEATURES.md, awaiting the auth decision when Howard wants it.
|
||||
|
||||
## Reference Information
|
||||
- Submodule `main` HEAD `f246091` (claudetools pin `27c1d97` at time of fix).
|
||||
- Commits this turn: `66eb7cb` sizing, `3a2301b` FR-1+fieldcheck, `3e3a9ab` export exec-summary, `f246091` api auth fix.
|
||||
- Live server backups: `*.bak-20260621-181744` in the docroot (rollback if needed).
|
||||
- Export endpoint: `api.php?action=export&id=<id>&view=internal|client` (origin requires the CF Access email header).
|
||||
- Companion logs: `2026-06-21-howard-security-assessment-scoring.md`, `...-unifi-pfsense-control-verbs.md`, `...-gururmm-bug-018-019.md`.
|
||||
Reference in New Issue
Block a user