Files
felhom.eu/REPORT-plex2shell-felhom-impact-2026-10-23.md
T
admin 8257ff1cbe
gates / gates (push) Successful in 12m37s
Plex2Shell impact on Felhom: verdict NOT REACHED; R-1241 (P1), R-1242 (P3) opened (register 186 -> 188)
Read-only audit of whether the hacked Plex pod on DooPlex (HM-040, 2026-10-17 -> 10-23) reached Felhom's
secrets. Two no-login doors existed (the Longhorn NFS export and the Longhorn API); neither was used:
nfsd accepted 0 new connections in the window (positive control), no off-schedule Longhorn backup or volume.
Evidence in documentation/audits/plex2shell-felhom-impact-2026-10-23/. The NFS export was narrowed from *
to 10.42.0.0/16 on the operator's yes (host change, not in git). 13-threat-model.md: attacker j and one
boundary row. STATUS: verdict, the P1, one do item.
2026-10-23 17:53:43 +02:00

5.5 KiB

REPORT — did the Plex attack on DooPlex reach Felhom's secrets? (2026-10-23)

Plain words first

  1. Verdict: NOT REACHED. Two open doors led from the hacked Plex to Felhom's secrets. Neither was used in the attack days: the backup folder got no new connection at all, and Longhorn made no backup or disk outside its normal plan.
  2. The shared backup folder: closed to the home network and the tailnet (your yes). It is still open to every app on DooPlex — Longhorn needs that, so the real fix is the homelab session's.
  3. What you do next: give the homelab session the hand-over list (documentation/audits/plex2shell-felhom-impact-2026-10-23/README.md, last section). Nothing needs to be rotated.

The Part 4 table

In documentation/audits/plex2shell-felhom-impact-2026-10-23/README.md § Part 4. Short form: every Felhom secret on DooPlex has exposure none. The ones a hacked pod could have reached: the hub's unencrypted nightly copies (with the unsealed Cloudflare/tunnel/git tokens, R-975) through the NFS export or a Longhorn backup, and the operator signing keys through the NFS file-handle escape (documented, not exercised). Sealed hub columns need a key that is not in the copies; escrow blobs need each household's recovery code; the k8s API, the kubelet and the hub refuse a caller with no credential (measured).

The paths and the evidence per path

path existed? evidence of use (window 10-17 04:00Z → 10-23 08:04Z)
NFS export longhorn-pvc (*, no_root_squash, no_subtree_check; secure void in pods) yes unused — node_nfsd_connections_total flat at 288 for 13 days, 3902 samples, no gap; positive control: today's three probe connections moved it to 4. nfsd is TCP-only. Reads only in Longhorn's backup hours
Longhorn API :9500, no login yes no sign of use — 0 backups first seen off-schedule (1-min scrape); every night wrote to the local store; no unexplained volume; the backup target is the 2025-11-29 one. Manager logs: lost (reboot)
hub hub:8080 direct yes, but no secret without a credential 0 requests from 10.42.0.52 in /data/access-log (from 10-18 10:25Z; positive control: the probe's IP is logged). 10-17 04:00Z → 10-18 10:25Z: no record
k8s API, kubelet no (401) —
SSH, Samba on DooPlex login needed 0 sshd lines from the pod network (control: 61 from the LAN); no Samba client file for 10.42.0.52 (positive control: the probe made one)
Vaultwarden login needed; vault encrypted logs lost (reboot)

Evidence lost before this session started: the 13:20Z maintenance reboot erased the pre-reboot container logs of longhorn-manager, longhorn-ui, the ingress, the hub, Gitea, Vaultwarden, Grafana and Prometheus. Reproduced independently from records that survived: Prometheus history (nfsd, Longhorn, cAdvisor, node network), the hub's own access log, the journal (boot -1), Samba per-client files, CoreDNS error lines, the Alertmanager silence list. The incident session's pre-reboot greps (10.42.0.52 in longhorn-manager, CNPG, Gitea, authentik: 0) are cited as theirs.

For the homelab session

The seven items at the end of the audit README: the export still open to pods (and secure is void there); Longhorn API and UI with no login; an unattributed Longhorn delete of the old Plex volume at 11:24:15Z; ~1.5 TB sent out by the Plex pod 10-18 → 10-22 (not in INCIDENT.md) plus hand.genddos.st DNS lookups on 10-19; the reboot that erased the logs; the monitoring stack and Headlamp reachable from every pod; a python3 main.py listener on :8443. No HM numbers minted; homelab-manifests not touched.

What this session changed

  • DooPlex /etc/exports (operator yes, ~15:18Z): longhorn-pvc from * to 10.42.0.0/16, exportfs -ra; Longhorn target available: true at 15:20:10Z. Backup /etc/exports.bak-2026-10-23-plex2shell. The only change on DooPlex.
  • Probe pod default/cc-p2s-probe: created 15:19:46Z, removed 15:33:44Z; before/after listings in the evidence. No other object created. The incident's NetworkPolicies untouched.
  • felhom.eu: the audit folder; R-1241 and R-1242 in OPEN-ITEMS.md; 13-threat-model.md (attacker j, one boundary row); STATUS.md (verdict in „What works", the P1 in „What is broken", one „do" item; the old „Updated" paragraph moved to STATUS-HISTORY.md).
  • Nothing rotated. No secret value written anywhere (evidence scanned for secret shapes; the only 64-hex string is the sha256 of /etc/exports).

Rows

Before 186, after 188; opened 2 (R-1241 P1, R-1242 P3), closed 0.

Observations

  • Hacked pod → hub backups + signing keys through the NFS export and the Longhorn API — FILED: R-1241.
  • Demo NAS export on the same disk with no_subtree_check — FILED: R-1242.
  • The hub answers pods without the geo filter — NOT-A-FINDING: the geo filter is not authentication; every no-token path refused.
  • demo-felhom's Proxmox UI and SSH reachable from any DooPlex pod — NOT-A-FINDING: the door of R-982; added as attacker j in 13 §3.
  • Pod logs erased by the reboot — NOT-A-FINDING for Felhom (the hub's access log persisted, R-1140); handed to the homelab session.

Notes for the next session

  • Teardown, three layers: machine — probe pod removed, export change kept on purpose (operator yes); host — none; hub — none (read-only access-log aggregation in the running pod).
  • System poster: no fact on it changed (none of the three applied).
  • unproven.py: not run — no capability claim changed.