mirror of
https://github.com/myronblair/infra
synced 2026-06-30 17:50:10 -05:00
Compare commits
21 Commits
2a92b958c1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 274aef4097 | |||
| ffb03ec80e | |||
| da9f44948f | |||
| 7303c52aad | |||
| e55da16b65 | |||
| 56c56e5c60 | |||
| a208001848 | |||
| 5471956a45 | |||
| 5bf68feab6 | |||
| 45f734d426 | |||
| e040f5d02a | |||
| e670f8ae80 | |||
| 92e49eb71c | |||
| 66ff15f22d | |||
| 37bed46223 | |||
| b6b3ae2828 | |||
| f8add5d65a | |||
| 4346881d38 | |||
| 2dcd8e9975 | |||
| 2a45dac693 | |||
| 094bd7ac80 |
@@ -0,0 +1,345 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
|
||||||
|
This is a home-lab / managed-hosting environment. There is no local codebase to build or test — work consists of editing PHP/JS files on remote servers via SSH and managing infrastructure across several machines. All tool calls use `sshpass` with password auth.
|
||||||
|
|
||||||
|
## Tailscale Network
|
||||||
|
|
||||||
|
All key hosts are on Tailscale (myronblair@gmail.com). Use Tailscale IPs for SSH — no relay or port forwarding needed.
|
||||||
|
|
||||||
|
| Host | Tailscale IP | LAN IP | Password |
|
||||||
|
|------|-------------|--------|----------|
|
||||||
|
| Claude VM (this) | 100.69.120.58 | 10.48.200.29 | — |
|
||||||
|
| PVE1 | 100.80.188.8 | 10.48.200.90 | `Joker1974!!!` |
|
||||||
|
| PVE2 | 100.87.186.12 | 10.48.200.91 | `Joker1974!!!` |
|
||||||
|
| DO server (orbis) | 100.121.13.34 | 165.22.1.228 | `Gonewalk1974!@#` |
|
||||||
|
| FusionPBX | 100.74.46.120 | 134.209.72.226 | `Joker1974!@#` |
|
||||||
|
| JARVIS VM | 100.77.178.42 | 10.48.200.211 | `Joker1974!!!` |
|
||||||
|
| NPM VM | 100.110.239.71 | 10.48.200.201 | `Joker1974!!!` |
|
||||||
|
| Ollama VM | 100.96.100.113 | 10.48.200.210 | `Joker1974!!!` |
|
||||||
|
| NovaCPX (hostpanel-110) | 100.86.51.18 | 10.48.200.110 | `Joker1974!!!` |
|
||||||
|
| HomeBridge | 100.124.182.18 | 10.48.200.18 | — |
|
||||||
|
| WireGuard CT | 100.122.55.10 | 10.48.200.19 | — |
|
||||||
|
| Synology NAS | 100.118.175.5 | 10.48.200.249 | — |
|
||||||
|
| mini-it12 (Windows) | 100.98.151.120 | 10.48.200.87 | — |
|
||||||
|
|
||||||
|
**DNS note:** FortiGate blocks outbound port 53. All PVE1 VMs must use `10.48.200.90` (PVE1 dnsmasq → 100.100.100.100) as their DNS server, not 8.8.8.8 directly.
|
||||||
|
|
||||||
|
## Server Map
|
||||||
|
|
||||||
|
| Host | IP | SSH | Purpose |
|
||||||
|
|------|-----|-----|---------|
|
||||||
|
| DO (main) | 165.22.1.228 | `root / Gonewalk1974!@#` | CyberPanel/OLS — all websites (not JARVIS after migration) |
|
||||||
|
| FusionPBX | 134.209.72.226 | `root / Joker1974!@#` (via Tailscale 100.74.46.120) | FreeSWITCH PBX |
|
||||||
|
| PVE1 (Proxmox) | orbisne.fortiddns.com (10.48.200.90) | `root / Joker1974!!!` (via Tailscale 100.80.188.8) | Primary hypervisor |
|
||||||
|
| PVE2 (Proxmox) | 10.48.200.91 | `root / Joker1974!!!` | Secondary hypervisor |
|
||||||
|
| JARVIS VM | 10.48.200.211 | `root / Joker1974!!!` (via Tailscale 100.77.178.42) | JARVIS dashboard — PVE1 VM 211, 8c/16GB |
|
||||||
|
| NPM VM | 10.48.200.201 | `root / Joker1974!!!` (via Tailscale 100.110.239.71) | Nginx Proxy Manager — PVE1 VM 105 (was VM200 pre-2026-06-22 restore; cloud-init says .200 but runs at .201) |
|
||||||
|
| Ollama VM | 10.48.200.210 | `root / Joker1974!!!` (via Tailscale 100.96.100.113) | Local LLM — PVE1 VM 106 (was VM210 pre-2026-06-22 restore), 4c/8GB |
|
||||||
|
| Home Assistant | 10.48.200.97 | `myron → sudo` | HA VM 101 |
|
||||||
|
| NetworkBackup | 10.48.200.99 | `myron → sudo` | Backup VM (PVE2 VM 302) |
|
||||||
|
| MediaStack | 10.48.200.35 | `root via PVE1 key` | Sonarr/Radarr/Prowlarr/qBittorrent (PVE1 VM 103, was VM113 pre-2026-06-22 restore) |
|
||||||
|
| NovaCPX | 10.48.200.110 | `root / Joker1974!!!` (direct SSH — Tailscale 100.86.51.18 needs re-auth) | Custom hosting control panel (PVE1 VM 120) |
|
||||||
|
| NPM | 10.48.200.201 | `root / Joker1974!!!` (via Tailscale 100.110.239.71) | Nginx Proxy Manager — PVE1 VM 200 · NPM API: `POST http://localhost:81/api/tokens` identity=myronblair@outlook.com |
|
||||||
|
|
||||||
|
**SSH password order** (try in sequence if first fails): `Joker1974!@#` → `Joker1974!!!` → `Joker1974!`
|
||||||
|
|
||||||
|
**SSH pattern for all remote work:**
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228 'commands here'
|
||||||
|
```
|
||||||
|
|
||||||
|
For PVE1 from anywhere (FortiGate DDNS, survives IP changes):
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@orbisne.fortiddns.com 'commands here'
|
||||||
|
```
|
||||||
|
|
||||||
|
For commands inside VMs on PVE1:
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@orbisne.fortiddns.com \
|
||||||
|
'qm guest exec <VMID> -- bash -c "commands here"'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Websites on DO (165.22.1.228)
|
||||||
|
|
||||||
|
All sites live at `/home/<domain>/public_html/` on DO. CyberPanel/OpenLiteSpeed serves them.
|
||||||
|
|
||||||
|
| Site | Path | GitHub |
|
||||||
|
|------|------|--------|
|
||||||
|
| ~~jarvis.orbishosting.com~~ | ~~removed from DO~~ | myronblair/jarvis (now on PVE1 VM 211) |
|
||||||
|
| tomsjavajive.com | /home/tomsjavajive.com/public_html/ | myronblair/tomsjavajive |
|
||||||
|
| epictravelexpeditions.com | /home/epictravelexpeditions.com/public_html/ | myronblair/epictravelexpeditions |
|
||||||
|
| parkerslingshotrentals.com | /home/parkerslingshotrentals.com/public_html/ | myronblair/parkerslingshotrentals |
|
||||||
|
| orbishosting.com | /home/orbishosting.com/public_html/ | myronblair/orbishosting |
|
||||||
|
| orbis.orbishosting.com | /home/orbis.orbishosting.com/public_html/ | myronblair/orbis-hosting-portal |
|
||||||
|
| tomtomgames.com | /home/tomtomgames.com/public_html/ | myronblair/tomtomgames |
|
||||||
|
|
||||||
|
**Parker Slingshot** is served from epictravelexpeditions.com, not its own domain:
|
||||||
|
- URL: `https://parkerslingshot.epictravelexpeditions.com`
|
||||||
|
- Path: `/home/epictravelexpeditions.com/parkerslingshot/`
|
||||||
|
- GitHub: `myronblair/parkerslingshot` (own repo, auto-deploy active)
|
||||||
|
- `db.php` and `config.php` are gitignored (credentials); `db.php.example` is the reference template
|
||||||
|
|
||||||
|
## Deployment Workflow
|
||||||
|
|
||||||
|
**Auto-deploy is active.** Push to `main` on any site repo → GitHub webhook → server pulls automatically within 1 minute. PHP syntax is validated before deploy; bad commits are auto-reverted.
|
||||||
|
|
||||||
|
**Two separate webhook handlers:**
|
||||||
|
- **JARVIS repo** → `http://jarvis.orbishosting.com:1972/webhook.php` — deploys to JARVIS VM (`/var/www/jarvis/`). Deploy log: `/var/www/jarvis/logs/deploy.log`
|
||||||
|
- **All 6 website repos → `https://tomtomgames.com/webhook.php` on DO — deploys to `/home/<site>/public_html/` on DO. Deploy log: `/home/tomtomgames.com/logs/deploy.log`. Deploy log: `/home/<site>/logs/deploy.log`
|
||||||
|
|
||||||
|
HMAC secret (both handlers): `4c8805f0285214ff0a0602b5880270b935f36a896946c7f1`
|
||||||
|
Deploy queue: `/tmp/jarvis-deploy-queue.txt` | Runner: `/usr/local/bin/jarvis-deploy.sh` (cron every min, on both DO and JARVIS VM)
|
||||||
|
|
||||||
|
For hotfixes that can't wait 1 min, SCP directly:
|
||||||
|
```bash
|
||||||
|
# JARVIS VM
|
||||||
|
scp -o StrictHostKeyChecking=no /tmp/changed.php root@100.77.178.42:/var/www/jarvis/public_html/changed.php
|
||||||
|
# DO websites
|
||||||
|
sshpass -p 'Gonewalk1974!@#' scp -o StrictHostKeyChecking=no /tmp/changed.php \
|
||||||
|
root@165.22.1.228:/home/site.com/public_html/changed.php
|
||||||
|
```
|
||||||
|
|
||||||
|
GitHub PAT (embedded in remote URLs): `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` — expires ~2026-08-20.
|
||||||
|
Infra repo: `myronblair/infra` — cloned at `/opt/infra` on DO server.
|
||||||
|
|
||||||
|
**DO server backup:** `myronblair/do-server-config` — scripts, systemd units, WireGuard, OLS vhosts, cron, MySQL creds + 8-phase restore wizard. Weekly Sunday 4am. Launcher: `/usr/local/bin/do-server-backup`.
|
||||||
|
|
||||||
|
Gitignored credentials (never in GitHub): `api/config.php` (JARVIS, epictravelexpeditions), `config/database.php` (tomsjavajive).
|
||||||
|
|
||||||
|
## JARVIS System
|
||||||
|
|
||||||
|
Iron Man-style AI dashboard at `http://jarvis.orbishosting.com:1972`. **Migrated from DO to PVE1 VM 211 (2026-06-18).** All files on JARVIS VM at `/var/www/jarvis/`.
|
||||||
|
|
||||||
|
**Access:**
|
||||||
|
- Dashboard: `http://jarvis.orbishosting.com:1972`
|
||||||
|
- Admin: `http://jarvis.orbishosting.com:1972/admin`
|
||||||
|
- Internal (LAN): `http://10.48.200.211` or via Tailscale `http://100.77.178.42`
|
||||||
|
- FortiGate VIP: external port `1972` → `10.48.200.211:80`
|
||||||
|
- Cloudflare: DNS only (grey cloud) — no CF proxy, no SSL overhead on origin
|
||||||
|
|
||||||
|
**Stack on JARVIS VM:**
|
||||||
|
- nginx + PHP 8.3-FPM (replaces OLS/lsphp on DO)
|
||||||
|
- MariaDB (jarvis_db local, `jarvis_user / J4rv1s_Pr0t0c0l_2026!`)
|
||||||
|
- Redis (`redis-server`)
|
||||||
|
- Python 3 + Arc Reactor daemon
|
||||||
|
|
||||||
|
**Architecture:**
|
||||||
|
- `public_html/api.php` — API router; `session_start()` skipped only for machine-agent sub-actions (heartbeat/metrics/ha_state/command_result/register); browser-facing agent routes (list/status/myip) need session. Has `session_write_close()` guard (must skip for `auth` endpoint to prevent LSAPI session deadlock).
|
||||||
|
- `api/config.php` — all credentials/constants (gitignored)
|
||||||
|
- `api/endpoints/chat.php` — 4-tier AI: KB intent → Groq (`compound-beta-mini`) → Claude API; includes Tier 0.7 planner intents (tasks/appointments/briefing). Ollama at `http://10.48.200.210:11434`.
|
||||||
|
- `api/endpoints/agent.php` — push-based agent registration/heartbeat/metrics; browser actions (list/status/myip) auth via `$_SESSION`, machine actions auth via `X-Agent-Key` header
|
||||||
|
- `api/endpoints/alerts.php` — auto-generates alerts (CPU >85%, RAM >85%, disk >88%, offline agents, site down); dispatches restart commands to agents when their services fail
|
||||||
|
- `api/endpoints/facts_collector.php` — runs every 3 min via cron (php8.3); collects agent metrics, KB facts, Proxmox/HA status, and all 7 site HTTP health checks. Site checks use external URLs (JARVIS VM is NOT the web host). `$fresh()` queries `WHERE category=?` (not `fact_category`).
|
||||||
|
- `api/endpoints/stats_cache.php` — runs every 5 min via cron; weather/news/Proxmox cache refresh. Proxmox API at `https://10.48.200.90:8006` (direct LAN).
|
||||||
|
- `api/endpoints/do_server.php` — reads `/proc` for JARVIS VM stats; also includes DO server agent metrics (`do_server` key from jarvis-do agent via Tailscale).
|
||||||
|
- `api/endpoints/planner.php` — tasks & appointments CRUD; routes: `planner/tasks`, `planner/appointments`, `planner/today`, `planner/done`
|
||||||
|
- `api/endpoints/ha.php` — HA entity list reads from `ha_entities` table (real-time agent push); service calls go direct to HA_URL (`http://10.48.200.97:8123`)
|
||||||
|
- `api/lib/kb_engine.php` — `storeFact()` ON DUPLICATE KEY UPDATE always sets `updated_at=NOW()` explicitly; without this, unchanged values don't bump the timestamp and freshness checks break.
|
||||||
|
|
||||||
|
**Voice system (index.html):**
|
||||||
|
- Continuous SpeechRecognition; mic stays open always (mute toggle button)
|
||||||
|
- **Phase 1 wake**: say "wake up JARVIS" or "daddy's home" → activates voice mode once
|
||||||
|
- **Phase 2 command**: say "JARVIS [command]" → executes; opens 17-second free-listen window (no prefix needed for follow-ups)
|
||||||
|
- After 30 min of no commands → voice sleeps; full wake phrase required again
|
||||||
|
- Mic paused during ElevenLabs TTS playback (`isSpeaking` guard) to prevent feedback loop
|
||||||
|
- Auto-reload after 5 min idle is silent (no greeting speech)
|
||||||
|
|
||||||
|
**Planner system (2026-05-31):**
|
||||||
|
- DB tables: `tasks` (id, title, notes, category, priority, status, due_date, due_time, completed_at) and `appointments` (id, title, description, category, start_at, end_at, location, all_day, reminder_min, alerted)
|
||||||
|
- Voice commands: "add task [title]", "my tasks", "mark [x] done", "schedule [title] on [date]", "my calendar", "daily briefing"
|
||||||
|
- Home page: small top-bar badge "N TASKS · N APPTS" when items due today (no panel added)
|
||||||
|
- Admin CRUD at `/admin` under PLANNER section → TASKS and APPOINTMENTS tabs
|
||||||
|
|
||||||
|
**Agent system:** Agents phone home every 10s (heartbeat) / 30s (metrics) to `http://10.48.200.211` (direct LAN — no Cloudflare). Config at `/etc/jarvis-agent/config.json` or `/opt/jarvis-agent/config.json` on each Linux agent.
|
||||||
|
Agent installer (one-liner for any Linux host): `curl -sk http://10.48.200.211/install-agent.sh | bash -s <hostname> <linux|homeassistant|proxmox>`
|
||||||
|
DO server agent (jarvis-do) uses Tailscale: `jarvis_url: http://100.77.178.42`
|
||||||
|
|
||||||
|
**Agent file paths by host** (for manual updates — push to correct path then restart service):
|
||||||
|
- Most Linux hosts: `/opt/jarvis-agent/jarvis-agent.py` · service: `systemctl restart jarvis-agent`
|
||||||
|
- WireGuard CT (10.48.200.19, Alpine): `/opt/jarvis-agent/agent.py` · service: `rc-service jarvis-agent restart`
|
||||||
|
- `public_html/agent/jarvis-agent.py` is the self-update URL — must be kept in sync with `agent/jarvis-agent.py` (both are tracked in git; auto-deploy keeps them in sync after 2026-06-17)
|
||||||
|
|
||||||
|
**Self-healing:** `/usr/local/bin/jarvis-watchdog.sh` runs every 5 min (root cron on DO). Restarts lsws/mysql/redis on DO if down. Log: `/usr/local/lsws/logs/watchdog.log` on DO.
|
||||||
|
|
||||||
|
**JARVIS DB:** `jarvis_db` on JARVIS VM localhost (MariaDB). User: `jarvis_user / J4rv1s_Pr0t0c0l_2026!`. phpMyAdmin at `/phpmyadmin` on JARVIS VM (myron / Joker1974!!!).
|
||||||
|
Core tables: agent_commands, agent_metrics, alerts, api_cache, appointments, conversations, ha_entities, kb_facts, kb_intents, kb_ollama_models, kb_preferences, known_commands, metrics_history, network_devices, registered_agents, tasks, users. Arc Reactor adds: arc_jobs, guardian_events, guardian_config, agent_screenshots.
|
||||||
|
|
||||||
|
`kb_facts` schema: `(id, category, fact_key, fact_value, host, expires_at, updated_at)` — column is `category` not `fact_category`.
|
||||||
|
|
||||||
|
**Arc Reactor daemon:** Python service at `/opt/jarvis-arc/reactor.py` on JARVIS VM, port 7474, managed by `systemctl restart jarvis-arc`. Deploy source: `deploy/reactor.py` in the jarvis repo. After pushing to GitHub, auto-deploy pulls to `/var/www/jarvis/deploy/reactor.py` — then manually `cp /var/www/jarvis/deploy/reactor.py /opt/jarvis-arc/reactor.py && systemctl restart jarvis-arc`. Log: `/var/www/jarvis/logs/arc_reactor.log`.
|
||||||
|
|
||||||
|
**Arc Reactor AI routing:**
|
||||||
|
| Feature | Provider | Model |
|
||||||
|
|---------|----------|-------|
|
||||||
|
| Guardian anomaly alerts | Groq | `llama-3.3-70b-versatile` |
|
||||||
|
| SITREP | Groq | `llama-3.3-70b-versatile` |
|
||||||
|
| Vision: text-only sysinfo snapshot | Groq | `llama-3.3-70b-versatile` |
|
||||||
|
| Vision: actual screenshot image | Claude | `claude-opus-4-8-20251101` |
|
||||||
|
| Email drafting, research, tool_loop | Claude | `claude-sonnet-4-6` |
|
||||||
|
|
||||||
|
`llm_call(messages, provider)` cascades: groq → ollama on failure. Pass `"groq"` or `"claude"` as provider.
|
||||||
|
|
||||||
|
**Groq API note:** Use model name `compound-beta-mini` directly — NOT `groq/compound-beta-mini` (that's OpenAI router syntax and will 404 on api.groq.com).
|
||||||
|
|
||||||
|
## Tom's Java Jive
|
||||||
|
|
||||||
|
PHP e-commerce site. DB: `toms_tjj_db / toms_tjj_user / +60wlPc+55e@gFq4`. Key quirks:
|
||||||
|
- No `slug` column on products — URLs use `?id=product_id`
|
||||||
|
- All tables must be `utf8mb4_unicode_ci` — mixed collation causes MySQL error 1267 on JOINs
|
||||||
|
- `wallet_transactions.type` and `loyalty_transactions.type` have strict enums (see memory for values)
|
||||||
|
|
||||||
|
## MediaStack
|
||||||
|
|
||||||
|
Automated media server on PVE1 VM 113. All traffic routes through WireGuard VPN → DO, bypassing home ISP.
|
||||||
|
|
||||||
|
**SSH:** From PVE1: `ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa root@10.48.200.35`
|
||||||
|
|
||||||
|
**Services:**
|
||||||
|
| Service | Port | Login |
|
||||||
|
|---------|------|-------|
|
||||||
|
| qBittorrent | :8080 | admin / Joker1974!!! |
|
||||||
|
| Sonarr | :8989 | API key: `b43e04350a594846b4ee95261c29e9e0` |
|
||||||
|
| Radarr | :7878 | API key: `53c4268360444feeae5f98c0cc24e0e3` |
|
||||||
|
| Prowlarr | :9696 | API key: `9d0ce6c5660743b5bf1c7951efc62252` |
|
||||||
|
|
||||||
|
**Media paths:** downloads → `/media/downloads/complete` | movies → `/media/movies` | tv → `/media/tv`
|
||||||
|
**Jellyfin NFS mounts** (VM 112, 10.48.200.33): `/mnt/mediastack/movies` and `/mnt/mediastack/tv`
|
||||||
|
**WireGuard:** `wg0` IP `10.200.0.4` → CT110 (10.48.200.19:51821) → DO. Kill-switch active; LAN always allowed.
|
||||||
|
**DNS:** FortiGate blocks port 53 outbound. PVE1 runs dnsmasq on :53 → 100.100.100.100. MediaStack uses `DNS=10.48.200.90`.
|
||||||
|
**Indexer:** IPTorrents via Prowlarr (cookie auth). Prowlarr syncs to Sonarr + Radarr automatically.
|
||||||
|
**GitHub:** `myronblair/mediastack` (private) — config files, systemd units, README with full setup notes.
|
||||||
|
**JARVIS agent quirks:** needs `jarvis_url`, `registration_key` (`f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518`), `ssl_verify: false` in config.
|
||||||
|
|
||||||
|
## NovaCPX Panel
|
||||||
|
|
||||||
|
Custom web hosting control panel (PVE1 VM 120, 10.48.200.110). Root SSH: `sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.110` (direct LAN — use this, Tailscale 100.86.51.18 requires re-auth periodically).
|
||||||
|
|
||||||
|
**Public URLs (via NPM → FortiGate VIP port 443 → 10.48.200.201):**
|
||||||
|
- Admin: `https://admin.novacpx.orbishosting.com` (→ port 8882) · `admin / Admin2026!` or `myron / Joker1974!!!`
|
||||||
|
- Reseller: `https://reseller.novacpx.orbishosting.com` (→ port 8881)
|
||||||
|
- User: `https://panel.novacpx.orbishosting.com` or `https://novacpx.orbishosting.com` (→ port 8880)
|
||||||
|
- Webmail: port 8883 (Roundcube) — no public NPM proxy yet
|
||||||
|
- `https://web.orbishosting.com` → port 80 (placeholder for a new hosted website)
|
||||||
|
|
||||||
|
**Ports:** 8880 (user) · 8881 (reseller) · 8882 (admin) · 8883 (Roundcube webmail)
|
||||||
|
|
||||||
|
**Paths:** Panel web root `/srv/novacpx/public/` · Git repo `/opt/novacpx-src/` · DB `/var/lib/novacpx/panel.db` (SQLite) · Config `/etc/novacpx/config.ini`
|
||||||
|
|
||||||
|
**Config notes:** `/etc/novacpx/config.ini` must have `server = nginx` (not apache) — VhostManager checks this to write the correct vhost format.
|
||||||
|
|
||||||
|
**⚠ After any restore from PBS backup:** config.ini reverts to `server = apache`. Always run: `sed -i "s/^server = apache/server = nginx/" /etc/novacpx/config.ini` after a restore. Also: PHP-FPM will fail to start if orphaned pool configs exist from pre-restore accounts — run the cleanup: `for f in /etc/php/8.3/fpm/pool.d/*.conf; do [[ "$f" == *"www.conf"* ]] && continue; u=$(basename "$f" .conf); id "$u" &>/dev/null || rm -f "$f"; done && systemctl start php8.3-fpm`. The `webacct` hosting account and its nginx vhost must be recreated after restore (Linux user survives but DB record and vhost are lost).
|
||||||
|
|
||||||
|
**GitHub:** `myronblair/novacpx` (private). Auto-deploy active: push to `main` (stable) or `beta` → webhook → VM pulls. GitHub Actions auto-bumps VERSION: main→PATCH, beta→-beta.N suffix. Current version: 1.0.40.
|
||||||
|
|
||||||
|
**Update channels:** `stable` tracks `origin/main`, `beta` tracks `origin/beta`. Set in Admin → Settings → Update Channel.
|
||||||
|
|
||||||
|
**Local clone:** `/tmp/novacpx/` on this machine. All edits go here first, then `git push origin main`. The deploy runner syncs `panel/` → `/srv/novacpx/public/` and `panel/lib/` → `/srv/novacpx/public/lib/`. For immediate changes use SCP to `root@10.48.200.110:/srv/novacpx/public/`.
|
||||||
|
|
||||||
|
**PHP-FPM:** Per-account pools in `/etc/php/8.3/fpm/pool.d/`. If php8.3-fpm fails to start, check for orphaned pool configs referencing deleted Linux users — remove them and `systemctl start php8.3-fpm`.
|
||||||
|
|
||||||
|
**JARVIS agent:** Installed, online. Agent ID: `novacpx_e3b07264`.
|
||||||
|
|
||||||
|
**SQLite quirk:** Never use MySQL syntax (ON DUPLICATE KEY, NOW(), DATE_ADD, etc.). DB.php has translate() layer but endpoints must also use SQLite syntax directly.
|
||||||
|
|
||||||
|
## Parker Slingshot Rentals
|
||||||
|
|
||||||
|
Admin portal at `/admin/index.php` uses HMAC-signed cookie auth (not PHP sessions — sessions were unreliable under LiteSpeed caching). Admin: `admin / Parker2026!`. DB: `epic_parkersling / epic_parkersling / Joker1974!!!`.
|
||||||
|
|
||||||
|
## FusionPBX / FreeSWITCH
|
||||||
|
|
||||||
|
Production at 134.209.72.226. Web: `https://fusion.orbishosting.com` (admin / fY7XP5swgtpbzrYLhkeVYkA4744). SIP profiles served via Lua XML handler — config changes require deleting `/var/cache/fusionpbx/FusionPBX.configuration.sofia.conf` to force reload. Extension 1000 (Yealink T48S at 10.48.200.43) registered on production server via port 5080 with `aggressive-nat-detection=true` to bypass FortiGate SIP ALG.
|
||||||
|
|
||||||
|
**SSH access:** Direct via Tailscale (preferred):
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Joker1974!@#' ssh -o StrictHostKeyChecking=no root@100.74.46.120
|
||||||
|
```
|
||||||
|
Fallback if Tailscale down — relay through DO:
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228 \
|
||||||
|
'sshpass -p "Joker1974!@#" ssh -o StrictHostKeyChecking=no root@134.209.72.226 "command"'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Backup:** `myronblair/fusionpbx-config` — PostgreSQL dump (gzip, ~29MB) + FreeSWITCH configs + restore wizard. Weekly Sunday 5am. Launcher: `/usr/local/bin/fusionpbx-backup`.
|
||||||
|
|
||||||
|
## Proxmox
|
||||||
|
|
||||||
|
PVE1 at 10.48.200.90, PVE2 at 10.48.200.91. Root login direct. Run commands inside VMs via:
|
||||||
|
```bash
|
||||||
|
qm guest exec <VMID> -- bash -c 'command'
|
||||||
|
```
|
||||||
|
Proxmox `--nameserver` must be space-separated: `"8.8.8.8 1.1.1.1"` (comma causes netplan bug).
|
||||||
|
|
||||||
|
**Backup:** `myronblair/proxmox-config` — shared cluster configs (VM .conf, storage, HA, SDN) + per-node (network, cron, systemd, scripts). Weekly Sunday 3am. Launcher: `/usr/local/bin/proxmox-backup` on both nodes.
|
||||||
|
|
||||||
|
## PHP / OLS Runtime
|
||||||
|
|
||||||
|
CyberPanel uses `lsphp85`. Run PHP scripts directly with:
|
||||||
|
```bash
|
||||||
|
/usr/local/lsws/lsphp85/bin/lsphp /path/to/script.php
|
||||||
|
```
|
||||||
|
For PHP syntax checking use `php8.3 -l file.php` — lsphp segfaults on `-l` flag.
|
||||||
|
When a PHP endpoint uses `ob_start()` + `header.php` pattern, add `ob_end_clean()` before any CSV/JSON response output.
|
||||||
|
|
||||||
|
**Cloudflare Rocket Loader:** JARVIS uses `data-cfasync="false"` on every `<script>` tag in `index.html` (including CDN scripts like face-api.js). One untagged script is enough to trigger Rocket Loader's bootstrap, which injects `mainScript.js` and causes `SyntaxError: Identifier 'mainScriptFlag' has already been declared`. `Cache-Control: no-store, no-cache, must-revalidate, no-transform` is set in `index.php` but tag every new script with `data-cfasync="false"` anyway.
|
||||||
|
|
||||||
|
**Cloudflare auto-deploy cache problem:** After pushing JS fixes, Cloudflare CDN serves stale cached files even on hard refresh. Bump the `?v=YYYYMMDD` query param on script tags in `index.html` to force a cache miss. Current version param: `?v=20260617b`.
|
||||||
|
|
||||||
|
**JS file structure (as of 2026-06-17):**
|
||||||
|
- `assets/js/jarvis-effects.js` — canvas particle effects, sparklines
|
||||||
|
- `assets/js/jarvis-overlays.js` — sleep overlay, network map canvas
|
||||||
|
- `assets/js/jarvis-app.js` — globals, init, chat, voice, system/network/HA/alerts/weather panels
|
||||||
|
- `assets/js/panels/jarvis-arc.js` — Arc Reactor, Intel Protocol, Comms Protocol, Guardian Mode
|
||||||
|
- `assets/js/panels/jarvis-agents.js` — Missions, Directives, Memory, Clearance, Agents tab, Sites, Vision Protocol
|
||||||
|
- `assets/js/panels/jarvis-assistant.js` — Chat History, Command Palette, Suggestions, Mobile switcher, Topology map
|
||||||
|
|
||||||
|
A SyntaxError in any panels/ file breaks only that group — other panels stay functional. `escHtml()` is defined in jarvis-arc.js (loads first) and is global to all subsequent files.
|
||||||
|
|
||||||
|
## GitHub Repos
|
||||||
|
|
||||||
|
| Repo | Site | DB Schema |
|
||||||
|
|------|------|-----------|
|
||||||
|
| myronblair/jarvis | jarvis.orbishosting.com | db/schema.sql (15 tables) |
|
||||||
|
| myronblair/tomsjavajive | tomsjavajive.com | db/schema.sql (45 tables) |
|
||||||
|
| myronblair/epictravelexpeditions | epictravelexpeditions.com | db/schema.sql (7 tables) |
|
||||||
|
| myronblair/parkerslingshot | parkerslingshot.epictravelexpeditions.com | (no schema file — DB managed directly) |
|
||||||
|
| myronblair/parkerslingshotrentals | parkerslingshotrentals.com | db/schema.sql (10 tables) |
|
||||||
|
| myronblair/orbishosting | orbishosting.com | — |
|
||||||
|
| myronblair/orbis-hosting-portal | orbis.orbishosting.com | — |
|
||||||
|
| myronblair/tomtomgames | tomtomgames.com | db/schema.sql (22 tables) |
|
||||||
|
| myronblair/infra | server configs | cron, systemd, agent configs |
|
||||||
|
| myronblair/mediastack | MediaStack VM 113 | config/, systemd units, wg0.conf, README |
|
||||||
|
| myronblair/do-server-config | DO server backup | scripts, systemd, WG, OLS vhosts, restore.sh |
|
||||||
|
| myronblair/proxmox-config | PVE1+PVE2 backup | shared cluster configs + per-node, restore.sh |
|
||||||
|
| myronblair/novacpx | admin.novacpx.orbishosting.com | db/schema.sql (SQLite, 19+ tables) |
|
||||||
|
| myronblair/web-dashboard | web.orbishosting.com | — |
|
||||||
|
| myronblair/fusionpbx-config | FusionPBX backup | PostgreSQL dump (gzip) + FS configs, restore.sh |
|
||||||
|
|
||||||
|
All repos are private. Each has `config/vhost/` with OLS vhost config. The jarvis repo also has `deploy/` (watchdog, deploy runner, systemd units) and `agent/jarvis-agent.py`.
|
||||||
|
|
||||||
|
## Split DNS (added 2026-06-21)
|
||||||
|
|
||||||
|
PVE1 dnsmasq (`/etc/dnsmasq.d/forwarder.conf`) has split DNS entries so all NPM-proxied domains resolve to `10.48.200.201` (NPM internal IP) for LAN clients — bypasses FortiGate hairpin NAT for HTTPS:
|
||||||
|
|
||||||
|
```
|
||||||
|
address=/jarvis.orbishosting.com/10.48.200.201
|
||||||
|
address=/hoa.orbishosting.com/10.48.200.201
|
||||||
|
address=/novacpx.orbishosting.com/10.48.200.201
|
||||||
|
address=/admin.novacpx.orbishosting.com/10.48.200.201
|
||||||
|
address=/reseller.novacpx.orbishosting.com/10.48.200.201
|
||||||
|
address=/panel.novacpx.orbishosting.com/10.48.200.201
|
||||||
|
address=/web.orbishosting.com/10.48.200.201
|
||||||
|
```
|
||||||
|
|
||||||
|
For any LAN device to use this: set DNS to `10.48.200.90` in Wi-Fi settings (or update FortiGate DHCP to push 10.48.200.90 as DNS for all clients).
|
||||||
|
|
||||||
|
## NovaCPX Panel (updated 2026-06-22)
|
||||||
|
|
||||||
|
Post-restore notes added — see `deploy/novacpx-post-restore.sh` which fixes config.ini, cleans pools, rebuilds webacct account. VM IDs changed after restore: MediaStack VM103, NPM VM105, Ollama VM106. Run script after any PBS restore.
|
||||||
|
|
||||||
|
**NovaCPX v1.0.54** — security fixes (CORS, open redirect, CSS injection, exception leakage), subdomains (#36), parked domains (#37), account settings page (#38), better default index (#39), post-restore script (#50), collapsible nav (#48).
|
||||||
|
|
||||||
|
**web.orbishosting.com** — Blair HQ dashboard with server-backed notes (notes.php → /home/webacct/notes.json). Password: myronblair@outlook.com / Joker1974!!!
|
||||||
@@ -0,0 +1,738 @@
|
|||||||
|
# INFRASTRUCTURE REFERENCE — COMPLETE SYSTEM MAP
|
||||||
|
**Last Updated:** 2026-06-14
|
||||||
|
**Owner:** Myron Blair — myronblair@outlook.com
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
1. [Network Overview](#1-network-overview)
|
||||||
|
2. [Cloud Servers](#2-cloud-servers)
|
||||||
|
3. [On-Premise — Proxmox Hypervisors](#3-on-premise--proxmox-hypervisors)
|
||||||
|
4. [On-Premise — Virtual Machines](#4-on-premise--virtual-machines)
|
||||||
|
5. [NAS Storage](#5-nas-storage)
|
||||||
|
6. [Websites (all on DO)](#6-websites--all-on-do)
|
||||||
|
7. [JARVIS AI System](#7-jarvis-ai-system)
|
||||||
|
8. [Phone System (FusionPBX)](#8-phone-system-fusionpbx)
|
||||||
|
9. [Networking & VPN](#9-networking--vpn)
|
||||||
|
10. [Backup Systems](#10-backup-systems)
|
||||||
|
11. [SSH Quick Reference](#11-ssh-quick-reference)
|
||||||
|
12. [Critical Credentials Master List](#12-critical-credentials-master-list)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. NETWORK OVERVIEW
|
||||||
|
|
||||||
|
```
|
||||||
|
INTERNET
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
[Cloudflare CDN] ──────────────────────────────────────────────────────────────
|
||||||
|
│ (proxied DNS for public sites)
|
||||||
|
│
|
||||||
|
├─► [DigitalOcean 165.22.1.228] — CyberPanel/OLS — All websites + JARVIS
|
||||||
|
│
|
||||||
|
└─► [FusionPBX 134.209.72.226] — FreeSWITCH PBX (SSH via DO relay)
|
||||||
|
|
||||||
|
HOME NETWORK (FortiGate router at 10.48.200.1)
|
||||||
|
WAN: 97.154.109.245 (dynamic, DDNS: orbisne.fortiddns.com)
|
||||||
|
│
|
||||||
|
├─► PVE1 Proxmox 10.48.200.90 (primary hypervisor)
|
||||||
|
│ ├── VM 101 10.48.200.97 Home Assistant
|
||||||
|
│ ├── VM 112 10.48.200.33 Jellyfin
|
||||||
|
│ ├── VM 113 10.48.200.35 MediaStack (Sonarr/Radarr/qBT/Prowlarr)
|
||||||
|
│ ├── VM 118 10.48.200.18 Homebridge
|
||||||
|
│ ├── VM 120 10.48.200.110 NovaCPX hosting panel
|
||||||
|
│ ├── VM 210 10.48.200.95 Ollama (local LLM)
|
||||||
|
│ └── CT110 10.48.200.19 WireGuard exit container
|
||||||
|
│
|
||||||
|
├─► PVE2 Proxmox 10.48.200.91 (secondary hypervisor)
|
||||||
|
│ └── VM 302 10.48.200.99 NetworkBackup
|
||||||
|
│
|
||||||
|
├─► Synology NAS 10.48.200.249 — Media & backup storage
|
||||||
|
├─► Yealink T48S 10.48.200.2 — Ext 1000 (Myron Blair, Desk)
|
||||||
|
├─► Yealink T48S 10.48.200.43 — Ext 1001 (Tommy Ivy, Desk)
|
||||||
|
├─► Yealink AX86R 10.48.200.65 — Ext 1002 (Myron Blair, WiFi Work)
|
||||||
|
├─► Yealink T57W 10.48.200.3 — External SIP (United Mirror & Glass)
|
||||||
|
├─► Yealink T57W 10.48.200.83 — Ext 1003 (Kitchen)
|
||||||
|
└─► Yealink T57W 10.48.200.85 — Ext 1004 (Master Bedroom)
|
||||||
|
|
||||||
|
FortiGate Port Forwards:
|
||||||
|
orbisne.fortiddns.com:8006 → PVE1:8006 (Proxmox web UI)
|
||||||
|
orbisne.fortiddns.com:8123 → HA:8123 (Home Assistant)
|
||||||
|
orbisne.fortiddns.com:22 → HA VM:22 (SSH — key only, unreliable)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. CLOUD SERVERS
|
||||||
|
|
||||||
|
### 2A. DigitalOcean — Main Server
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 165.22.1.228 |
|
||||||
|
| **OS** | Ubuntu 22.04 LTS |
|
||||||
|
| **Panel** | CyberPanel (OpenLiteSpeed) |
|
||||||
|
| **SSH** | `ssh root@165.22.1.228` — password: `Gonewalk1974!@#` |
|
||||||
|
| **Purpose** | All public websites + JARVIS AI + webhook deploy system |
|
||||||
|
|
||||||
|
**Key Paths:**
|
||||||
|
- All sites: `/home/<domain>/public_html/`
|
||||||
|
- JARVIS: `/home/jarvis.orbishosting.com/`
|
||||||
|
- Deploy log: `/home/jarvis.orbishosting.com/logs/deploy.log`
|
||||||
|
- Watchdog log: `/home/jarvis.orbishosting.com/logs/watchdog.log`
|
||||||
|
- Infra repo: `/opt/infra`
|
||||||
|
|
||||||
|
**Services running:**
|
||||||
|
- OpenLiteSpeed web server (`lsws`) — serves all 7 sites
|
||||||
|
- MySQL 8 — all site databases on localhost
|
||||||
|
- Redis — session/cache
|
||||||
|
- PHP 8.5 (`lsphp85`) — runtime for all sites
|
||||||
|
- Cron jobs: JARVIS deploy runner (every 1 min), facts collector (every 3 min), stats cache (every 5 min), watchdog (every 5 min)
|
||||||
|
|
||||||
|
**CyberPanel Web UI:** `https://165.22.1.228:8090`
|
||||||
|
Login: `myron / Joker1974!!!`
|
||||||
|
|
||||||
|
**phpMyAdmin:** `https://165.22.1.228/phpmyadmin`
|
||||||
|
Login: `myron / Joker1974!!!`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2B. FusionPBX / FreeSWITCH — PBX Server
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 134.209.72.226 |
|
||||||
|
| **OS** | Debian (DigitalOcean droplet) |
|
||||||
|
| **SSH** | Must relay via DO: `ssh root@165.22.1.228` → `ssh root@134.209.72.226` — password: `Joker1974!@#` |
|
||||||
|
| **Direct SSH** | Only from: 107.178.2.130 / 97.154.109.245 |
|
||||||
|
| **Purpose** | VoIP phone system — handles all inbound/outbound calls |
|
||||||
|
|
||||||
|
**Web UI:** `https://fusion.orbishosting.com`
|
||||||
|
Login: `admin / fY7XP5swgtpbzrYLhkeVYkA4744`
|
||||||
|
|
||||||
|
**Database:** PostgreSQL
|
||||||
|
User: `fusionpbx` / Password: `pSJaF9mUJqPr4Sj5mwJyRqvCCpc` / Host: 127.0.0.1
|
||||||
|
|
||||||
|
**SIP Trunk:** SignalWire
|
||||||
|
DID: +1 (817) 764-5007
|
||||||
|
Gateway: `signalwire` on external profile (port 5080, UDP)
|
||||||
|
|
||||||
|
**How calls flow:**
|
||||||
|
```
|
||||||
|
Caller → SignalWire SIP → FusionPBX:5080 → IVR (ext 900) → Ring extensions
|
||||||
|
Outbound: Phone → FusionPBX:5080 → SignalWire → PSTN
|
||||||
|
```
|
||||||
|
|
||||||
|
**SSH Relay Command:**
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228 \
|
||||||
|
'sshpass -p "Joker1974!@#" ssh -o StrictHostKeyChecking=no root@134.209.72.226 "COMMAND"'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. ON-PREMISE — PROXMOX HYPERVISORS
|
||||||
|
|
||||||
|
### PVE1 — Primary Hypervisor
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **Local IP** | 10.48.200.90 |
|
||||||
|
| **External** | orbisne.fortiddns.com (FortiGate DDNS — auto-updates on WAN IP change) |
|
||||||
|
| **OS** | Proxmox VE 8.x |
|
||||||
|
| **SSH** | `ssh root@orbisne.fortiddns.com` OR `ssh root@10.48.200.90` — password: `Joker1974!!!` |
|
||||||
|
| **Web UI** | `https://orbisne.fortiddns.com:8006` — `root / Joker1974!!!` |
|
||||||
|
| **Purpose** | Runs VMs 101, 112, 113, 118, 120, 210, CT110 |
|
||||||
|
|
||||||
|
**Useful commands:**
|
||||||
|
```bash
|
||||||
|
qm list # list all VMs
|
||||||
|
qm start/stop/restart <VMID> # control VMs
|
||||||
|
qm guest exec <VMID> -- bash -c "cmd" # run command inside VM (requires QEMU agent)
|
||||||
|
```
|
||||||
|
|
||||||
|
**JARVIS API Token:** `root@pam!jarvis=c45b5feb-f9a9-445d-a626-14fbb959f78b`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### PVE2 — Secondary Hypervisor
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **Local IP** | 10.48.200.91 |
|
||||||
|
| **OS** | Proxmox VE 8.x |
|
||||||
|
| **SSH** | `ssh root@10.48.200.91` — password: `Joker1974!!!` |
|
||||||
|
| **Web UI** | `https://10.48.200.91:8006` — `root / Joker1974!!!` |
|
||||||
|
| **Purpose** | Runs VM 302 (NetworkBackup); part of shared Proxmox cluster with PVE1 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. ON-PREMISE — VIRTUAL MACHINES
|
||||||
|
|
||||||
|
### VM 101 — Home Assistant (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.97 |
|
||||||
|
| **OS** | Ubuntu + Home Assistant OS/Supervised |
|
||||||
|
| **Web UI** | `http://orbisne.fortiddns.com:8123` — `myron / [HA password]` |
|
||||||
|
| **SSH** | Via HA web terminal only (Settings → Add-ons → Advanced SSH & Web Terminal) |
|
||||||
|
| **Purpose** | Smart home automation — 212 entities (lights, switches, scenes, sensors) |
|
||||||
|
| **JARVIS Agent** | ID: `homeassistant_ha` — pushes entity states to JARVIS every 10s |
|
||||||
|
|
||||||
|
**JARVIS ↔ HA Integration:**
|
||||||
|
- HA custom component at `/config/custom_components/jarvis_agent/`
|
||||||
|
- Pushes all entity state changes to JARVIS `/api/agent/ha_state` (debounced 2s)
|
||||||
|
- JARVIS admin toggles → queued in `agent_commands` table → HA executes natively
|
||||||
|
- HA Long-lived Token (Jarvis2): `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzNmI0N2I1Njk5ZGQ0MTQ2ODMwZWFmYjZiYTQ1MjJkMSIsImlhdCI6MTc4MDIwMzU5NCwiZXhwIjoyMDk1NTYzNTk0fQ.sYRok-jRDlA4lFgWxLQELcEjkJNGQdprk6ZziLwLtXE`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 112 — Jellyfin Media Server (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.33 |
|
||||||
|
| **OS** | Ubuntu 22.04 LTS |
|
||||||
|
| **SSH** | `ssh root@10.48.200.33` — password: `Joker1974!!!` (enabled 2026-06-14) |
|
||||||
|
| **Web UI** | `http://10.48.200.33:8096` |
|
||||||
|
| **Purpose** | Media streaming server — Movies and TV shows |
|
||||||
|
| **JARVIS Agent** | Not yet installed |
|
||||||
|
|
||||||
|
**Media Libraries:**
|
||||||
|
- Movies: `/mnt/mediastack/movies` — NFS from MediaStack (10.48.200.35:/media/movies)
|
||||||
|
- TV: `/mnt/mediastack/tv` — NFS from MediaStack (10.48.200.35:/media/tv)
|
||||||
|
|
||||||
|
**NFS chain:** Jellyfin → MediaStack → Synology NAS (`/volume1/video/movies` and `/volume1/video/tv`)
|
||||||
|
|
||||||
|
**Admin token:** `7c0ccf78b91d4b5bafa607f585f24f2d`
|
||||||
|
|
||||||
|
**If library scan needed:**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://10.48.200.33:8096/Library/Refresh" \
|
||||||
|
-H "X-Emby-Token: 7c0ccf78b91d4b5bafa607f585f24f2d"
|
||||||
|
```
|
||||||
|
|
||||||
|
**If NFS stale after MediaStack changes:**
|
||||||
|
```bash
|
||||||
|
umount -l /mnt/mediastack/movies && umount -l /mnt/mediastack/tv
|
||||||
|
mount /mnt/mediastack/movies && mount /mnt/mediastack/tv
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 113 — MediaStack (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.35 |
|
||||||
|
| **OS** | Ubuntu 24.04 LTS |
|
||||||
|
| **SSH** | Via PVE1: `ssh -i /root/.ssh/id_rsa root@10.48.200.35` (no direct access from DO) |
|
||||||
|
| **Purpose** | Automated media download pipeline + NFS server to Jellyfin |
|
||||||
|
| **JARVIS Agent** | ID: `MediaStack_2c00b1b8` |
|
||||||
|
|
||||||
|
**Services:**
|
||||||
|
| Service | Port | Login | API Key |
|
||||||
|
|---------|------|-------|---------|
|
||||||
|
| qBittorrent | :8080 | `admin / Joker1974!!!` | — |
|
||||||
|
| Sonarr | :8989 | `admin / Joker1974!!!` | `b43e04350a594846b4ee95261c29e9e0` |
|
||||||
|
| Radarr | :7878 | `admin / Joker1974!!!` | `53c4268360444feeae5f98c0cc24e0e3` |
|
||||||
|
| Prowlarr | :9696 | `admin / Joker1974!!!` | `9d0ce6c5660743b5bf1c7951efc62252` |
|
||||||
|
|
||||||
|
**All services run as root** — required by Synology NFS ACL (only root can write).
|
||||||
|
|
||||||
|
**VPN:** NordVPN — `nordlynx` WireGuard interface — exit IP 181.214.226.188 (US Dallas)
|
||||||
|
All download traffic exits via NordVPN. If downloads stall, check: `ip rule show` for rules 32764/32765.
|
||||||
|
|
||||||
|
**Media Flow:**
|
||||||
|
```
|
||||||
|
IPTorrents (Prowlarr) → Sonarr/Radarr search → qBittorrent download
|
||||||
|
→ /mnt/nas/video/downloads (NAS)
|
||||||
|
→ Sonarr/Radarr import → /mnt/nas/video/tv or /mnt/nas/video/movies (NAS)
|
||||||
|
→ NFS → Jellyfin /mnt/mediastack/movies or /mnt/mediastack/tv
|
||||||
|
```
|
||||||
|
|
||||||
|
**Indexer:** IPTorrents via Prowlarr cookie auth
|
||||||
|
Cookie: `uid=2237410; pass=JzLP2niTWxBJAZIU3yvtLbJzD55kdLeB`
|
||||||
|
(Expires — if search fails, log into iptorrents.com, copy uid+pass cookies)
|
||||||
|
|
||||||
|
**If Radarr/Sonarr shows "0 active indexers":**
|
||||||
|
```bash
|
||||||
|
systemctl stop radarr
|
||||||
|
sqlite3 /var/lib/radarr/radarr.db "DELETE FROM IndexerStatus WHERE ProviderId=1;"
|
||||||
|
systemctl start radarr
|
||||||
|
```
|
||||||
|
|
||||||
|
**SSH from DO:**
|
||||||
|
```bash
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.90 \
|
||||||
|
'ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa root@10.48.200.35 "COMMAND"'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 118 — Homebridge (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.18 |
|
||||||
|
| **OS** | Linux |
|
||||||
|
| **SSH** | `ssh myron@10.48.200.18` — password: `Joker1974!` |
|
||||||
|
| **Purpose** | Apple HomeKit bridge — exposes non-HomeKit devices to Apple Home app |
|
||||||
|
| **JARVIS Agent** | ID: `homebridge_b57cbaea` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 120 — NovaCPX Hosting Panel (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.110 |
|
||||||
|
| **OS** | Ubuntu 24.04 LTS |
|
||||||
|
| **SSH** | `ssh root@10.48.200.110` — password: `Joker1974!!!` (direct, no PVE hop) |
|
||||||
|
| **Purpose** | Custom web hosting control panel (cPanel alternative), v1.0.27 |
|
||||||
|
| **JARVIS Agent** | ID: `novacpx_e3b07264` |
|
||||||
|
|
||||||
|
**Ports:**
|
||||||
|
| Port | Panel |
|
||||||
|
|------|-------|
|
||||||
|
| :8880 | User panel |
|
||||||
|
| :8881 | Reseller panel |
|
||||||
|
| :8882 | Admin panel |
|
||||||
|
| :8883 | Roundcube webmail |
|
||||||
|
|
||||||
|
**Admin:** `https://10.48.200.110:8882` — `admin / Admin2026!`
|
||||||
|
**phpMyAdmin:** `http://10.48.200.110/phpmyadmin`
|
||||||
|
|
||||||
|
**File Paths:**
|
||||||
|
- Web root: `/srv/novacpx/public/`
|
||||||
|
- DB (SQLite): `/var/lib/novacpx/panel.db`
|
||||||
|
- Config: `/etc/novacpx/config.ini`
|
||||||
|
- Git repo: `/opt/novacpx-src/`
|
||||||
|
- GitHub: `myronblair/novacpx` (auto-deploy on push to `main`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 210 — Ollama Local LLM (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.95 |
|
||||||
|
| **OS** | Ubuntu (cloud image) |
|
||||||
|
| **SSH** | `ssh myron@10.48.200.95` — password: `Joker1974!` (then `sudo`) |
|
||||||
|
| **Purpose** | Local AI inference — runs llama3.2 model for JARVIS Tier 1 chat |
|
||||||
|
| **API** | `http://10.48.200.95:11434` (Ollama REST API) |
|
||||||
|
| **JARVIS Agent** | ID: `ollama-ai_ubuntu` |
|
||||||
|
|
||||||
|
**JARVIS uses this as Tier 1 AI** — if Ollama is down, falls back to Groq (cloud).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### VM 302 — NetworkBackup (PVE2)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.99 |
|
||||||
|
| **OS** | Ubuntu/Linux |
|
||||||
|
| **SSH** | `ssh myron@10.48.200.99` — password: `Joker1974!` (then `sudo`) |
|
||||||
|
| **Purpose** | Network backup storage / backup operations |
|
||||||
|
| **JARVIS Agent** | ID: `networkbackup_NetworkB` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CT110 — WireGuard Exit Container (PVE1)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.19 / 10.48.200.67 |
|
||||||
|
| **Purpose** | Legacy WireGuard exit tunnel to DO (10.200.0.4 via wg-exit) — currently NOT used by MediaStack/Jellyfin |
|
||||||
|
| **Note** | MediaStack uses NordVPN directly; Jellyfin uses wg1 peer on MediaStack for NFS only |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. NAS STORAGE
|
||||||
|
|
||||||
|
### Synology NAS
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **IP** | 10.48.200.249 |
|
||||||
|
| **Login** | `nas / Joker1974!!!` |
|
||||||
|
| **DSM Web UI** | `http://10.48.200.249:5000` |
|
||||||
|
| **Purpose** | Primary media and download storage |
|
||||||
|
|
||||||
|
**NFS Share:** `/volume1/video` (exported to MediaStack only)
|
||||||
|
|
||||||
|
**Directory structure:**
|
||||||
|
```
|
||||||
|
/volume1/video/
|
||||||
|
movies/ ← Radarr imports here; NFS-exported to Jellyfin via MediaStack
|
||||||
|
tv/ ← Sonarr imports here; NFS-exported to Jellyfin via MediaStack
|
||||||
|
downloads/ ← qBittorrent downloads here (temp)
|
||||||
|
incomplete/ ← in-progress torrents
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** Synology NFS ACL only allows root to write. All services on MediaStack run as root.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. WEBSITES (ALL ON DO)
|
||||||
|
|
||||||
|
All sites are at `/home/<domain>/public_html/` on DO (165.22.1.228).
|
||||||
|
**Auto-deploy:** Push to `main` on GitHub → webhook → server pulls in ~1 min.
|
||||||
|
**GitHub PAT:** `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` (expires ~2026-08-20)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### jarvis.orbishosting.com — JARVIS AI Dashboard
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://jarvis.orbishosting.com |
|
||||||
|
| **Path** | `/home/jarvis.orbishosting.com/` |
|
||||||
|
| **GitHub** | `myronblair/jarvis` |
|
||||||
|
| **Login** | `myron / Joker1974!!!` |
|
||||||
|
| **Purpose** | Iron Man-style AI home dashboard with voice control, smart home, media, planner |
|
||||||
|
|
||||||
|
See Section 7 for full JARVIS details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### tomsjavajive.com — Tom's Java Jive
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://tomsjavajive.com |
|
||||||
|
| **Path** | `/home/tomsjavajive.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/tomsjavajive` |
|
||||||
|
| **Purpose** | Coffee shop e-commerce — products, orders, loyalty, wallet, reviews |
|
||||||
|
| **Admin URL** | `https://tomsjavajive.com/admin/` |
|
||||||
|
| **Admin Login** | `admin@tomsjavajive.com / Joker1974!!!` OR `myronblair@outlook.com / Joker1974!!!` |
|
||||||
|
| **DB** | `toms_tjj_db / toms_tjj_user / +60wlPc+55e@gFq4` |
|
||||||
|
| **Email** | CyberMail API key: `sk_live_7f9b0f9a29f6de31a0d229d4af75d56b094ad724fc58a57d` |
|
||||||
|
| **Email From** | `noreply@tomsjavajive.com` / `Toms Java Jive` (set in DB settings table) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### epictravelexpeditions.com — Epic Travel Expeditions
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://epictravelexpeditions.com |
|
||||||
|
| **Path** | `/home/epictravelexpeditions.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/epictravelexpeditions` |
|
||||||
|
| **Purpose** | Travel booking / expeditions website |
|
||||||
|
| **DB** | `epic_travel_db` (see `api/config.php`) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### parkerslingshot.epictravelexpeditions.com — Parker Slingshot (OLD)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://parkerslingshot.epictravelexpeditions.com |
|
||||||
|
| **Path** | `/home/epictravelexpeditions.com/parkerslingshot/` |
|
||||||
|
| **GitHub** | `myronblair/parkerslingshot` |
|
||||||
|
| **Purpose** | Old slingshot rental site (superseded by parkerslingshotrentals.com) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### parkerslingshotrentals.com — Parker Slingshot Rentals (LIVE)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://www.parkerslingshotrentals.com |
|
||||||
|
| **Path** | `/home/parkerslingshotrentals.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/parkerslingshotrentals` |
|
||||||
|
| **Purpose** | Polaris Slingshot rental — bookings, e-signature waiver, admin management |
|
||||||
|
| **Admin** | `/admin/index.php` — `admin / Parker2026!` |
|
||||||
|
| **DB** | `park_slingshot / park_slingshotuser / 4@rxg*8kovxCr7w6` |
|
||||||
|
| **Square** | Production token: `EAAAl3FsAu_2ri8kZE_ENEyi2T_C8HXXm5XQFY6Lbnd8SX6FqYp8J_upUeXNYh7v` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### orbishosting.com — Orbis Hosting (Landing Page)
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://orbishosting.com |
|
||||||
|
| **Path** | `/home/orbishosting.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/orbishosting` |
|
||||||
|
| **Purpose** | Public landing page for Orbis Hosting brand |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### orbis.orbishosting.com — Orbis Hosting Portal
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://orbis.orbishosting.com |
|
||||||
|
| **Path** | `/home/orbis.orbishosting.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/orbis-hosting-portal` |
|
||||||
|
| **Purpose** | Customer-facing hosting portal |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### tomtomgames.com — TomTom Games
|
||||||
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| **URL** | https://tomtomgames.com |
|
||||||
|
| **Path** | `/home/tomtomgames.com/public_html/` |
|
||||||
|
| **GitHub** | `myronblair/tomtomgames` |
|
||||||
|
| **Purpose** | Gaming website |
|
||||||
|
| **DB** | `tomtom_games_db` (see config) |
|
||||||
|
| **Email** | CyberMail API key: `sk_live_7f9b...` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. JARVIS AI SYSTEM
|
||||||
|
|
||||||
|
**URL:** https://jarvis.orbishosting.com
|
||||||
|
**Files:** `/home/jarvis.orbishosting.com/` on DO
|
||||||
|
**DB:** `jarvis_db` — `jarvis_user / J4rv1s_Pr0t0c0l_2026!`
|
||||||
|
**Login:** `myron / Joker1974!!!`
|
||||||
|
**Admin portal:** https://jarvis.orbishosting.com/admin
|
||||||
|
|
||||||
|
### Architecture (end-to-end)
|
||||||
|
|
||||||
|
```
|
||||||
|
Voice (browser mic)
|
||||||
|
→ SpeechRecognition API
|
||||||
|
→ Wake phrase: "wake up JARVIS" / "daddy's home"
|
||||||
|
→ "JARVIS [command]" triggers action
|
||||||
|
→ /api/chat.php (4-tier AI)
|
||||||
|
Tier 0.7: KB intents / planner (tasks, appointments)
|
||||||
|
Tier 1: Knowledge Base (MySQL)
|
||||||
|
Tier 1.5: Ollama (10.48.200.95:11434, llama3.2) — local LLM
|
||||||
|
Tier 2: Groq (cloud, model: compound-beta-mini)
|
||||||
|
Tier 3: Claude API (Anthropic, fallback)
|
||||||
|
→ ElevenLabs TTS → browser speaker
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy Pipeline
|
||||||
|
```
|
||||||
|
Code edit → git push → GitHub webhook → /webhook.php (HMAC verified)
|
||||||
|
→ /tmp/jarvis-deploy-queue.txt → /usr/local/bin/jarvis-deploy.sh (cron 1min)
|
||||||
|
→ git pull + PHP syntax check → deploy or auto-revert
|
||||||
|
```
|
||||||
|
Webhook secret: `4c8805f0285214ff0a0602b5880270b935f36a896946c7f1`
|
||||||
|
|
||||||
|
### Agent System
|
||||||
|
Agents installed on all servers — phone home every 10s (heartbeat) / 30s (metrics).
|
||||||
|
Registration key: `f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518`
|
||||||
|
Install command: `curl -sk https://jarvis.orbishosting.com/install-agent.sh | bash -s <hostname> <linux|proxmox>`
|
||||||
|
|
||||||
|
### Self-Healing Watchdog
|
||||||
|
`/usr/local/bin/jarvis-watchdog.sh` — runs every 5 min (root cron on DO)
|
||||||
|
Restarts: lsws, mysql, redis if down
|
||||||
|
Restarts offline Proxmox VM agents via `qm guest exec`
|
||||||
|
|
||||||
|
### Cron Jobs (DO server)
|
||||||
|
| Schedule | Script | Purpose |
|
||||||
|
|----------|--------|---------|
|
||||||
|
| Every 1 min | `jarvis-deploy.sh` | Process GitHub deploy queue |
|
||||||
|
| Every 3 min | `facts_collector.php` | Collect agent metrics, KB facts, site health |
|
||||||
|
| Every 5 min | `stats_cache.php` | Weather, news, Proxmox stats refresh |
|
||||||
|
| Every 5 min | `jarvis-watchdog.sh` | Self-healing: restart dead services |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. PHONE SYSTEM (FUSIONPBX)
|
||||||
|
|
||||||
|
### Extensions
|
||||||
|
| Ext | Name | Phone | IP | SIP Password |
|
||||||
|
|-----|------|-------|----|-------------|
|
||||||
|
| 1000 | Myron Blair — Desk | Yealink T48S | 10.48.200.2 | `Xk9mPw3nQv7rLs2t` |
|
||||||
|
| 1001 | Tommy Ivy — Desk | Yealink T48S | 10.48.200.43 | `Tv8xNm4pWq6rZs3k` |
|
||||||
|
| 1002 | Myron Blair — WiFi Work | Yealink AX86R | 10.48.200.65 | `yXHaJTwa8rj?$GkrVFQB` |
|
||||||
|
| 1003 | Kitchen | Yealink T57W | 10.48.200.83 | — |
|
||||||
|
| 1004 | Master Bedroom | Yealink T57W | 10.48.200.85 | — |
|
||||||
|
| 1010 | Parker County Slingshot | Virtual (voicemail only) | — | — |
|
||||||
|
| 1011 | Epic Travel Expeditions | Virtual (voicemail only) | — | — |
|
||||||
|
| 1012 | Tom's Java Jive | Virtual (voicemail only) | — | — |
|
||||||
|
| 900 | IVR | — | — | (auto-attendant) |
|
||||||
|
|
||||||
|
**Phone SIP Settings (all phones):**
|
||||||
|
- Server: `134.209.72.226`
|
||||||
|
- Port: `5080`
|
||||||
|
- Transport: UDP
|
||||||
|
|
||||||
|
**Provisioning URL:** `https://fusion.orbishosting.com/app/provision/`
|
||||||
|
(Username: `provision-master`, Password: `Joker1974!!!`)
|
||||||
|
|
||||||
|
### Call Flow
|
||||||
|
```
|
||||||
|
Inbound (+18177645007)
|
||||||
|
→ SignalWire → FusionPBX:5080 (UDP)
|
||||||
|
→ signalwire-inbound dialplan (catch-all ^.*$)
|
||||||
|
→ IVR ext 900 (ivr_menu_16k.wav)
|
||||||
|
→ Routes to extensions 1000/1001/1002/1003/1004
|
||||||
|
|
||||||
|
Outbound
|
||||||
|
→ Phone → FusionPBX:5080
|
||||||
|
→ signalwire gateway → SignalWire → PSTN
|
||||||
|
```
|
||||||
|
|
||||||
|
### FreeSWITCH CLI Commands
|
||||||
|
```bash
|
||||||
|
fs_cli -x "sofia status profile external reg" # check registrations
|
||||||
|
fs_cli -x "sofia xmlstatus gateway" # check SignalWire gateway
|
||||||
|
fs_cli -x "reloadxml" # reload config (safe)
|
||||||
|
fs_cli -x "reloadacl" # reload ACL (safe)
|
||||||
|
# AVOID: sofia profile external restart (drops all phone registrations)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. NETWORKING & VPN
|
||||||
|
|
||||||
|
### FortiGate Firewall
|
||||||
|
- WAN IP: 97.154.109.245 (dynamic)
|
||||||
|
- DDNS: `orbisne.fortiddns.com` (FortiGate auto-updates on IP change)
|
||||||
|
- Blocks: outbound port 53 (DNS) — MediaStack uses PVE1 dnsmasq (10.48.200.90) as resolver → 100.100.100.100
|
||||||
|
|
||||||
|
**Port Forwards:**
|
||||||
|
| External Port | Internal Destination | Purpose |
|
||||||
|
|--------------|---------------------|---------|
|
||||||
|
| :8006 | PVE1:8006 | Proxmox web UI |
|
||||||
|
| :8123 | HA VM:8123 | Home Assistant |
|
||||||
|
| :22 | HA VM:22 | HA SSH (unreliable) |
|
||||||
|
|
||||||
|
### WireGuard — Jellyfin ↔ MediaStack
|
||||||
|
- MediaStack runs WireGuard server on `wg1` (port 51820, subnet 10.200.0.1/24)
|
||||||
|
- Jellyfin peer: 10.200.0.3 (active handshake)
|
||||||
|
- Used for NFS media file access ONLY — not internet VPN
|
||||||
|
|
||||||
|
### NordVPN — MediaStack Internet Traffic
|
||||||
|
- Interface: `nordlynx` on MediaStack
|
||||||
|
- Exit IP: 181.214.226.188 (US Dallas)
|
||||||
|
- Policy routing: table 205 (all traffic via nordlynx), managed by `nordvpn-routing.service`
|
||||||
|
- Required for IPTorrents access (blocks non-VPN IPs)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. BACKUP SYSTEMS
|
||||||
|
|
||||||
|
### DO Server Backup
|
||||||
|
- **Repo:** `myronblair/do-server-config`
|
||||||
|
- **Schedule:** Weekly, Sunday 4am
|
||||||
|
- **Launcher:** `/usr/local/bin/do-server-backup` on DO
|
||||||
|
- **Covers:** Scripts, systemd units, WireGuard, OLS vhosts, cron, MySQL credentials
|
||||||
|
- **Restore:** 8-phase wizard in `restore.sh`
|
||||||
|
- **DB backups:** `jarvis-backup.sh` runs daily (separate)
|
||||||
|
|
||||||
|
### Proxmox Config Backup
|
||||||
|
- **Repo:** `myronblair/proxmox-config`
|
||||||
|
- **Schedule:** Weekly, Sunday 3am (both PVE1 and PVE2)
|
||||||
|
- **Launcher:** `/usr/local/bin/proxmox-backup` on each node
|
||||||
|
- **Covers:** VM .conf files, network, cron, systemd, scripts
|
||||||
|
- **VM disks:** Covered by Proxmox Backup Server (PBS)
|
||||||
|
|
||||||
|
### FusionPBX Backup
|
||||||
|
- **Repo:** `myronblair/fusionpbx-config`
|
||||||
|
- **Schedule:** Weekly, Sunday 5am
|
||||||
|
- **Launcher:** `/usr/local/bin/fusionpbx-backup`
|
||||||
|
- **Covers:** PostgreSQL dump (gzip, ~29MB) + FreeSWITCH configs
|
||||||
|
- **Restore:** 10-phase wizard in `restore.sh`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. SSH QUICK REFERENCE
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# DO (main web server)
|
||||||
|
sshpass -p 'Gonewalk1974!@#' ssh -o StrictHostKeyChecking=no root@165.22.1.228
|
||||||
|
|
||||||
|
# FusionPBX (must relay via DO)
|
||||||
|
sshpass -p 'Gonewalk1974!@#' ssh root@165.22.1.228 \
|
||||||
|
'sshpass -p "Joker1974!@#" ssh root@134.209.72.226 "CMD"'
|
||||||
|
|
||||||
|
# PVE1 (direct or via DDNS)
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@orbisne.fortiddns.com
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.90
|
||||||
|
|
||||||
|
# PVE2
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.91
|
||||||
|
|
||||||
|
# MediaStack (via PVE1)
|
||||||
|
sshpass -p 'Joker1974!!!' ssh root@10.48.200.90 \
|
||||||
|
'ssh -i /root/.ssh/id_rsa root@10.48.200.35 "CMD"'
|
||||||
|
|
||||||
|
# Jellyfin (direct, password enabled 2026-06-14)
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.33
|
||||||
|
|
||||||
|
# NovaCPX (direct)
|
||||||
|
sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.110
|
||||||
|
|
||||||
|
# Ollama / Homebridge / NetworkBackup (myron user, then sudo)
|
||||||
|
sshpass -p 'Joker1974!' ssh myron@10.48.200.95 # Ollama
|
||||||
|
sshpass -p 'Joker1974!' ssh myron@10.48.200.18 # Homebridge
|
||||||
|
sshpass -p 'Joker1974!' ssh myron@10.48.200.99 # NetworkBackup
|
||||||
|
|
||||||
|
# Run command inside VM via Proxmox (requires QEMU agent installed)
|
||||||
|
sshpass -p 'Joker1974!!!' ssh root@10.48.200.90 \
|
||||||
|
'qm guest exec 210 -- bash -c "CMD"'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Password fallback order:** `Joker1974!@#` → `Joker1974!!!` → `Joker1974!`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. CRITICAL CREDENTIALS MASTER LIST
|
||||||
|
|
||||||
|
### SSH / Root Access
|
||||||
|
| System | User | Password | Notes |
|
||||||
|
|--------|------|----------|-------|
|
||||||
|
| DO (165.22.1.228) | root | `Gonewalk1974!@#` | Main web server |
|
||||||
|
| FusionPBX (134.209.72.226) | root | `Joker1974!@#` | Via DO relay |
|
||||||
|
| PVE1 (10.48.200.90) | root | `Joker1974!!!` | Also via DDNS |
|
||||||
|
| PVE2 (10.48.200.91) | root | `Joker1974!!!` | |
|
||||||
|
| MediaStack (10.48.200.35) | root | key only | Via PVE1 (`/root/.ssh/id_rsa`) |
|
||||||
|
| Jellyfin (10.48.200.33) | root | `Joker1974!!!` | Enabled 2026-06-14 |
|
||||||
|
| NovaCPX (10.48.200.110) | root | `Joker1974!!!` | Direct SSH works |
|
||||||
|
| Ollama / Homebridge / Backup VMs | myron | `Joker1974!` | Then sudo |
|
||||||
|
|
||||||
|
### Web Panels & Admin
|
||||||
|
| System | URL | User | Password |
|
||||||
|
|--------|-----|------|----------|
|
||||||
|
| CyberPanel | https://165.22.1.228:8090 | myron | `Joker1974!!!` |
|
||||||
|
| phpMyAdmin (DO) | https://165.22.1.228/phpmyadmin | myron | `Joker1974!!!` |
|
||||||
|
| Proxmox PVE1 | https://orbisne.fortiddns.com:8006 | root | `Joker1974!!!` |
|
||||||
|
| Proxmox PVE2 | https://10.48.200.91:8006 | root | `Joker1974!!!` |
|
||||||
|
| JARVIS | https://jarvis.orbishosting.com | myron | `Joker1974!!!` |
|
||||||
|
| JARVIS Admin | https://jarvis.orbishosting.com/admin | myron | `Joker1974!!!` |
|
||||||
|
| FusionPBX | https://fusion.orbishosting.com | admin | `fY7XP5swgtpbzrYLhkeVYkA4744` |
|
||||||
|
| Home Assistant | http://orbisne.fortiddns.com:8123 | myron | (HA password) |
|
||||||
|
| NovaCPX Admin | https://10.48.200.110:8882 | admin | `Admin2026!` |
|
||||||
|
| Jellyfin | http://10.48.200.33:8096 | — | token: `7c0ccf78b91d4b5bafa607f585f24f2d` |
|
||||||
|
| qBittorrent | http://10.48.200.35:8080 | admin | `Joker1974!!!` |
|
||||||
|
| Sonarr | http://10.48.200.35:8989 | admin | `Joker1974!!!` |
|
||||||
|
| Radarr | http://10.48.200.35:7878 | admin | `Joker1974!!!` |
|
||||||
|
| Prowlarr | http://10.48.200.35:9696 | admin | `Joker1974!!!` |
|
||||||
|
| Synology NAS | http://10.48.200.249:5000 | nas | `Joker1974!!!` |
|
||||||
|
| Parker Slingshot Admin | https://parkerslingshotrentals.com/admin | admin | `Parker2026!` |
|
||||||
|
| TJJ Admin | https://tomsjavajive.com/admin | `admin@tomsjavajive.com` OR `myronblair@outlook.com` | `Joker1974!!!` |
|
||||||
|
|
||||||
|
### Databases
|
||||||
|
| Site | DB Name | DB User | DB Password |
|
||||||
|
|------|---------|---------|-------------|
|
||||||
|
| JARVIS | `jarvis_db` | `jarvis_user` | `J4rv1s_Pr0t0c0l_2026!` |
|
||||||
|
| Tom's Java Jive | `toms_tjj_db` | `toms_tjj_user` | `+60wlPc+55e@gFq4` |
|
||||||
|
| Parker Slingshot Rentals | `park_slingshot` | `park_slingshotuser` | `4@rxg*8kovxCr7w6` |
|
||||||
|
| Epic Travel | `epic_travel_db` | (see config.php) | (see config.php) |
|
||||||
|
| Epic/Parker Slingshot | `epic_parkersling` | `epic_parkersling` | `Joker1974!!!` |
|
||||||
|
| NovaCPX | SQLite: `/var/lib/novacpx/panel.db` | — | — |
|
||||||
|
| FusionPBX | PostgreSQL | `fusionpbx` | `pSJaF9mUJqPr4Sj5mwJyRqvCCpc` |
|
||||||
|
| MySQL root (DO) | — | root | `b71e5c1a8c7457541b9c1db822de37adfa271926a38b6c20` |
|
||||||
|
|
||||||
|
### API Keys
|
||||||
|
| Service | Key |
|
||||||
|
|---------|-----|
|
||||||
|
| GitHub PAT | `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` (exp ~2026-08-20) |
|
||||||
|
| JARVIS Agent Registration | `f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518` |
|
||||||
|
| Proxmox API Token | `root@pam!jarvis=c45b5feb-f9a9-445d-a626-14fbb959f78b` |
|
||||||
|
| HA Long-lived Token | `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzNmI0N2I1Njk5ZGQ0MTQ2ODMwZWFmYjZiYTQ1MjJkMSIsImlhdCI6MTc4MDIwMzU5NCwiZXhwIjoyMDk1NTYzNTk0fQ.sYRok-jRDlA4lFgWxLQELcEjkJNGQdprk6ZziLwLtXE` |
|
||||||
|
| Sonarr API | `b43e04350a594846b4ee95261c29e9e0` |
|
||||||
|
| Radarr API | `53c4268360444feeae5f98c0cc24e0e3` |
|
||||||
|
| Prowlarr API | `9d0ce6c5660743b5bf1c7951efc62252` |
|
||||||
|
| Jellyfin Admin Token | `7c0ccf78b91d4b5bafa607f585f24f2d` |
|
||||||
|
| Square (Parker) Production | `EAAAl3FsAu_2ri8kZE_ENEyi2T_C8HXXm5XQFY6Lbnd8SX6FqYp8J_upUeXNYh7v` |
|
||||||
|
| Square App ID (Parker) | `sq0idp-YSM7BU9IVyOWSzpeP-0nzQ` |
|
||||||
|
| Webhook HMAC Secret | `4c8805f0285214ff0a0602b5880270b935f36a896946c7f1` |
|
||||||
|
|
||||||
|
### SIP / Phone
|
||||||
|
| Extension | Name | SIP Password |
|
||||||
|
|-----------|------|-------------|
|
||||||
|
| 1000 | Myron Blair — Desk (10.48.200.2) | `Xk9mPw3nQv7rLs2t` |
|
||||||
|
| 1001 | Tommy Ivy — Desk (10.48.200.43) | `Tv8xNm4pWq6rZs3k` |
|
||||||
|
| 1002 | Myron Blair — WiFi Work (10.48.200.65) | `yXHaJTwa8rj?$GkrVFQB` |
|
||||||
|
| 1003 | Kitchen (10.48.200.83) | — |
|
||||||
|
| 1004 | Master Bedroom (10.48.200.85) | — |
|
||||||
|
| 1010 | Parker County Slingshot (voicemail only) | — |
|
||||||
|
| 1011 | Epic Travel Expeditions (voicemail only) | — |
|
||||||
|
| 1012 | Tom's Java Jive (voicemail only) | — |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This document contains sensitive credentials. Store securely and do not share.*
|
||||||
@@ -18,3 +18,31 @@ cp agent/config.json /opt/jarvis-agent/config.json
|
|||||||
systemctl enable jarvis-agent
|
systemctl enable jarvis-agent
|
||||||
systemctl start jarvis-agent
|
systemctl start jarvis-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Cloudflare Rocket Loader — IMPORTANT
|
||||||
|
|
||||||
|
JARVIS (and all sites) sit behind Cloudflare with **Rocket Loader enabled**.
|
||||||
|
Rocket Loader does two things that break JavaScript login forms:
|
||||||
|
|
||||||
|
1. Changes `<script>` tag `type` to a fake value, deferring execution.
|
||||||
|
2. Injects `if (!window.__cfRLUnblockHandlers) return false;` into **every**
|
||||||
|
`onclick=`, `onkeydown=`, and other inline HTML event attributes,
|
||||||
|
blocking them until Rocket Loader finishes loading.
|
||||||
|
|
||||||
|
### Rules for any page with JavaScript that must run immediately:
|
||||||
|
|
||||||
|
- Add `data-cfasync="false"` to ALL `<script>` tags.
|
||||||
|
- **Never use inline event handler attributes** (`onclick=`, `onkeydown=`, etc.)
|
||||||
|
on HTML elements — Rocket Loader will block them.
|
||||||
|
- Attach all event listeners via `addEventListener()` in JavaScript.
|
||||||
|
- Use `XMLHttpRequest` instead of `fetch()` for auth calls (more compatible).
|
||||||
|
- Put scripts **after** their target DOM elements (end of body), not in `<head>`,
|
||||||
|
so the elements exist when the script runs without needing DOMContentLoaded.
|
||||||
|
|
||||||
|
### Current login implementation (jarvis repo: public_html/login.html)
|
||||||
|
|
||||||
|
Standalone `/login.html` page handles all auth. `index.html` redirects to
|
||||||
|
`/login.html` if no `jarvis_token` in sessionStorage.
|
||||||
|
- Script is at end of body, after elements, with `data-cfasync="false"`
|
||||||
|
- All handlers attached via `addEventListener` — no inline attributes
|
||||||
|
- Uses XHR (not fetch) to POST to `/api/auth`
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# FusionPBX Custom Configs (134.209.72.226)
|
||||||
|
|
||||||
|
## Yealink T48S Provisioning — Critical Fixes
|
||||||
|
|
||||||
|
### Problem: BLF buttons never applied from provisioning
|
||||||
|
Root cause: nginx rewrite for `{mac}.boot` stripped the `file=` param, so FusionPBX
|
||||||
|
served the full 122KB config as a boot file. Yealink ignores DSS keys in .boot files —
|
||||||
|
they only apply from .cfg files.
|
||||||
|
|
||||||
|
### Fix 1: nginx rewrite (in /etc/nginx/sites-enabled/fusionpbx)
|
||||||
|
OLD: rewrite "^.*/provision/([A-Fa-f0-9]{12})(\.boot)$" /app/provision/index.php?mac=$1;
|
||||||
|
NEW: rewrite "^.*/provision/([A-Fa-f0-9]{12})(\.boot)$" /app/provision/index.php?mac=$1&file=%7b%24mac%7d.boot;
|
||||||
|
|
||||||
|
### Fix 2: {$mac}.boot template
|
||||||
|
Created: /var/www/fusionpbx/resources/templates/provision/yealink/t48s/{$mac}.boot
|
||||||
|
Content: boot file with includes pointing to y000000000065.cfg and {$mac}.cfg
|
||||||
|
Phone flow: {mac}.boot (164 bytes) → y000000000065.cfg → {mac}.cfg (full config applied)
|
||||||
|
|
||||||
|
### Fix 3: y000000000065.cfg template changes
|
||||||
|
- features.auto_linekeys.enable = 0 (prevents phone overriding BLF keys)
|
||||||
|
|
||||||
|
### Fix 4: All y000000000000.boot templates
|
||||||
|
- overwrite_mode = 1 (forces re-provision on every reboot, default was 0)
|
||||||
|
|
||||||
|
### Fix 5: External sofia profile
|
||||||
|
- manage-presence = passive (not true — BLF SUBSCRIBEs delegate to internal profile)
|
||||||
|
- Fix: UPDATE v_sip_profile_settings SET value='passive' WHERE profile=external AND name='manage-presence'
|
||||||
|
- Then delete /var/cache/fusionpbx/FusionPBX.configuration.sofia.conf and reload sofia
|
||||||
|
|
||||||
|
## Device Profile "yealink" (UUID 2c68fe07-b29a-4429-a3c2-7ce9010c69ff)
|
||||||
|
|
||||||
|
| Key | Type | Value | Label | Notes |
|
||||||
|
|-----|------|-------|-------|-------|
|
||||||
|
| 1 | 16 (BLF) | 1000 | Myron 1000 | |
|
||||||
|
| 2 | 16 (BLF) | 1001 | Tommy 1001 | |
|
||||||
|
| 3 | 16 (BLF) | 1002 | Myron Vanguard | |
|
||||||
|
| 4 | 12 | 1003 | PC Slingshot | |
|
||||||
|
| 5 | 12 | 1004 | Epic Travel | |
|
||||||
|
| 6 | 12 | 1005 | Toms Java | |
|
||||||
|
| 7 | 13 (Speed Dial) | *5901 | Park 5901 | Press during call=park, idle=retrieve |
|
||||||
|
| 8 | 13 (Speed Dial) | *5902 | Park 5902 | |
|
||||||
|
| 9 | 13 (Speed Dial) | *5903 | Park 5903 | |
|
||||||
|
| 11 | 16 (BLF) | *724 | Page All | |
|
||||||
|
|
||||||
|
Park buttons use Speed Dial (type=13) not BLF — BLF for park requires mod_presence
|
||||||
|
which is not installed. Speed Dial works: press during call parks it, press idle retrieves.
|
||||||
|
|
||||||
|
## BLF Type Reference (Yealink T48S firmware 66.86.x, FusionPBX)
|
||||||
|
- type=16 = BLF (requires pickup_value field in template)
|
||||||
|
- type=13 = Speed Dial
|
||||||
|
- type=12 = (user-defined)
|
||||||
|
- type=1 = Line
|
||||||
|
|
||||||
|
## Provisioning URL
|
||||||
|
- Server: https://fusion.orbishosting.com/app/provision/
|
||||||
|
- Auth: provision-master / Joker1974!!! (Digest)
|
||||||
|
- After factory reset: must re-enter manually via Menu > Settings > Advanced > Auto Provision
|
||||||
|
- Firmware 66.86.0.15: requires power cycle after "Update Now" to register
|
||||||
|
|
||||||
|
## fail2ban Whitelist (/etc/fail2ban/jail.local)
|
||||||
|
- 107.178.2.130 (office)
|
||||||
|
- 97.154.109.245 (home WAN)
|
||||||
|
|
||||||
|
## Phones
|
||||||
|
- Ext 1000 (Myron): MAC 805ec0350477, firmware 66.86.0.15, IP 10.48.200.2
|
||||||
|
- Ext 1001 (Tommy): MAC 805e0c150c4f, firmware 66.86.0.160, IP 10.48.200.43
|
||||||
|
|
||||||
|
## IVR Audio
|
||||||
|
- /var/lib/freeswitch/recordings/134.209.72.226/ivr_menu.wav
|
||||||
|
- American male voice (Festival TTS), 27s, 8kHz 16-bit mono PCM
|
||||||
|
|
||||||
|
## mod_presence
|
||||||
|
- NOT installed — FreeSWITCH built from source at /usr/src/freeswitch-1.11/
|
||||||
|
- Basic extension BLF works via manage-presence=true on internal sofia profile
|
||||||
|
- Park slot BLF would require mod_presence — workaround: Speed Dial buttons
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
ignoreip = 127.0.0.1/8 ::1 107.178.2.130 97.154.109.245
|
||||||
|
|
||||||
|
[ssh]
|
||||||
|
enabled = true
|
||||||
|
port = 22
|
||||||
|
protocol = ssh
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
action = iptables-allports[name=sshd, protocol=all]
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# In /etc/nginx/sites-enabled/fusionpbx
|
||||||
|
# Critical fix: pass file= param so FusionPBX returns a boot file (not full config)
|
||||||
|
# Phone ignores DSS/BLF keys when received in a .boot file — must come from .cfg
|
||||||
|
|
||||||
|
# CORRECT:
|
||||||
|
rewrite "^.*/provision/([A-Fa-f0-9]{12})(\.boot)$" /app/provision/index.php?mac=$1&file=%7b%24mac%7d.boot;
|
||||||
|
|
||||||
|
# WRONG (original — serves full 122KB config as .boot, phone ignores linekeys):
|
||||||
|
# rewrite "^.*/provision/([A-Fa-f0-9]{12})(\.boot)$" /app/provision/index.php?mac=$1;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!version:1.0.0.1
|
||||||
|
## The header above must appear as-is in the first line
|
||||||
|
|
||||||
|
include:config "y000000000065.cfg"
|
||||||
|
include:config "{$mac}.cfg"
|
||||||
|
|
||||||
|
overwrite_mode = 1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!version:1.0.0.1
|
||||||
|
## The header above must appear as-is in the first line
|
||||||
|
|
||||||
|
include:config "y000000000065.cfg"
|
||||||
|
include:config "{$mac}.cfg"
|
||||||
|
|
||||||
|
overwrite_mode = 1
|
||||||
Reference in New Issue
Block a user