Synology NAS — NGAGED_CLOUD
DS220+ · DSM 7.3.2-86009 · 2×4TB SHR RAID-1 · 3.5 TB btrfs · Docker 24.0.2
Audited 2026-08-21 · read-only · no modifications made
Executive Summary
00 — Executive Summary
NAS Modernization Project — Phase 1: Discovery / As-Built Inventory (Digital Twin)
- Audit date: 2026-08-21
- Auditor host: Golden-Eye (Ubuntu 26.04, orchestrator/compute) → reached NAS read-only over SSH (Tailscale
100.90.167.88, port 54321) - Audit mode: READ-ONLY. No files, containers, packages, users, tasks, settings, network config, or storage were modified. No secrets were read or recorded.
- Scope: Complete as-built inventory of the Synology NAS (
NGAGED_CLOUD) in its current state, per the Phase 1 directive.
1. What Exists
Hardware / System
- Model: Synology DS220+ (2-bay), platform
geminilake, x86_64 - CPU: Intel Celeron J4025 (2c/2t)
- RAM: 17 GB (12 GB swap: 2 GB
/dev/md1+ 2× zram) - DSM: 7.3.2-86009 (build 2026/06/18)
- Storage: 2× Synology HAT3300-4T (4 TB HDD) in SHR RAID-1 (
md3/md2), LVM → single 3.5 TB btrfs volume1 - External: 1× 2 TB USB drive (
usbshare1, ext4, 1.8 TB) - Disk health: Both drives report normal SMART, 0 bad sectors, temp ~35°C. No failing-disk risk currently.
Data (volume1, 3.5T — 2.5T used, 1.1T free — 70%)
vMix Recordings— 752 GB (church service recordings)homes— 823 GB (6 users; shaconann 321G, vidalstephen 202G, sadevidal 141G, rore-admin 114G)docker— 594 GB (primarily/volume1/docker/data/media= 534 GB of media: TV 282G, Anime-TV 155G, Movies 88G)projects— 11 GB,mediashare — 21 GB,Shared Documents— 3.8 GB,music— 422 MB- USB drive: 760 GB used (Hyber Backup homes target + DSM_HOMES_BACKUP)
Containers (Docker 24.0.2 / Container Manager)
- 23 running, ~28 stopped/exited. Total 255 images (162 dangling), 23 volumes.
- Biggest running groups:
- media-platform (~21 containers): Jellyfin, Plex, Sonarr/Radarr/Prowlarr/Bazarr (+anime variants), Overseerr, Tautulli, Deemix, TubeArchivist (kids), qmutorrent/gluetun, rdt-client, FlareSolverr, Recyclarr, CleanUpArr
- platform: Traefik v3 (reverse proxy), cloudflared (tunnel
6f717a56, serves *.nsystems.live + *.vectorhost.net), cf-ddns - monitoring: Gatus + Gotify
- homelab: vaultwarden (password manager), rustdesk (hbbs+hbbr), devshell
- hosted: scrapline2, crimson-haven, skybreaker-transform, ghostline-command
Packages (installed, Synology + community)
- Data-facing: Hyper Backup, Synology Drive, Synology Photos, Snapshot (share snapshots on all shares), Storage Analyzer, MailPlus-Server (+ MailClient, Contacts, Calendar), Chat, Audio Station, Codec Pack
- Container Manager 24.0.2, Git, Node.js 18/20, PHP 8.2, Python 2/3.9/3.10, Tailscale, Secure SignIn, QuickConnect, Active/ActiveInsight
2. Where the Important Data Lives
| Share | Size | Nature | Protection |
|---|---|---|---|
vMix Recordings | 752 GB | Church services video (LOSS-HIGH) | Single copy; NOT in Hyper Backup job; small/empty btrfs snapshot |
homes (esp. shachonn/vidal) | 836 GB | Personal/family photos & files | In Hyper Backup "Local Copy 1" → USB only (see §6) |
docker/data/media | 534 GB | Media library (Plex/Jellyfin/arr) | NO backup — voluminous, low-value, re-downloadable |
projects, Shared Documents, music | ~15 GB | Business/work docs | In USB backup? (partial) |
USB usbshare | 760 GB | Backup target + DSM_HOMES_BACKUP | Itself un-backed-up |
3. What Depends on What
- All public web services depend on: cloudflared (tunnel) → Traefik (routing/TLS) → container. Authelia (auth) is exited/down, so exposed services may lack SSO enforcement (verify).
- All media containers bind-mount
/volume/data/media(the media library). Jellyfin & Plex bind/volume/docker/data/media-library. - devshell container bind-mounts
/var/run/docker.sock,/volume1, and.ssh— a powerful container. - homes are served via Synology Drive/FileStation and are the subject of the only configured Hyper Backup job.
4. What Is Currently Protected
- One Hyper Backup job ("Local;1") → USB drive (
usbshare1, targetNGAGED_CLOUD_1), daily 03:00, enabled. Butstate=disabledin the schedule task, and the job's folder list is homes only. Last backup ~2025-11 (from target dir listing). - btrfs snapshots available (share snapshot service on all shares) — only
vMix Recordingshas an actual snapshot (empty/1 file). - Syncthing/ActiveInsight/SynologyDrive present.
5. What Is NOT Adequately Protected (top risks)
- CRITICAL — No verified restore. No Hyper Backup restore has been tested; job last ran ~Nov 2025. Cannot prove recoverability.
- CRITICAL —
vMix Recordings(752 GB) has NO backup. Not in the Hyper Backup folder list; snapshots essentially empty. Single copy on a 2-bay RAID1 (protects against disk failure, not against deletion/corruption/fire). - HIGH — Docker/container config is not centrally backed up.
/volume1/docker(compose files + stack configs) are inside the docker share (594 GB, mostly data). Many containers have no reproduceable-config backup outside the host. 255 images and 23 anonymous volumes suggest a lot of un-tracked state. - HIGH — No offsite/off-NAS backup. USB target sits on the same NAS. No cloud/offsite copy.
- MEDIUM/HIGH — Authelia (access control) is DOWN while services are internet-exposed via tunnel.
- MEDIUM — 4 service accounts + broad permissions (see §3): devshell has docker.sock + full /volume1 + ssh access.
6. What Appears Safe
- Disk health good (both drives normal, 0 bad sectors).
- NAS RAID1 mirror functional.
- DSM up-to-date on recent minor.
- Structured compose directories (
/volume1/docker/platform,/stacks,/data).
7. What Concerns Me
- The only existing backup is a stale (~9-month-old) local USB backup of homes only. Not restore-tested, not offsite, excludes the two largest/high-value directories (media, vMix).
- 42 containers exited, many months old — configuration fragility if lost.
- 155 dangling images / anonymous volumes — storage + restore clutter.
- Exposed public ports on
0.0.0.0: Plex(32400), RustDesk(21115-21119), Jellyfin(8096), phpmyadmin(8086), freightline-dev(3001). - Authelia (SSO) is down at a time when 28+ subdomains route through the tunnel.
- vMix Recordings is the single largest, un-backed-up, irreplaceable dataset.
- SMB shares are guest-writable (including
homesanddocker) — mitigated only by the firewall confining SMB to Tailscale/LAN. - SSH password authentication is enabled — brute-force surface on the known port.
8. What Remains UNKNOWN / REQUIRES MANUAL REVIEW
- Hyper Backup restore state — never verified.
- Exact Hyper Backup retention policy (version counts) — GUI-only detail.
- Router port-forwarding state — the DSM firewall allows DSM web/Drive/SSH from any source, but whether the router actually forwards those ports (5000/5001/54321) to the NAS is external to the NAS.
- Syncthing/ActiveInsight/ActiveInsight exact job configs (GUI-only).
- Who "ryan" is (empty home; deny-ACL on docker, allow on vMix).
- Whether Authelia was deliberately decommissioned or just crashed.
> Resolved during the admin-access pass (no longer unknown): firewall rules (DSM INPUT_FIREWALL), SSHD hardening (password auth enabled), per-share ACLs (enumerated), SMB guest access (all shares guest-open but Tailscale-only at firewall), DSM config backup (exists at /volume1/@config_backup, 61 KB, dated 2026-08-16), storage pool layout (SHR RAID-1, LVM 3.63 T).
9. What I Recommend Next
- Proceed to PHASE 2 — BACKUP, INTEGRITY VERIFICATION & RESTORE TESTING (see below), with priorities:
- P0: Design + implement a verified, off-NAS backup for
vMix Recordings(and homes) — using golden-eye/srv1388017/edge as target, not the same-NAS USB. - P0: Restore-test the existing USB homes backup (pick one user's dir) to prove recoverability — do NOT trust it.
- P1: Back up all compose configs + env-file NAMES (
/volume1/docker/platform,/stacks,/nsystems-monitoring, plus anystack-config/under the media stack) to a safe, reproducibly-restorable location; enable restore-test. - P1: Record container config to a reproducibility manifest (inventory already produced; next is a
docker inspectdump). - P2: Offsite (edge) copy of critical small datasets.
- During Phase 2 you may want to enable SSH
sudoor share the DSM admin password with the agent for firewall/SSHD/task-reads — OR provide those directly to complete the UNKNOWN section.
Final Gate
This document and its 12 companions constitute the Phase-1 as-built inventory / digital twin. Discovery is complete and I am STOPPING here as directed.
I request authorization to proceed to PHASE 2 — BACKUP, INTEGRITY VERIFICATION & RESTORE TESTING, with the priorities above. No destructive operation has been performed or is authorized by this directive.
System Inventory
01 — System Inventory
NAS: NGAGED_CLOUD · Model: Synology DS220+ (2-bay) · Platform: geminilake · Arch: x86_64
| Attribute | Value |
|---|---|
| Hostname | NGAGED_CLOUD |
| DSM version | 7.3.2-86009 (build 2026/06/18, GM, smallfix 4) |
| Kernel | 4.4.302+ synology_geminilake_220+ |
| CPU | Intel Celeron J4025 @ 2.00 GHz (2 cores / 2 threads) |
| RAM | 17 GiB total (6.8 used / 9.7 avail) |
| Swap | 12 GiB total (2 GB /dev/md1 + 2× zram 5.5 GB), ~1.4 GiB used |
| Uptime | 41 days, 11h (at audit); load ~2.9 (IO-heavy) |
| Timezone (log evidence) | UTC-5 (US Central) |
| Enclosure health | Good — both drives SMART normal, 0 bad sectors |
Network Interfaces
| Interface | State | Address |
|---|---|---|
eth0 | UP | 192.168.0.164/24 (LAN, primary) |
eth1 | DOWN | 169.254.67.66/16 (unused) |
tailscale0 | UP | 100.90.167.88/32 (Tailscale) |
docker0 + 11 docker bridges | mix | 172.x/192.168.x docker subnets |
- Gateway: 192.168.0.1
- DNS: 8.8.8.8 / 8.8.4.4
- Public/DDNS:
ngaged.synology.me(Synology DDNS enabled) - Tailscale: v1.58.2 package, node
ngaged-cloud, IP100.90.167.88
Storage Pools / RAID / Volumes
The NAS uses SHR (Synology Hybrid RAID) over a 2-disk RAID-1 arrangement with LVM on top.
| Device | Role | Filesystem | Size | Used / Free |
|---|---|---|---|---|
/dev/md0 | System (/) | ext4 | 7.9 GB | 3.9 / 3.9 G (50%) |
/dev/md1 | Swap | — | 2 GB | — |
/dev/md2 | SHR data part 1 (member) | btrfs (LVM PV) | 1.93 TB | — |
/dev/md3 | SHR data part 2 (member) | btrfs (LVM PV) | 1.95 TB | — |
/dev/vg1/volume_1 → /volume1 | Main volume | btrfs | 3.5 TB | 2.5 used / 1.1 free (70%) |
/dev/usb1p1 | USB drive → /volumeUSB1/usbshare | ext4 | 1.8 TB | 760 G used / 1.1 free (42%) |
- md arrays (all RAID-1,
[2/2] [UU]healthy): md0, md1, md2, md3. - LVM (confirmed via
lvs/vgs/pvs):vg1= 3.63 T across PVs/dev/md2(1.81 T) +/dev/md3(1.82 T); LVvolume_1= 3.63 T (thin volumesyno_vg_reserved_area12 M also present). SHR RAID-1 confirmed. - Filesystem: btrfs with
synoacl,space_cache=v2, subvol per shared folder under/volume1/@syno. - Encryption: Volume/share encryption supported by DSM but volume is NOT encrypted (LVM thin volume not listed as encrypted; no encrypted-mount in
/proc/mounts).support_share_encryption=yes,support_volume_encryption=yes,lock_encrypted_storage=no. - SSD cache: None. No SSD cache md devices;
support_m2_pool=no.
Physical Disks
| Disk | Path | Model | Firmware | Size | Serial | Type | Temp | SMART |
|---|---|---|---|---|---|---|---|---|
| Bay 2 | /dev/sata1 | Synology HAT3300-4T | PL01 | 4.0 TB | ZW62LVN1 | HDD | 35°C | normal |
| Bay 1 | /dev/sata2 | Synology HAT3300-4T | PL01 | 4.0 TB | ZW61Z06C | HDD | — | normal |
| USB | /dev/usb1 | (USB drive) | — | 2.0 TB | — | HDD | — | n/a |
SMART / health detail (from /var/log/diskprediction/data-2026-08-21.json):
overview_status=normal,smart=normal,smart_test=normal,bad_sec_ct=0,below_remain_life_thr=0.- No failing-disk indicators. Safe to run a large backup at present (both drives healthy).
Encryption Configuration
- Volume + share encryption supported but the primary volume is not encrypted (drive data at rest unencrypted).
/usr/syno/etc/keymanagerpresent (key management service) — no encrypted volume mounted.
Storage Utilization Flags
- Main volume at 70% (1.1 TB free). Large backup of
docker/data/media(534 GB) onto same volume would not fit (534 GB > 1.1 TB free — but would still fit off-NAS). - Health is good; no immediate backup-blocking hardware risk.
Discovery Commands (sanitized)
ssh -p 54321 msn0624c@100.90.167.88 cat /etc.defaults/VERSION cat /proc/cpuinfo | grep -E "model name|cpu cores" free -h; cat /proc/swaps cat /proc/mdstat lsblk; df -hT cat /var/log/diskprediction/data-<date>.json | python3 -m json.tool # disk health
Storage & Shares
02 — Storage & Shared Folders
Primary volume /volume1 (btrfs, 3.5 T, 70% used). Each DSM shared folder is a btrfs subvolume under /volume1/@syno. A USB drive mounts at /volumeUSB1/usbshare (ext4).
Shared Folder Table
| Share | Size | Path | Purpose (inferred) | Snapshot | Recycle bin | Key users | Classification |
|---|---|---|---|---|---|---|---|
vMix Recordings | 752 GB | /volume1/vMix Recordings | Church services video (largest, irreplaceable) | btrfs snapshot present (essentially empty) | yes (#recycle 6.3G) | — | KEEP (critical, needs backup) |
homes | 823 GB | /volume1/homes | Per-user home dirs (photos/files) | available | yes (#recycle 7.2G) | all users | KEEP |
docker | 594 GB | /volume1/docker | Docker compose configs + data/media (534 GB) | — | yes | msn0624c | REVIEW (config KEEP, media is data) |
media | 21 GB | /volume1/media | Legacy media staging (seedbox-data 15G, temp) | — | yes | — | MIGRATE/REVIEW (largely redundant with docker/data/media) |
projects | 11 GB | /volume1/projects | Project files (vps 6G, ZeroArcade) | — | yes (5G) | — | MIGRATE/REVIEW |
Shared Documents | 3.8 GB | /volume1/Shared Documents | Office/docs (Synology Office) | — | — | — | KEEP |
music | 422 MB | /volume1/music | Audio library | — | — | — | REVIEW (vs docker/data/media/Music) |
chat | 324 KB | /volume1/chat | Synology Chat data | — | — | — | REVIEW |
MailPlus | 1.7 MB | /volume1/MailPlus | MailPlus server mail data | — | — | — | REVIEW |
web | 4.0 K | /volume1/web | Web root (DSM web station) | — | — | — | REVIEW |
web_packages | 0 | /volume1/web_packages | Package web files | — | — | — | REVIEW |
gitea-share | 0 | /volume1/gitea-share | Gitea container share (empty) | — | — | — | REVIEW |
backups | 1 MB | /volume1/backups | Docker inventory + romm backups | — | — | msn0624c | KEEP (small, admins) |
USB drive /volumeUSB1/usbshare (1.8 TB, 760 G used, ext4)
NGAGED_CLOUD_1/— Hyper Backup "Local;1" target (homes backup)DSM_HOMES_BACKUP/— separate manual homes archive (Nov 2025)- Un-backed-up itself.
Major Storage Consumers
/volume1/docker/data/media — 534 GB
TV— 282 GBAnime-TV— 155 GBMovies— 88 GBInstrumentals— 4.5 GB,Music— 2.5 GB- (Empty: Stems, MusicVideos, Anime-Movies)
/volume1/docker/data/media-library — 22 GB
YouTube-Kids— 22 GB (TubeArchivist)
/volume1/docker/data/torrents — 9.3 GB (active download area)
/volume1/homes — 823 GB (per user)
| User | Size | Top folders |
|---|---|---|
shaconann | 321 GB | Photos 106G, "all images" 60G, USA TRIP 23G, sd-card 20G, Family videos 8G |
vidalstephen | 202 GB | Photos 98G, Assets 44G, My Shared Folders 19G, Business Projects 12G |
sadevidal | 141 GB | (n/i) |
rore-admin | 114 GB | (n/i) |
rore-worship | 14 GB | |
mskeete | 14 GB | |
msn0624c | 12 GB |
/volume1/vMix Recordings — 752 GB
archive136 GB, many 4–57 GB.mp4/.avisingle-service files;#recycle6.3 GB.
Notes
- Recycle bin is enabled on
homes,docker,media,projects,vMix Recordings— deleted files remain reclaimable; good for safety, but inflates size (e.g.#recyclein homes 7.2G). mediashare is largely redundant withdocker/data/media— candidates for consolidation during Phase 2+.- Container data (
docker/data/media) has NO backup — re-downloadable from *arr indexers (lowest priority to back up). - vMix + homes are the irreplaceable, high-value data.
Snapshot Configuration
- Share-snapshot service enabled on all shares (
/usr/syno/etc/sharesnap/sharesnap.conflists every share). - Actual snapshot: only
/volume1/@sharesnap/vMix Recordings/exists and it contains just adesktop.ini(effectively empty). No usable snapshots protect any share today.
Discovery Commands
sudo du -sh /volume1/<share> du -sh /volume1/vMix\ Recordings/* | sort -rh | head du -sh /volume1/homes/*/ | sort -rh | head du -sh /volume1/docker/data/media/* | sort -rh | head cat /usr/syno/etc/sharesnap/sharesnap.conf
Users, Groups & Permissions
03 — Users, Groups & Permissions
> NOTE: Full fine-grained ACLs and share-permission matrices require synoacltool/DSM admin (sudo). Values below are from /etc/passwd, /etc/group, and filesystem ownership (read-only). Fine-grained ACLs not dumped — UNKNOWN / REQUIRES MANUAL REVIEW for exact per-user ACLs.
Local Users (/etc/passwd, non-system)
| User | UID | Home | Notes |
|---|---|---|---|
admin | 1024 | /var/services/homes/admin | DSM default admin account (system) |
msn0624c | 1026 | /var/services/homes/msn0624c | NAS SSH/operator account (used by agent) |
postgres | 55 | /var/services/pgsql | service account (PostgreSQL) |
root | 0 | /root | OS root (ash) |
> Other DSM users exist as home dirs: shaconann, vidalstephen, sadevidal, rore-admin, rore-worship, mskeete, ryan — visible via /volume1/homes/* even though not all are in passwd excerpt. ryan has an empty home (possible orphan).
Groups (abridged, non-system)
| Group | Members / purpose |
|---|---|
administrators | admin, msn0624c — full DSM admin |
users | default user group (members via homes) |
docker (65538) | msn0624c — docker group access |
ngaged-cloud (65537) | sadevidal, shaconann, vidalstephen, rore-admin, mskeete — shared family group |
roreccelsia (65536) | rore-admin |
| Many package service groups | (ContainerManager, HyperBackup, MailPlus-Server, SynologyPhotos, SynologyDrive, FileStation, etc.) |
Permission Observations / Findings
- Two full administrators (
admin+msn0624c).msn0624cis the automation/SSH account with admin + docker group. msn0624cis a very broad account: inadministrators, indocker, and it owns/volume1/backups,/volume1/docker. This is the agent's operational account — broad but intentional.devshellcontainer is exceptionally privileged: bind-mounts/var/run/docker.sock, the entire/volume1, and~/.ssh. Anyone with that container's console = full NAS control.nfs/nobodysharing groups exist but NFS exports file was empty (NFS not obviously exporting).- Service accounts for packages (postgres, mysql, mailplus, chat, etc.) — expected.
ryanhome exists but empty — possible orphaned/incomplete user.- Fine-grained share ACLs are the DSM default
rwxrwxrwx+on most shares (the+indicates extended ACL). Exact per-user access NOT enumerated (needs sudosynoacltool).
Excessive / Unnecessary Privilege Flags (for Phase 2+ review — no changes made)
devshellcontainer: docker.sock + /volume1 + .ssh = effectively root-equivalent. Restrict or gate.msn0624cas full admin + docker — acceptable for the migration operator but should be least-privileged once migration is done.- Confirm
adminaccount is needed vs. a dedicated admin (defense-in-depth).
SMB / NFS (now read with admin access)
- SMB service installed (
SMBService). Nearly all shares are configuredguest ok=yes,valid users=nobody,nobody,writeable=yes— i.e. guest-accessible SMB onchat,docker,gitea-share,homes,MailPlus,media,music,projects,usbshare1,web,web_packages. This is a significant finding: SMB shares (includinghomesanddocker) accept guest/write. However, the DSM firewall only allows SMB (445/139/137/138) from the Tailscale subnet (100.0.0.0/8), so LAN/Tailscale-only exposure is the mitigating factor. - NFS:
/etc/exportsempty → NFS not exported.
Fine-Grained ACLs (now enumerated with admin access)
| Share | Owner | ACL highlights |
|---|---|---|
homes | root | group:administrators rwx, group:users rwx, user:ContainerManager rwx, everyone r-x |
docker | msn0624c | user:msn0624c rwx, user:ryan deny, group:users rwx, user:ContainerManager rwx, everyone r-x |
vMix Recordings | root | user:mskeete deny, group:administrators rwx, user:ryan rwx, user:vidalstephen rwx, user:rore-admin rwx |
projects | root | group:administrators rwx only |
user:ryanappears with a deny ondockerand allow onvMix Recordings— inconsistent; review whether theryanaccount is still needed.
Discovery Commands
grep -vE "nologin|/bin/false|daemon|/sbin/" /etc/passwd cat /etc/group ls -la /volume1/homes/ # Fine ACLs (need sudo): sudo /usr/syno/sbin/synoacltool --enumerate <share> # REQUIRES MANUAL (sudo)
Containers & Services
04 — Containers & Services (Docker / Container Manager)
Engine: Docker 24.0.2 (Container Manager 24.0.2-1606) · Compose v2.20.1 · storage driver btrfs · cgroup v1 · logging db
Totals: 23 running, ~28 exited/stopped · 255 images (162 dangling <none>) · 23 volumes · 16 networks
Running Containers
Platform Layer
| Container | Image | Status | Ports | Compose source | Purpose |
|---|---|---|---|---|---|
traefik | traefik:v3 | Up 5w | expose 8080 | /platform/traefik/ | Reverse proxy + TLS (CF DNS-01) |
cloudflared | cloudflare/cloudflared:latest | Up 5w (healthy) | — | /platform/cloudflared/ | Tunnel 6f717a56 → serves *.nsystems.live + *.vectorhost.net |
cf-ddns-nsystems | favonia/cloudflare-ddns:latest | Up 5w | — | /platform/ddns/ | Cloudflare DDNS updater |
Media Platform (/volume1/docker/stacks/media/media-platform/)
| Service | Image | Notes |
|---|---|---|
jellyfin | lscr.io/linuxserver/jellyfin | 0.0.0.0:8096 exposed |
plex | lscr.io/linuxserver/plex | 0.0.0.0:32400 exposed + DLNA/UPnP |
sonarr, sonarr-anime | linuxserver/sonarr | anime variant |
radarr, radarr-anime | linuxserver/radarr | anime variant |
prowlarr | linuxserver/prowlarr | indexer manager |
bazarr, bazarr-anime | linuxserver/bazarr | subtitles |
overseerr | linuxserver/overseerr | requests/Discovered |
tautulli | linuxserver/tautulli | Plex stats |
deemix | bockiii/deemix | music download |
recyclarr | ghcr.io/recyclarr/recyclarr | Arr config sync |
cleanuparr | ghcr.io/cleanuparr/cleanuparr | Arr cleanup |
rdt-client | rogerfar/rdtclient | 192.168.0.164:6500 (debrid client) |
flaresolverr | flaresolverr/flaresolverr | proxy solver |
tubearchivist-kids + tak-redis + tak-elasticsearch | (separate docker-compose-tak.yml) | YouTube archiving (media-library/YouTube-Kids) |
Torrent/VPN sub-stack (docker-compose.torrent.yml)
| Service | Image | Notes |
|---|---|---|
gluetun | qmcgaw/gluetun | WireGuard VPN sidecar |
qbittorrent | linuxserver/qbittorrent | via gluetun |
rutorrent | crazy-max/rtorrent-rutorrent | legacy torrent UI (has anonymous volumes) |
Platform/Homelab
| Service | Image | Port | Notes |
|---|---|---|---|
nsystems-gatus | twinproduction/gatus | 100.90.167.88:8081 | uptime monitoring |
nsystems-gotify | gotify/server | 100.90.167.88:8082 | notifications |
vaultwarden | vaultwarden/server | (80 int) | password manager (config in /volume1/docker/stacks/homelab/vault/config) |
hbbs, hbbr | rustdesk/rustdesk-server | 0.0.0.0:21115-21119 | RustDesk relay |
devshell | ghcr.io/vidalstephen/devshell | 127.0.0.1:2222→22 | remote dev shell (docker.sock + /volume1 + .ssh) |
Hosted apps (static nginx / game services)
| Service | Image | Port | Notes |
|---|---|---|---|
scrapline2 | scrapline2:production | 8080/tcp | game |
crimson-haven | nginx:alpine | 80/tcp | static |
skybreaker-transform | nginx:alpine | 80/tcp | static |
ghostline-command | nginx:alpine | 80/tcp | static |
Exited / Stopped Containers (~28) — notable
scrapline (old), aethrix-wordpress + -phpmyadmin (0.0.0.0:8086), wordpress + wordpress-db (mariadb:11), druglord-dev, freightline, freightline-dev (0.0.0.0:3001), starforge, agent-zero, reactive-resume(+db+printer), calcom(+db+redis), uptime-kuma, dsm-router, dozzle, dungeon-generator, template-myapp-1, buildx_buildkit_synobuilder0, plus Invidious tasks (disabled).
> These exited containers represent significant un-backupped configuration fragility and storage clutter (images/volumes).
Volumes (23)
- Named:
devshell-vscode-server,scrapline2_scrapline2-data,starforge_starforge-data,uptime-kuma_uptime-kuma-data,nsystems-gatus-data,nsystems-gotify-data,druglord_druglord_node_modules,freightline_freightline_node_modules,scrapline-shell_*,aethrix_wordpress_*,skybreaker-drone-strike-node-modules,sessioncraft_*,buildx_buildkit_*. - 11 anonymous hash volumes (hex IDs) — likely from
docker composeon manually-run containers (rutorrent, flaresolverr, calcom, etc.). Unknown owner/content — flag.
Networks
proxy (shared Traefik ingress net), bridge, host, plus per-project: media-platform_ta-internal, media-platform_tak-internal, calcom_*, reactive-resume_*, rustdesk_default, ddns_default, docker_default, freightline_default, sessioncraft_*, wordpress_*, socket-proxy, nsystems-monitoring_default.
Published / Exposed Ports (risk-relevant)
- 0.0.0.0 (all interfaces): Plex
32400, RustDesk21115-21119, Jellyfin8096, phpmyadmin8086, freightline-dev3001 - LAN IP: rdt-client
192.168.0.164:6500 - Tailscale-only: gatus
100.90.167.88:8081, gotify100.90.167.88:8082, devshell127.0.0.1:2222 - Traefik/cloudflared expose the tunnel layer (28+ subdomains) — internal service ports mostly not directly public (good), but phpmyadmin/Jellyfin/Plex/RustDesk ARE directly exposed.
Bind-Mounts (data locality)
- Media stack reads
/volume1/docker/data(media, torrents, media-library). devshell:/var/run/docker.sock,/volume1(whole volume),.ssh.vaultwarden:/volume1/docker/stacks/homelab/vault/config(password vault — backup priority).scrapline2: named volumescrapline2_scrapline2-data.- Traefik: docker.sock (ro) + acme.json + config.
- cloudflared: tunnel cred JSON (
6f718a56-….json) + config.
Dependencies
- All web apps depend on
cloudflared→traefik→ app;authelia(auth) is exited/down. - Media stack depends on
/volume1/docker/data/mediaand (for torrent)gluetunVPN. - RustDesk needs both
hbbs+hbbrrunning for relay (both up). - DDNS (
cf-ddns) depends on a valid CF token + IP detection.
Provisional Classification
| Workload | Classification |
|---|---|
| Traefik, cloudflared, ddns | KEEP on NAS (network/edge layer; could move to VPS) |
| Authelia | REVIEW (down; decide fix vs replace/remove) |
| Media stack (Jellyfin, Plex, *arr, Overseerr, Tautulli, Deemix, TubeArchivist) | KEEP ON NAS (data-local to media share) — but streamers can later move to compute if desired |
| qBittorrent/gluetun/rutorrent/rdt-client | REVIEW (data flows; keep on NAS near media) |
| Gatus, Gotify | MOVE TO COMPUTE (monitoring belongs on golden-eye) |
| vaultwarden | KEEP ON NAS or MOVE TO COMPUTE/VPS (decide in Phase 2; data must be backed up) |
| RustDesk (hbbs/hbbr) | MOVE TO VPS/EDGE (public-facing, wants a stable always-up host) |
| devshell | REPLACE (dev shell should live on compute; restrict) |
| scrapline2, crimson-haven, skybreaker-transform, ghostline-command | MOVE TO COMPUTE/VPS (static/hosted apps need not be on NAS) |
| Exited containers (wordpress, aethrix, reactive-resume, calcom, uptime-kuma, dozzle, etc.) | RETIRE/REVIEW (old; decide per project) |
Upk Keep everything mounted to /volume1/docker/data/media | KEEP (data-centric) |
> These are provisional recommendations only — no migration performed in Phase 1.
Discovery Commands
/usr/local/bin/docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
/usr/local/bin/docker inspect --format '{{ index .Config.Labels "com.docker.compose.project" }}' <name>
/usr/local/bin/docker inspect --format '{{range .Mounts}}{{.Type}}:{{.Source}}:{{.Destination}} {{end}}' <name>
/usr/local/bin/docker network ls; docker volume ls; docker imagesPackages
05 — Synology Packages
Installed packages enumerated from /var/packages/. Grouped by role.
Data / Backup / Sync
| Package | Version | Role | Active? | Data location | Essential? |
|---|---|---|---|---|---|
| Hyper Backup | 4.2.1-4228 | Backup engine | Yes (1 job → USB) | /var/packages/HyperBackup/ | ESSENTIAL (only backup path) |
| Synology Drive | 4.0.3-27892 | File sync/Drive | Yes | /volume1/@syno Drive subvols | Important |
| Synology Photos | 1.9.0-10924 | Photo management | Yes | homes/Photos | Important (consumer) |
| Snapshot (share snap) | — | btrfs snapshots | enabled all shares | /volume1/@sharesnap | Important (no real snapshots today) |
| Storage Analyzer | 2.1.1-0641 | Usage analysis | Yes | — | No |
| ActiveInsight | 3.0.5-24122 | Cloud monitoring/support | Yes | — | No |
| SynoAnalytics | 1.0.4-20014 | Analytics | — | — | No |
| HybridShare | 1.5.2-1832 | C2 cloud file mgmt | — | — | No |
| USBCopy | 2.2.1-1306 | USB auto-copy | — | — | No (but used for backup target?) |
| Tailscale | 1.58.2-700058002 | VPN mesh | Yes (agent access) | — | Essential for remote mgmt |
Communications / Collaboration
| Package | Role | Essential? |
|---|---|---|
| MailPlus-Server 4.0.0-31657 | mail server | Yes if email in use (has data) |
| MailClient 4.0.0-22251 | webmail | No |
| Contacts 1.0.10 | address book | No |
| Calendar 3.0.2 | CalDAV | No |
| Chat 2.4.6 | chat server | No (has data) |
| Synology Office (Spreadsheet) | docs | No |
| UniversalViewer 1.4.0 | preview | No |
Media
| Package | Purpose | Essential? |
|---|---|---|
| Audio Station 7.2.0 | audio | No (docker deems used) |
| CodecPack/AME 4.0.0 | codecs | Yes for native video |
| Synology Photos | (above) | — |
Runtime / App frameworks
| Package | Version | Essential? |
|---|---|---|
| Container Manager | 24.0.2-1606 | Yes (all Docker) |
| Node.js_v18 / v20 | 18.18.2 / 20.19.5 | No (dev) |
| PHP 8.2 | 8.2.28 | No (web station) |
| Python2 / 3.9 / 3.10 | 2.7.18 / 3.9.22 / 3.10.20 | No |
| Git / git | 2.39 / 2.53 | No (dev) |
| Perl 5.34 | — | No |
Security / Auth / Access
| Package | Purpose | Essential? |
|---|---|---|
| SecureSignIn 1.1.6 | passwordless/2FA | Yes (if used) |
| OAuthService 1.2.0 | OAuth2 | framework |
| QuickConnect 1.0.10 | internet connect | Exists; DDNS enabled |
| ActiveInsight | (above) | — |
Core DSM services (always present)
FileStation, StorageManager, SMBService, ScsiTarget (iSCSI/SAN), LogCenter, SynoFinder, SynologyApplicationService, SynoOnlinePack_v2, SupportService, AIConsole, StorageAnalyzer, TextEditor.
Package attention (per directive)
- Hyper Backup — present, 1 job (see 06). Critical to NAS operation.
- Snapshot Replication — snapshot capability present (share snap), but no meaningful snapshots exist.
- Synology Drive — active, homes-centric.
- Container Manager / Docker — core (see §04).
- Synology Photos — active, home photos.
- Active Backup — NOT installed (no "ActiveBackup" package seen). No client backup to NAS.
- VPN packages — none (only Tailscale).
- Media services — Audio Station, CodecPack, Photos; plus Docker media stack (Plex/Jellyfin/*arr).
- File-sharing — SMB, QuickConnect, Synology Drive, FileStation.
Classification summary (for later)
- Keep/Essential: Container Manager, Hyper Backup, Synology Drive, Photos, Storage Manager, FileStation, Tailscale, SecureSignIn, SMB.
- Review: Chat, MailPlus, Calendar, Contacts, HybridShare, USBCopy, Analjyics, AIConsole, ActiveInsight — enable/retire decision.
- Retire candidates (bloat): Python2, Perl (legacy), redundant runtimes.
Discovery Commands
ls /var/packages/ for p in $(ls /var/packages/); do cat /var/packages/$p/INFO 2>/dev/null | grep -E "^version=|^package=|^description=" ; done
Backup & Recovery
06 — Backup & Recovery Audit
> Critical finding: The only configured backup is stale (~9 months old), targets the same-NAS USB drive, covers homes only, and has never been restore-tested. BACKUP EXISTS ≠ RESTORE VERIFIED.
Backup Mechanisms
1. Hyper Backup — "Local;1" → USB
| Attribute | Value |
|---|---|
| Job name | Local Copy 1 (task id 10) |
| Engine | Hyper Backup 4.2.1-4228 |
| Source folders | /homes/mskeete, /homes/msn0624c, /homes/rore-admin, /homes/rore-worship, /homes/sadevidal, /homes/vidalstephen (homes only) |
| Destination | Local USB usbshare1 → target dir NGAGED_CLOUD_1 |
| Transport | trans_type=local (same-NAS USB) |
| Schedule | task id 10: daily 03:00 (from crontab), but task state=disabled |
| Retention | enable_delete=true (version deletion on) — retention policy not fully captured |
| Encryption | not indicated |
| Last successful run | ~2025-11-02/04 (target dir mtime + DSM_HOMES_BACKUP 2025-11). Stale ~9 months. |
| RESTORE VERIFIED | NO — no evidence of a restore test |
Evidence of staleness: USB NGAGED_CLOUD_1 last modified Nov 2025; synobkpinfo.db dated Nov 4 2025; DSM_HOMES_BACKUP Nov 2025. No recent Hyper Backup activity log.
2. Manual homes copy — DSM_HOMES_BACKUP (USB)
- Separate homes archive on USB (
admin,mskeete,msn0624c,rore-admin,rore-worship,sadevidal,shaconann,vidalstephen). - Dated 2025-11. Not automated, not verified.
3. Docker config backups (ad-hoc)
/volume1/docker/backups/— manual snapshots:media-platform-20251112,traefik-20260420,wordpress/,stacks-inactive-20260501,20250929./volume1/docker/_archive/traefik-old-platform/— old Traefik config./volume1/docker/_backups/pre-kvm1-alignment-20260420/.- These are manual, not scheduled, not verified.
4. Container/app-level backups
backups/romm(small),backups/docker-inventory.- No automated container config backup detected (no
dsmbackup-driven docker backup;state=disabledon backup task).
5. DSM configuration backup (auto)
- DSM maintains an automatic config backup at
/volume1/@config_backup(61 KB, dated 2026-08-16) — this captures DSM settings/account/network config. Good, but it lives on the same volume/NAS, so it protects against config drift, not NAS loss. Include in any off-NAS backup.
Snapshot Protection
- Share-snapshot service enabled on all shares, but only
vMix Recordingshas a snapshot, and it is empty (singledesktop.ini). - Effectively zero snapshot protection today.
Protection Gaps (BACKUP EXISTS vs RESTORE VERIFIED)
| Dataset | Backup exists? | Restore verified? | Notes |
|---|---|---|---|
homes (all users) | Yes (Hyper Backup → USB, stale) | NO | Only non-offsite backup; stale 9 mo |
vMix Recordings (752 GB) | NO | — | CRITICAL GAP — irreplaceable, largest dataset |
docker/data/media (534 GB) | NO | — | Re-downloadable; low priority |
| Docker compose configs | Partial manual (stale) | NO | Fragile |
| Vaultwarden data | NO (within docker share) | — | Priority — password manager |
| Synology packages/config | not captured | — | DSM config not exported |
projects, Shared Documents | Not in Hyper Backup job | — | Gap |
| Offsite/cloud copy | NO | — | No off-NAS backup anywhere |
Conclusion
- Only the homes directories are nominally backed up, and only to a USB drive on the same physical NAS (protects against disk failure within the box, but not against fire/theft/whole-NAS loss, and is 9 months stale and unverified).
- vMix Recordings, media config, projects, vaultwarden have no effective backup.
- No restore has ever been tested → cannot assume any backup is recoverable.
Phase-2 Priorities (proposal — not executed)
- P0 — Add an off-NAS backup for
vMix Recordings+homes(target: golden-eye / srv1388017 VPS / edge; rsync/rclone/rsnapshot). - P0 — Restore-test the existing USB homes backup (restore one user dir to scratch, verify hashes) before trusting it.
- P1 — Back up all compose configs + env-file names under
/volume1/docker(platform/, stacks/, nsystems-monitoring/) to a restorable location. - P1 — Export DSM config (Control Panel → config backup) + Hyper Backup task config.
- P2 — Offsite copy of vaultwarden + key small datasets.
Discovery Commands
cat /var/packages/HyperBackup/etc/synobackup.conf ls -la /volumeUSB1/usbshare/NGAGED_CLOUD_1/ ls -la /volumeUSB1/usbshare/DSM_HOMES_BACKUP/ ls -la /volume1/backups/ /volume1/docker/backups/ cat /usr/syno/etc/sharesnap/sharesnap.conf
Network & Security
07 — Network & Security
> NOTE: Firewall rules, SSH daemon hardening, and reverse-proxy internal rules could not be read without privileged (sudo) access. Items marked UNKNOWN / REQUIRES MANUAL REVIEW need DSM admin or the sudo password.
IP & Interfaces
| Interface | State | Address | Notes |
|---|---|---|---|
eth0 | UP | 192.168.0.164/24 | LAN primary |
eth1 | DOWN | 169.254.67.66/16 | unused |
tailscale0 | UP | 100.90.167.88/32 | Tailscale node ngaged-cloud |
- Gateway: 192.168.0.1
- DNS: 8.8.8.8 / 8.8.4.4
- DDNS: Synology DDNS enabled,
ngaged.synology.me(→ public IP). QuickConnect package present. - Tailscale package v1.58.2 — remote admin path for the agent.
Public Exposure
- Cloudflare tunnel
6f717a56-…(cloudflared container) serves: *.nsystems.live+nsystems.live*.vectorhost.net+vectorhost.net- Ingress →
http://traefik:8080→ internal services (28+ subdomains) - Directly exposed ports (0.0.0.0):
- Plex
32400 - RustDesk
21115-21119 - Jellyfin
8096 - phpmyadmin
8086(container exited but port defined) - freightline-dev
3001(container exited) - LAN: rdt-client
192.168.0.164:6500 - Tailscale-only: gatus
100.90.167.88:8081, gotify100.90.167.88:8082 - Loopback: devshell
127.0.0.1:2222
Exposure flags (unnecessarily exposed?)
- phpmyadmin and freightline-dev are exposed on 0.0.0.0 even though their containers are exited — if they ever start they'd be internet-facing without auth. Flag.
- Jellyfin + Plex directly bound to 0.0.0.0 in addition to the tunnel — double exposure. Prefer tunnel-only (no direct bind).
- RustDesk on 0.0.0.0 (public relay) — intentional but should be confirmed desired.
SSH Configuration
- SSH access confirmed on port 54321 (custom) from golden-eye via key.
- From admin inspection:
PubkeyAuthentication yes,PasswordAuthentication yes(password auth is enabled),ChallengeResponseAuthentication no. The sshd listener runs on the standard DSM config (/usr/bin/sshd -D [listener]). - Finding: password auth is enabled for SSH. Combined with a high but known port, this is an exposure to brute-force. Recommend key-only auth + disable password auth during Phase 2 hardening.
Firewall (DSM firewall — now read with admin access)
- DSM's firewall is the
INPUT_FIREWALLchain (96 total rules). Key allow rules: 1 ACCEPT lo2 ACCEPT state RELATED,ESTABLISHED3 RETURN tcp 0.0.0.0/0 -> dports 5000,5001,6690,54321,22— DSM web (5000/5001), Synology Drive (6690), SSH (54321/22) are allowed from ANY source (internet-facing if the router forwards them).- Rules 4–16
RETURNmany services (NFS, SMB, FTP, media ports 8096/32400/6500, iSCSI, etc.) only from the Tailscale subnet100.0.0.0/8— so SMB, Jellyfin(8096), Plex(32400), rdt-client(6500) are Tailscale/LAN-only at the firewall even though Docker publishes them on 0.0.0.0 (the firewall blocks non-Tailscale access to those). - Net effect: the DSM firewall confines most services to Tailscale; but DSM web + Drive + SSH are open to the internet if the router port-forwards them. The cloudflared tunnel plus exposed Plex/RustDesk ports remain the primary internet paths.
Firewall / NFS / SMB
- iptables INPUT:
INPUT_FIREWALLchain (see above). Default action for unlisted traffic is effectively drop (only RETURN/ACCEPT rules exist; unreturned packets fall to the chain policy). - NFS:
/etc/exportsempty → NFS not exported. - SMB: nearly all shares
guest ok=yes(see §03), but SMB port 445/139/137/138 is RETURN-allowed only from100.0.0.0/8→ SMB is Tailscale/LAN-only. Mitigates the guest-open shares.
Reverse Proxy / TLS / Certificates
- Traefik v3 is the reverse proxy: entrypoints, ACME (Let's Encrypt), CF DNS-01 challenge using
CF_DNS_API_TOKEN(value REDACTED/SECRET). Certs stored inacme.json(/volume1/docker/platform/traefik/acme/). - Authelia (SSO/2FA for proxied apps) is exited/down → auth middleware
dashboard-auth@filestill referenced by Traefik dashboard; proxied services may lack enforced SSO while Authelia is down. Verify exposure.
Certificates
/usr/syno/etc/certificate/containssystem,ReverseProxy,_archivecerts (DSM + reverse proxy certs).
Security posture summary
| Area | Status |
|---|---|
| Public exposure path | Cloudflare tunnel (good) but with direct port binds (reduce) |
| SSO / Authelia | DOWN (gap) |
| SSH | custom port + key auth (good) BUT password auth enabled (tighten) |
| Firewall | DSM INPUT_FIREWALL: DSM-web/Drive/SSH open to all; most services Tailscale-only |
| SMB | guest-writable on most shares (Tailscale/LAN-only via firewall) |
| Malware/AV | BitDefenderForMailPlus group exists (MailPlus AV); no general AV |
| SecureSignIn | installed (2FA/passwordless) — usage UNKNOWN |
| ActiveInsight | cloud monitoring enabled |
Phase-2 recommendations (no change now)
- Remove/disable direct
0.0.0.0binds for Jellyfin, Plex, phpmyadmin, freightline-dev (keep tunnel-only). - Restore/replace Authelia OR confirm Cloudflare Access is enforced for exposed apps.
- Obtain SSH/firewall config via sudo to complete the UNKNOWN section.
- Consider binding RustDesk to Tailscale/LAN only if remote relay is not strictly required.
Discovery Commands
ip -br addr; ip route; cat /etc/resolv.conf ss -tlnp # (needs sudo on Synology) # Firewall (needs sudo): sudo iptables -L INPUT -n sudo cat /etc/ssh/sshd_config cat /volume1/docker/platform/cloudflared/config.yaml # tunnel ingress map grep -iE "entryPoints|providers|acme|endpoint|email" /volume1/docker/platform/traefik/traefik.yml
Scheduled Tasks
08 — Scheduled Tasks & Automation
Tasks enumerated from /etc/crontab, /usr/syno/etc/synoschedule.d/root/*.task, and the Docker scripts/ automation tree. All are read-only observations; nothing changed.
DSM Scheduled Tasks (/usr/syno/etc/synoschedule.d/root/)
| ID | Name | Type | State | Command (decoded) | Purpose |
|---|---|---|---|---|---|
| 1 | DSM Auto Update | weekly (Sun 04:45) | enabled | /usr/syno/sbin/synoupgrade --autoupdate | Auto-apply DSM hotfixes |
| 2 | Run security advisor | weekly (Sun 01:49) | enabled | bash synowebapi …SecurityScan… update/start items=ALL | Scheduled security scan |
| 3 | Update spamassassin rules | daily 04:15 | enabled | /var/packages/MailPlus-Server/target/scripts/SpamRuleUpdate.sh all | MailPlus spam rules |
| 4 | Security check | daily (hourly) | enabled | …/SecurityCheck.sh all | MailPlus security |
| 5 | do_regular_op | daily 02:00 | enabled | /var/packages/MailClient/target/tool/regular_op --all | MailPlus housekeeping |
| 7 | Docker Cleaner | once | disabled | bash /volume1/docker/dockerprune.sh | Docker prune (disabled) |
| 8 | Invidious Stop | daily | disabled | synowebapi …Docker.Container stop Invidious | stop Invidious (disabled) |
| 9 | Invidious Start | daily | disabled | docker container start Invidious | start Invidious (disabled) |
| 10 | Local Copy 1 (Hyper Backup) | daily 03:00 | disabled | /var/packages/HyperBackup/target/bin/dsmbackup --backup 1 | Backup job — DISABLED (stale) |
> Key finding: the only backup task (id 10) is disabled, matching the stale USB backup. DSM auto-update + security scans are enabled. Docker-prune and Invidious tasks are disabled (so nothing is auto-pruning/overwriting today — safe).
/etc/crontab (system)
- MailPlus clean-junk, clamav update, and synoschedtask dispatcher entries (mirror tasks above). No destructive crons found.
Custom Docker automation (/volume1/docker/scripts/)
Automation helpers (present but not necessarily scheduled):
nasops(14 KB bash CLI),stackctl.sh,stack-update.sh,stack-status.sh,compose-all-down.shnetwork-watchdog.sh,dnscheck.sh,portcheck.sh,tlscheck.sh,routercheck.sh,preflight.sh,validate-traefik-config.shemail-notify.sh/.py,fix-postgres-perms.sh,add-authelia-labels.py,lib.sh,boot-startup.sh/volume1/docker/update-all-stacks.sh(deprecated → points to stack-update.sh)/volume1/docker/dockerprune.sh— referenced by disabled task 7; not present at/volume1/docker/dockerprune.sh(only referenced). Verify in Phase 2.- Makefile (
/volume1/docker/Makefile) — deployment/ops targets (dns, preflight, tls, deploy, etc.) — not a cron, dev tooling.
What these do / depend on
- Auto-update depends on network + Synology update server.
- Security scan depends on DSM Security Advisor.
- MailPlus tasks depend on MailPlus server; relate to mail data.
- Backup task (disabled) would call
dsmbackup --backup 1→ the USB Hyper Backup job. - Prune task (disabled) — would delete Docker junk — currently not running (good; nothing being pruned now).
Anything capable of deleting/moving/syncing/overwriting?
- No enabled task does deletion today. The prune task and backup task are both disabled.
- Docker
*arr/media stack performs its own moves/hardlinks but that is application behavior, not a scheduled destructive task. - CleanUpArr / Recyclarr (running containers) manage *arr data (cleanup/config sync) — could delete media if misconfigured; note but they are healthy and user-configured.
Discovery Commands
cat /etc/crontab for f in /usr/syno/etc/synoschedule.d/root/*.task; do echo "--$f--"; grep -E "^(id|name|type|state|action|cmd)=" "$f"; done ls -la /volume1/docker/scripts/
Hermes Current State
09 — Hermes Current State (on NAS)
> Finding: There is no Hermes installation running on the NAS today. The mission brief said "Hermes currently exists on this NAS" — the evidence indicates it does not currently run there. What exists is a staging artifact (an empty Ollama data directory), not a live agent. Nothing was migrated.
Evidence
| Check | Result |
|---|---|
which hermes on NAS | not found |
~/.hermes on NAS | does not exist |
docker ps -a --filter name=hermes | no container |
find /volume1 -iname "*hermes*" | no matches |
/volume1/docker/ollama/ | exists but contains only empty logs + a 4 KB model blob stub (see below) |
/volume1/docker/ollama/ — the only NAS artifact
logs/ollama.log— logs from an Ollama process run 2026-07-02 … 2026-07-07 (last entry 2026-07-07T05:39). Shows an Ollama server was run on the NAS ~2 weeks in July, fetching model recommendations, then stopped.models/blobs/sha256-6528…— 4 KB blob (a tiny placeholder/stub, not a real model). Manifest forglm-5.2:cloudpresent (a cloud-sized pointer, no local weights).- Conclusion: Someone staged a Cloud-Ollama mount (
ollamadir) on the NAS, ran it briefly in early July, and it is no longer running and has no usable model weights. This is a leftover staging artifact, not an active Hermes.
Why it matters for the target architecture
- The target: Primary Hermes Orchestrator → Compute/Laptop (golden-eye), with an optional lightweight NAS Domain Agent (storage/DSM operator, read-only by default, least-privilege, reports to orchestrator).
- The NAS currently has no agent — clean slate. The
/volume1/docker/ollamadir should be treated as review (likely remove or repurpose as a future NAS-agent data mount during migration — Phase 2+, not now).
Data needed to (re)build a NAS Domain Agent later (NOT migrated now)
- NAS SSH account (msn0624c) + key access (present).
- Read-only DSM API/tool access (
synoshare,synouser,synostgpool,synosharesnapshot— via sudo). - A lightweight container/runtime for the agent (Ollama dir could host it).
- Connection back to golden-eye orchestrator (Tailscale
100.90.167.88↔100.112.235.92). - Least-privilege operator identity (dedicated NAS-agent user, not full admin).
Dependencies
- The future NAS agent depends on: golden-eye orchestrator (orchestration), Tailscale (connectivity), DSM API (management), and read-only access to shares/volumes/snapshots (storage ops). None of these are provisioned for Hermes yet.
Secrets
- No Hermes credentials exist on the NAS to document (none found). Any future agent credentials must be stored in SOPS/Vaultwarden/broker, never in the wiki or chat.
Recommendation
- Treat NAS Hermes as not present; plan the NAS Domain Agent from scratch in the target architecture. The
/volume1/docker/ollamadir is a REVIEW item (likely retire/repurpose). Confirm with Stephen whether a prior partial Hermes/Ollama setup was abandoned.
Discovery Commands
which hermes; ls ~/.hermes /usr/local/bin/docker ps -a --filter name=hermes find /volume1 -maxdepth 3 -iname "*hermes*" ls -la /volume1/docker/ollama; du -h /volume1/docker/ollama/models/blobs/* cat /volume1/docker/ollama/logs/ollama.log | tail
Dependency Map
10 — Dependency Map
Map of relationships among NAS shares, containers, packages, users, backups, and external infrastructure. Focus: hidden dependencies that could break after a factory reset.
External machines / services
| External node | Relationship to NAS |
|---|---|
| golden-eye (100.112.235.92) | Orchestrator; SSH operator to NAS (port 54321); future primary Hermes host |
| srv1388017 VPS | (documented sibling; may be backup target in Phase 2) |
| Cloudflare | Tunnel 6f717a56 + DNS for nsystems.live/vectorhost.net; Traefik CF DNS-01 token for TLS |
| Tailscale | VPN mesh; agent/NAS connectivity (100.90.167.88) |
| Ollama cloud | (nas-guestory) — NAS had staged Ollama cloud mount (glm-5.2:cloud), no local model |
| Internet indexers | *arr uses Prowlarr + FlareSolverr + debrid (rdt-client) — external API deps |
| USB drive | local backup target (Hyper Backup) |
Share → Service dependencies
docker/data/media← all *arr, Jellyfin, Plex, rdt-client, bazarr, deemix (bind mounts)docker/data/media-library← Jellyfin, Plex (read), TubeArchivist-kids (write)docker/data/torrents← qBittorrent/rutorrent/cleanuparrdocker/stacks/…/stack-config/*← all media containers (config; reproduceability)docker/platform/{traefik,cloudflared,ddns}← all public web services (proxy/tunnel/DNS)homes← Synology Drive, FileStation, Photos, Hyper Backup sourcevMix Recordings← only filesystem/DSM (no container depends; no backup)
Container → Container
- Traefik ↔ all web apps (routing)
- cloudflared → Traefik (tunnel → ingress)
- Authelia (exited) → proxied apps (auth middleware) — down = SSO gap
- qBittorrent/rutorrent → gluetun (VPN network namespace)
- rdt-client → *arr (download client via fake qBit API)
- Plex → tautulli (stats), overseerr → sonarr/radarr (requests)
- Prowlarr → sonarr/radarr/lidarr (indexer sync)
- TubeArchivist → tak-redis + tak-elasticsearch
Users / service accounts
msn0624c(admin + docker) → all compose stacks, SSH, backupsngaged-cloudgroup (5 family users) → homes sharesshaconann/vidalstephen/sadevidal/rore-admin→ largest homes data- package service accounts (postgres, mysql, mailplus, etc.)
Backup
- Hyper Backup job (homes → USB) depends on USB drive + job enabled (currently disabled).
- No container/app config backup → hidden fragility for any container.
Hidden-dependency risks after a factory reset
- All DNS/TLS breaks unless Cloudflare tunnel creds (
6f717a56-….json) + CF DNS token are recovered. Stored in/volume1/docker/platform/{cloudflared,traefik}— inside the docker share. - All compose stacks lose their config if
/volume1/docker/stacks+/platform+/nsystems-monitoringare not backed up. - Vaultwarden (password manager) — if
/volume1/docker/stacks/homelab/vault/configis lost, all vault credentials are lost. - Media library is re-downloadable but huge; vMix Recordings is irreplaceable and has no backup.
- ACL/permission model is DSM-native; recreated cleanly only if config exported.
- Package list (MailPlus, Photos, Drive) must be reinstalled + re-licensed.
- Docker images (255, 162 dangling) — re-pullable but config labels are in the exited containers.
- Anonymous volumes (11 hex volumes) — content/ownership unknown; may hold unreproducible data.
Dependencies of external on NAS
- Cloudflare tunnel depends on the NAS's cloudflared container staying up (if NAS down, 28+ subdomains go dark).
- RustDesk relay (hbbs/hbbr) — clients depend on NAS.
- Plex/Jellyfin clients depend on NAS media + streaming containers.
- Synology Drive/Photos clients depend on NAS.
Diagram (text)
Internet
│ (DNS: nsystems.live / vectorhost.net)
▼
Cloudflare Tunnel (6f717a56) ──► cloudflared (NAS)
│
▼
Traefik (:80/443)
│ ├─(CF DNS-01 cert)
▼
Authelia [DOWN] ── SSO gate (gap)
│
┌──────────────┬───────────┴──────┬───────────────┐
▼ ▼ ▼ ▼
Jellyfin *arr stack static apps monitoring
Plex Sonarr/Radarr/ (scrapline2, (gatus/gotify)
Prowlarr/Bazarr crimson, ...)
│ │ │
▼ ▼ ▼
/docker/data/ /docker/data/ /volume1 (docker.sock
media-library media via devshell)Risk Register
11 — Risk Register
Prioritized risks with Evidence → Impact → Remediation (not executed in Phase 1).
CRITICAL
R1. No verified restore — backup may be unrecoverable
- Evidence: Hyper Backup job "Local;1" is disabled (task id 10
state=disabled); USB targetNGAGED_CLOUD_1+synobkpinfo.dblast modified 2025-11 (~9 months stale); no restore test on record. - Impact: Even the homes data cannot be guaranteed recoverable. A perceived backup may be a false sense of security.
- Remediation: Phase 2 P0 — restore-test the USB backup (restore a user dir to scratch, verify hashes) before proceeding; do not rely on it.
R2. vMix Recordings (752 GB) has NO backup
- Evidence: Not in Hyper Backup folder list (
backup_folders= homes only); snapshot empty (desktop.inionly); largest single dataset (752 GB, mostly >4 GB church service videos). - Impact: Total loss of irreplaceable recordings on any deletion/corruption/fire. Highest-value single dataset.
- Remediation: Phase 2 P0 — off-NAS backup (rsync/rclone/rsnapshot to golden-eye/srv1388017/edge) + enable snapshot scheduling + periodic integrity check.
R3. Only backup targets the SAME NAS (no offsite)
- Evidence: Hyper Backup
trans_type=local→ USBusbshare1physically attached to the NAS; no cloud/offsite job. - Impact: Whole-NAS loss (theft, fire, power surge) destroys data AND backup together.
- Remediation: Add off-NAS/offsite backup (rclone to object storage, edge VPS, or a second site).
HIGH
R4. Docker/container config not reproducibly backed up
- Evidence: Compose files + stack-config live inside
/volume1/docker(no automated backup; manual snapshots stale). 255 images / 162 dangling / 11 anonymous volumes. - Impact: Factory reset or volume loss = all stack configs gone; containers cannot be rebuilt from memory.
- Remediation: Back up
/volume1/docker/{platform,stacks,nsystems-monitoring}+.env/env-file names to a restorable location; dumpdocker inspectfor every container; snapshot named volumes.
R5. Vaultwarden (password manager) data not backed up
- Evidence:
vaultwardenconfig at/volume1/docker/stacks/homelab/vault/config; inside docker share; no backup job. - Impact: Loss of the password vault = total credential loss.
- Remediation: Phase 2 P1 — include vaultwarden
config/in backup (ideally offsite) + enable Bitwarden built-in backups if available.
R6. Authelia (SSO/access control) is DOWN while services are internet-exposed
- Evidence:
autheliacontainer exited; compose labels referenceauthelia.nsystems.live; tunnel serves 28+ subdomains. - Impact: Exposed web apps may lack enforced SSO/2FA; dashboard-auth middleware may fail open.
- Remediation: Restore or replace Authelia, or enforce Cloudflare Access on tunnel routes; confirm every exposed route requires auth.
R7. Container config / anonymous volumes unowned
- Evidence: 11 anonymous hex volumes; several exited containers (calcom, reactive-resume, etc.) with DB volumes; no owner map.
- Impact: Unknown data, can't reproduce; storage + restore clutter; potential orphaned DBs.
- Remediation: Map each anonymous volume to its container in Phase 2; decide keep/retire; back up any needed.
MEDIUM
R8. Internet-exposed services on 0.0.0.0
- Evidence: Plex 32400, RustDesk 21115-21119, Jellyfin 8096, phpmyadmin 8086, freightline-dev 3001 all bound to 0.0.0.0.
- Impact: Direct internet exposure beyond the tunnel; phpmyadmin/freightline are exited but would expose if started.
- Remediation: Bind to 127.0.0.1/LAN/Tailscale or keep tunnel-only; disable the exited exposure.
R9. Stale/unsupported runtimes & old containers
- Evidence: Python2, Perl, old wordpress:6.8.3/mariadb:11,
agent-zero, calcom, uptime-kuma, etc. exited; 162 dangling images. - Impact: Attack surface (unpatched images), storage bloat, restore clutter.
- Remediation: Retire/archive stopped containers + prune dangling images (with approval).
R10. Undocumented/partial Docker prune task + Invidious tasks
- Evidence: tasks 7/8/9 (
dockerprune.sh, Invidious stop/start) exist but disabled. - Impact: If enabled accidentally, could delete Docker data (prune) or toggle a container.
- Remediation: Document; keep disabled; remove stale task 8/9 if Invidious not in use.
LOW
R11. Broad operator permissions
- Evidence:
msn0624c= full admin + docker;devshellcontainer mounts docker.sock +/volume1+.ssh. - Impact: If compromised, full NAS control.
- Remediation: Create least-privilege operator for migration; restrict/remove devshell docker.sock & /volume1.
R12. Data with unclear ownership
- Evidence:
ryanhome empty; legacymediashare redundant with docker/data/media; anonymous volumes. - Impact: Can't confidently archive/retire.
- Remediation: Confirm ownership in Phase 2 before any removal.
R13. Single copies of important data
- Evidence: vMix (752G) & vaultwarden & compose configs have single copies.
- Impact: any local failure = loss.
- Remediation: (covered by R2/R4/R5 backup actions)
R14. SSH/firewall hardening unverified
- Evidence:
sshd_config+ iptables not readable without sudo; SSH on custom port 54321. - Impact: unknown whether root login/password auth permitted.
- Remediation: Obtain sudo/DSM admin, review SSHD + firewall, enforce key-only, restrict root.
> Admin-pass update: This is now RESOLVED (firewall + SSHD + ACLs + SMB enumerated). Two new findings from the privileged pass:
R15 (MEDIUM→HIGH). SMB shares are guest-writable
- Evidence:
smb.confshows nearly all shares (homes,docker,media,projects,music,web,chat,MailPlus,usbshare1, etc.) withguest ok=yes,valid users=nobody,nobody,writeable=yes. - Impact: Any LAN/Tailscale client can access these shares without authentication, including
homes(personal data) anddocker(container configs/media). Mitigated only by the DSM firewall confining SMB to100.0.0.0/8(Tailscale) — so exposure is Tailnet/LAN, not internet. - Remediation: Restrict SMB shares to named users/groups (remove
guest ok), especiallyhomesanddocker. Enable SMB auth. During Phase 2, audit and lock down each share.
R (MEDIUM). SSH password authentication enabled
- Evidence:
sshd_confighasPasswordAuthentication yes. - Impact: Brute-force risk on the known SSH port (54321) for any account with password auth.
- Remediation: Disable password auth (key-only), enforce for all users; ideally restrict SSH to Tailscale/LAN.
Risk summary counts
- CRITICAL: 3 (no-verified-restore, vMix no backup, no offsite)
- HIGH: 4 (docker config not reproducible, vault not backed up, authelia down + exposure, SMB guest-writable)
- MEDIUM: 4 (0.0.0.0 exposure, stale/unsupported images, undocumented disabled automation, SSH password auth)
- LOW: 4 (broad perms, unclear ownership, single copies, unverified hardening)
> No remediation performed in Phase 1. All items pending Phase 2 authorization.
Keep / Move / Retire / Replace
12 — Keep / Move / Retire / Replace (Migration Classification)
Intended architecture principle:
- Synology NAS = storage, snapshots, backup, replication, and carefully selected data-centric services.
- Compute/Laptop (golden-eye) = Hermes orchestration, AI/agent workloads, automation, dev tools, monitoring, databases, compute-heavy services.
- VPS/Edge = services needing public internet accessibility.
- NAS Domain Agent = lightweight, read-only-by-default, least-privilege storage/DSM operator reporting to the primary orchestrator.
Provisional classification for each significant workload. No migration performed in Phase 1.
Storage / Shares
| Item | Class | Rationale |
|---|---|---|
vMix Recordings | KEEP on NAS (+ backup offsite) | Data-centric, irreplaceable, huge |
homes | KEEP on NAS (+ backup offsite) | Personal data, Synology Drive/Photos native |
docker/data/media | KEEP on NAS | Media library, re-downloadable, near streamers |
projects | MOVE (to compute) | Dev/project files belong with compute |
media (legacy share) | RETIRE/REVIEW | Redundant with docker/data/media |
Shared Documents | KEEP | Office docs |
music | REVIEW | vs docker/data/media/Music |
chat, MailPlus, Calendar, Contacts | REVIEW/RETIRE | decide if actively used |
web, web_packages | RETIRE/REVIEW | not used for hosted apps (they're Docker now) |
gitea-share | REVIEW | empty |
backups | KEEP | admin/backup staging |
Containers
| Workload | Class | Target host |
|---|---|---|
| Traefik (reverse proxy) | KEEP (or MOVE) | NAS (data-local) or VPS/edge |
| cloudflared (tunnel) | KEEP | NAS (or move to always-up edge) |
| cf-ddns | KEEP | NAS |
| Authelia | REPLACE/REVIEW | resolve SSO gap |
| media-platform (Jellyfin, Plex, *arr, Overseerr, Tautulli, Deemix, TubeArchivist) | KEEP ON NAS | data-local |
| qBittorrent/gluetun/rutorrent/rdt-client | REVIEW | near media; VPN sidecar on NAS |
| Gatus, Gotify | MOVE to COMPUTE | monitoring/notifications belong on golden-eye |
| Vaultwarden | KEEP or MOVE to VPS | decide; must be backed up |
| RustDesk (hbbs/hbbr) | MOVE to VPS/EDGE | public relay wants always-up host |
| devshell | REPLACE | dev shell on compute; restrict |
| scrapline2, crimson-haven, skybreaker-transform, ghostline-command | MOVE to COMPUTE/VPS | static/hosted apps |
| Exited: wordpress(+db), aethrix(+phpmyadmin), reactive-resume(+db+printer), calcom(+db+redis), uptime-kuma, dozzle, dsm-router, dungeon-generator, template-myapp, agent-zero, druglord, freightline(+dev), starforge, scrapline(old) | RETIRE/REVIEW | old project containers; keep only if needed |
Packages
| Package | Class |
|---|---|
| Container Manager, Hyper Backup, Synology Drive, Photos, Storage Manager, FileStation, SMB, Tailscale, SecureSignIn | KEEP (essential) |
| Synology Photos/Drive | KEEP |
| Chat, MailPlus(+Server/MailClient), Calendar, Contacts, HybridShare, USBCopy, Analytics, AIConsole, ActiveInsight | REVIEW/RETIRE (if unused) |
| Python2, Perl, redundant runtimes | RETIRE (bloat) |
| (None) — no Active Backup, no VPN packages installed | — |
Hermes / Agent
| Item | Class | Notes |
|---|---|---|
| Hermes on NAS | NOT PRESENT (no migration needed) | Only staging /volume1/docker/ollama stub |
| NAS Domain Agent (future) | ADD | read-only by default, least privilege, reports to golden-eye orchestrator |
| Primary Hermes Orchestrator | KEEP on golden-eye | target architecture |
/volume1/docker/ollama dir | REVIEW (likely retire/repurpose) | abandoned staging |
Summary of target placement
- On NAS: storage (all shares), media stack, torrent/VPN, Traefik/cloudflared/ddns (or edge), Synology data packages.
- On Compute (golden-eye): Hermes orchestrator, monitoring (gatus/gotify), dev tooling, static/hosted apps, project files.
- On VPS/Edge: RustDesk relay, any truly-public services, offsite backup target.
- NAS Domain Agent: lightweight read-only DSM/storage operator reporting to orchestrator (Phase 2+ design).
> All classifications are provisional recommendations. No migration or removal performed in Phase 1. Decision required from Stephen before Phase 2 moves any workload.