For Agents
Living index of themes for this project. Each H2 is a topic; bullets are wikilinks to related notes. Updated by
obsidian-documenterwhen documenting work. Read byhistorianat bootstrap. Topics kept alphabetical.
Access & Remote Management
- telep-router — SSH via Tailscale MagicDNS; on macOS a shell wrapper breaks bare
ssh, use/usr/bin/sshexplicitly - Access — Frigate UI over Tailscale Serve (
--https=443→127.0.0.1:8971), real LE cert, tailnet-only; iOS Private Relay breaks MagicDNS in Safari - 2026-07-24-global-dashboard —
home.taild4189d.ts.net, the tailnet landing dashboard linking Kamerák / Tudásbázis / Top képek / Router - filestash — Windows drive browser over Tailscale Serve (
--https=8445→127.0.0.1:8334), tailnet-only - Prerequisite router access — mainframe→router SSH added via LAN-only key-only dropbear +
/home/levander/.ssh/router_alarm(router was Tailscale-SSH-only, ACL-blocked)
Alerting & Notifications
- Alerting — Telegram bot “Dezsi az őr” → supergroup; frigate-notify polls the Frigate HTTP API every 15s (no MQTT); dedup is zone-aware
- 2026-07-17-intruder-alarm — same “Dezsi az őr” bot; auto-arm/disarm +
🚨 BETŐRŐ!intruder escalation (1×day/2×night) + snapshot; solegetUpdatesconsumer for enrollment/commands - 2026-07-23-frigate-viewer-alert — same frigate-notify bot+chat: Telegrams
👁 <device> opened Frigatewhen someone opens the camera UI; identity fromtailscale serve’sX-Forwarded-For→ tailscale device name; per-source 5-min session cooldown
Bandwidth & Traffic Metering
- 2026-07-22-wifi-usage-strip — live per-device WiFi bandwidth on the camwall;
wifi-usage.servicepollsiw dev <ap> station dumpevery 5s and diffs byte counters into Mbps - [[2026-07-22-wifi-usage-strip#2-bytes-come-from-iw-not-iwinfo|2. Bytes come from
iw, notiwinfo]] —iwinfo assoclisthas no byte counters,iw station dumpdoes; per-device metering needs no nftables accounting, conntrack parsing or nlbwmon, andiwships on the router - SESSION-HANDOVER — the
tcHTB 15 Mbit cap on192.168.1.135, persistent via/etc/hotplug.d/iface/99-throttle-fm;bmonfor live per-interface rates
Cameras & Surveillance
- telep-mainframe — Frigate 0.17.2, ONNX YOLOv9-s on an RTX 3080, events-only recording, birdseye HDMI wall
- RTSP stream map — Tapo TC47 dual-lens:
/cam1/and/cam2/are the same lens. Fixed =/stream1+/stream2, PTZ =/stream6+/stream7 - Camera VLAN (telep-cc) — isolated
192.168.30.0/24, hidden SSID, no internet, NTP DNAT’d back - 2026-07-17-intruder-alarm — watches Frigate person/car events to escalate intruders and siren the TV while armed
- 2026-07-18-birdseye-nvenc-blue-glare — the camwall’s live panes play Frigate’s
birdseyerestream; NVENC encoder corruption there = “blue glare” on the TV wall (isolation method for the whole RTSP→mpv→TV pipeline) - 2026-07-22-wifi-usage-strip — the camwall’s bottom strip (y 1880–2140, below TOP KÉPEK): live per-device WiFi rates drawn as an mpv
osd-overlay, never over the camera image; usesosd-overlayrather thancamwall-reloadso playback is untouched - 2026-07-23-frigate-viewer-alert — “who is looking at my cameras”: follows Frigate’s nginx access log via
docker logs -f, alerts on every UI session by tailnet device name; internal automation (XFF-) excluded by construction
Containers & Docker
- nvr) —
frigate(stable-tensorrtimage, butonnxdetector) +frigate-notify; mount the whole/configdir or the event DB is wiped on recreate - filestash —
machines/filestashbound to127.0.0.1:8334, state infilestash_datavolume, Windows drive passed in at/mnt/data:ro - The Windows drive — a bind-mount captures the host dir at container start: mounting
/mnt/winafterfilebrowserstarted leaves/srvempty inside the container → mount first, thendocker restart filebrowser
Documentation & Knowledge Tooling
- 2026-07-24-knowledgebase — tailnet-only manual library + OCR ingest portal; mkdocs-material static site of OCR’d PDF manuals (folder-tree browse, full-text search, dark mode, lazy images) + a Flask
/uploadportal that OCRs a PDF into the library - How it works (the reusable parts) — chunked loading = split each manual by its
#h1 headings into many small per-section pages (a 795 KB markdown would be one huge page) + a mkdocson_post_pagehook injectingloading="lazy"into every<img>; folder tree → mkdocs auto-nav; mkdocs builds to a temp dir thenos.rename-swapssite/(atomic, a broken source never takes down the live site) - Library expansion (2026-07-24) — the expanded manual library (suzuki-vitara / chevy-tracker / suzuki-sidekick); marker →
seed_import.py→ build, manuals queued as CHAINED nohup scripts (.donesentinel) to serialize the single GPU; md5-dedup downloads BEFORE OCR - 2026-07-24-kickfix-ingest — ingesting a 112 MB offline archive of the dead kick-fix.com repair site (HTML→markdown, 25 topics / 127 articles / 741 images) into
docs/kick-fix/; reusable lessons for old table-layout HTML - 2026-07-24-kb-vectorize-complete — semantic search over the whole library: 2839 chunks embedded (
bge-large-en-v1.5, CPU torch) into Qdrant (kb-qdrant, collectionmanuals); cross-source search blends official manuals + kick-fix; idempotent per-manual (delete-by-filter + uuid5 ids) - 2026-07-24-kb-semantics-phase2-complete — phase 2 (semantic dedup): fully-local SECTION clustering over the phase-1 vectors + a read-only “Szemantika” explorer, NO LLM. Mean-pool 3252 chunk vectors → ~1248 section vectors → HDBSCAN → 194 clusters / 24 cross-SOURCE / 631 noise;
clusters.jsonregenerated on demand (kbclust.py build), explorer/semanticsfolded into the existing knowledgebase app (no new service); ranked by cross-source span; labels pluggable behindmake_labelfor a futureclaude -prelabel;clusters.json= phase 3’s retrieval bundle - scanned-pdf-to-markdown-marker — the reusable
~/ocr/venvmarker OCR pipeline the knowledgebase ingest calls as a subprocess (no duplicate torch/model install)
File Storage & Sharing
- filestash — in-browser file browser for the box’s Windows C: drive; NTFS mounted read-only at
/mnt/winviantfs3, served over tailnet at:8445 - mp4-missing-moov-forensics — a 1.6 GB SplitCam recording served off
/mnt/winvia Filestash was dead on arrival; how to trace a download’s origin (kMDItemWhereFroms) and chunk-md5 it against the source - Drive inventory (2026-07-21) — mainframe drives:
nvme0n11.8T Windows,nvme1n13.6T LUKS+LVM OS,sda447G unused,sdb= Hiren’s BootCD PE USB stick
Firewall & Security
- telep-router — zones: lan ACCEPT, wan REJECT + masq + mtu_fix, plus an isolated
camszone with nocams → wan - Security Gaps — 8-char WPA3 PSK, dropbear password auth, LuCI on plain HTTP, plaintext DNS, unpatched 24.10.0
- telep-mainframe — all ports bound to
127.0.0.1; passwordless sudo is an accepted tradeoff; Secure Boot disabled to load the NVIDIA module - Prerequisite router access — new LAN-only key-only dropbear on the router (PasswordAuth off) partially closes the “dropbear password auth” gap; bot token read from
~/nvr/frigate-notify/config.yml, never hard-coded - 2026-07-24-luks-tpm-autounlock — root LUKS2 now TPM2 auto-unlocks via clevis (keyslot 1 = TPM with empty PCRs, keyslot 0 = passphrase fallback); with empty PCRs + Secure Boot off the tradeoff protects against bare-drive theft, not whole-box theft; header backed up before touching keyslots. Reboot test PASSED in production — self-recovered root through the 3-reboot PSU-load storm (2026-07-24-psu-load-resets)
GPU & Hardware Acceleration
- telep-mainframe — RTX 3080: ONNX inference ~12ms / ~6% GPU, NVDEC decode (
preset-nvidia),nvdec-copyin mpv so the drawtext filter can run - TV wall (HDMI) —
nvidia-drm modeset=1is mandatory or the 3080 exposes zero display connectors - 2026-07-18-birdseye-nvenc-blue-glare — the 3080’s NVENC encoder (not just NVDEC) can wedge and corrupt Frigate’s birdseye restream (
h264_nvenc) blue/purple even at GPU idle;docker compose restart frigateclears it, blankhwaccel_args→ libx264 for a durable fix (YOLO inference stays on CUDA) - 2026-07-24-knowledgebase — the knowledgebase ingest reuses the
~/ocr/venvmarker pipeline as a subprocess (marker_single,TORCH_DEVICE=cuda); a single background worker GPU-serialises OCR (one at a time, shared with Frigate) so occasional ingests coexist with detection on the 12 GB card - 2026-07-24-kb-vectorize-complete — embeddings run on CPU torch deliberately (sidesteps the CUDA-13-vs-driver-550 trap and avoids GPU contention with OCR + Frigate); but maxing all 16 cores browned out the PSU → cap to 4 threads (see 2026-07-24-psu-load-resets)
- Running it on a CUDA GPU box (telep-mainframe) — driver 550.163.01 caps you at CUDA 12.4: pip’s default cu130 torch can’t init CUDA and PyTorch silently runs on CPU; fix is a cu126 build (minor-version compat), not a driver upgrade — driver 550 is load-bearing for Frigate. Reusable OCR venv at
~/ocr/venv; marker ~3.5 GB VRAM coexists fine with Frigate’s ~2.5 GB on the 12 GB card
Gotchas & Learnings
- 2026-07-24-kb-semantics-phase2-complete — ⭐ HDBSCAN’s
min_samplesdefaults tomin_cluster_size→ withmin_cluster_size=2unset, everything becomes noise (0 clusters); setmin_samples=1explicitly. ⭐ Cross-source “span” inflates when your id is<folder>/<manual>and one archive is split into many subfolders (kick-fix = 1 source but ~25 subfolders) → rank span by distinct TOP-LEVEL folder (manual_id.split("/",1)[0]), stoplist boilerplate labels, and treat 51% noise singletons as EXPECTED for a dedup goal; whole pipeline is READ-ONLY scroll → localclusters.json - Gotchas — wifi-ifaces declare
network='lan wan'(inert, but one step from bridging APs onto WAN); 8-char PSK; double-NAT;/romat 100% is normal for squashfs - filestash — Windows NTFS mount is manual (not fstab, won’t survive reboot); RW would corrupt the live/hibernating Windows install; iOS Private Relay breaks MagicDNS in Safari
- The Windows drive — NVMe device nodes flip across reboots (the Windows NTFS partition moved
nvme1n1p2→nvme0n1p2):lsblk -fevery time,UUID=in fstab; anddocker restart filebrowserafter mounting or/srvlooks empty in the container - 2026-07-17-intruder-alarm — sleeping iOS phones stay WiFi-associated but stop answering ARP (arp-scan alone false-arms; assoc table saves it); failed scans skipped so blips can’t false-arm; camera SSID
telep-cc(phy1-ap1) leaked the camera as an enrollable device; enabling router dropbear rotated its SSH host key - 2026-07-18-birdseye-nvenc-blue-glare — camwall “blue glare” is NVENC-encode corruption of Frigate’s birdseye (distinct from the NVDEC decode magenta bug); wedges even at GPU idle; restart Frigate to clear, blank
hwaccel_argsfor a durable libx264 fix; isolate by grabbing a still per pipeline layer - mp4-missing-moov-forensics —
moov atom not founddoes not always mean “untrunc can fix it”: a crashed recorder + NTFS preallocation leaves an mdat full of stale deleted-file bytes (max entropy, zero valid NAL chains) = unrecoverable. Verify the payload parses before investing in recovery tooling; Homebrew has nountruncformula (2026-07) - 2026-07-22-facekom-vpn-exit-node — a wrong peer IP looks exactly like a bad CA bundle when two OpenVPN servers share a subnet+port; a labelled/tab-delimited vendor
auth.txt(jelszó:<TAB>pw) silently becomes part of the password →AUTH_FAILED;openvpn-client@.service’s process limit makesup/route-upscripts fatal (fork errno=11); Tailscale exit nodes exclude RFC1918; pincurl --resolvewhen testing route changes or anycast fools you; diff cert fingerprints before believing a “new” vendor bundle - 2026-07-22-wifi-usage-strip — mpv destroys
osd-overlayentries when the IPC client disconnects (and still replies{"error":"success"}) → the connection must be persistent and the event stream drained; station byte counters are AP-perspective sotx bytesis the device’s download while the WAN isn’t inverted;camwall-reloadrestarts playback so it’s unusable for live data; SSH ControlMaster masks a deleted key (drop the control socket to test);subprocess.run(text=True)can raiseUnicodeDecodeError— aValueError, not caught byexcept (SubprocessError, OSError) - 2026-07-23-mains-power-shutdowns — a journal that stops dead with no
Stopping/panic/thermal trace = power was physically removed, not a software or OS shutdown; to separate a PC PSU fault from a mains event, cross-check an independent always-on device’s boot time (date +%sminus/proc/uptime) — same-timestamp death = mains; a desktop that “stays off” while other gear silently recovers is the BIOSRestore on AC Power Loss = stay offpolicy, not a new failure - 2026-07-23-frigate-viewer-alert — X-Forwarded-For is the LAST quoted nginx field before
request_time=, not the first — leftmost-match is spoofable via a"injected into the User-Agent/Referer, so takefindall(...)[-1]; never spawntailscale status(or any ~10s subprocess) per log line — under an active viewer that’s a self-DoS, rate-limit miss-refreshes to ≤ once/60s; reset adocker logs -freconnect backoff only after a line is read, and--since 0mso a daemon restart doesn’t replay stale alerts - 2026-07-24-luks-tpm-autounlock — Debian 13 stock initramfs (
initramfs-tools) ignoressystemd-cryptenrollTPM2 tokens (update-initramfswarnsignoring unknown option 'tpm2-device'and still prompts at boot) → use clevis (clevis-initramfs+clevis-tpm2,clevis luks bind … tpm2 '{}') for TPM LUKS auto-unlock on Debian; adding ANY keyslot needs the existing passphrase (an agent can’t) and is slow, so an impatient Ctrl-C orphans asystemd-crypt*process that holds the header lock AND/dev/tpmrm0and blocks the next bind (SIGKILL it, verifyfuser/lsofclear); back up the LUKS header before touching keyslots - 2026-07-24-knowledgebase —
tailscale serve --httpsfails “no TailscaleVarRoot” (TLS handshake000even with-k, though TCP/ping succeed) when the secondtailscaledhas only--state=<file>— it has no var root for the LE cert; fix is--statedir=<dir>. Also: re-ingesting the same folder+name mustrmtreethe destination first or stale orphan section pages/images linger as ghost pages in nav/search; a bare mkdocs folder URL 404s by design (section pages have no folder index); the#split is on the ORIGINAL doc’s h1 count (few h1s → few coarse pages) - 2026-07-24-kickfix-ingest — markdownify silently drops
<img>inside<table>cells (old sites use tables for layout) →.unwrap()the layout containers first + rewritesrcto the copied basename in place; “see photo”<a href="X.jpg">text links are separate from inline<img>and were 365/664 broken → also walk<a href>, copy + rewrite existing images; URL-decode + resolve../cross-topic for bothsrcandhref; clean-regenerate each run - 2026-07-24-psu-load-resets — TWO distinct power problems: mains outage (router dies too → UPS) vs PSU-can’t-sustain-load resets (router stays up → serialize/bigger PSU, a UPS does nothing); the router-uptime cross-check is the discriminator (same dead-stop journal signature either way); the default 16-thread CPU embedding reset the box in 2–6 min,
OMP_NUM_THREADS=4+ serialize fixed it - shell-gotchas-pgrep-self-match —
pgrep -f/pkill -fmatch your own command line (worst over SSH, where the whole remote string is one argv): a completion monitor reported RUNNING 2.5 h after the job ended, and apkill -fkilled its own shell → exit 143 with the rest of the script silently skipped. Use PIDs, the[m]atchbracket trick, or a real artifact/sentinel - The CUDA driver mismatch — torch does not error on a too-new CUDA build, it falls back to CPU; and
pip install --index-url .../cu126is a silent no-op unless youpip uninstall -y torchfirst (the version constraint is already satisfied). Debian 13 PEP 668 also blocks barepip install→ plainpython3 -m venv - Since last handover (2026-07-24) — on OpenWrt/busybox use
setsid, notnohup(absent), to detach a self-reverting service swap (keep a persisted/overlaybinary backup + auto-revert so a bad swap can’t lock you out of the router); a hand-installed package (router tailscale 1.98.9) is out-of-band so opkg still records the old version and a futureopkg upgradecan clobber it - Gotchas — the nine that cost real time: Secure Boot vs the DKMS-signed NVIDIA module; TensorRT detector dead on amd64 in Frigate 0.17; YOLOv9 export broken by torch ≥2.6 (pin 2.5.1);
/cam1/and/cam2/are the same lens; Tapo silently truncates long passwords (and is Basic-auth only); Frigate’s DB lives at/config/frigate.db; birdseye draws no camera names; birdseye grid geometry follows the canvas aspect; iOS Private Relay vs MagicDNS
Linux Host Ops
- Host — Debian 13 bare metal; the installer ticks the desktop task by default (
systemctl set-default multi-user.target); all sleep/suspend/hibernate targets masked;getty@tty1disabled so mpv can own the TTY - The Windows drive — NTFS Windows C: mounted read-only via in-kernel
ntfs3at/mnt/win; RO because live Windows hibernation would corrupt RW; manual mount, not in fstab (won’t survive reboot); device node unstable →lsblk -f,UUID= - Mount procedure (verified 2026-07-21) —
modprobe ntfs3→mount -t ntfs3 -o ro <1.8T ntfs part> /mnt/win→docker restart filebrowser; proper fix is a systemd mount unit onUUID=orderedBefore=docker.service - 2026-07-23-mains-power-shutdowns — proving an overnight shutdown was external mains loss, not the host: the dead-stop journal signature (no
Stopping/panic/thermal), ruling out software poweroff (crontabs, poweroff/suspend timers,atq, rtc wakealarm, masked sleep targets) and thermal (grep -iE "thermal|mce|Xid"), and cross-checking the router’s boot epoch
Network Topology
- telep-router — br-lan
192.168.1.1/24, only10g-copperhas link; WAN is a DHCP client at192.168.254.2behind upstream192.168.254.1→ double-NAT - Camera VLAN (telep-cc) — third segment:
192.168.30.0/24, reachable from lan, reaches nothing - 2026-07-22-facekom-vpn-exit-node — a fourth segment reachable on demand: the FaceKom office LAN
192.168.105.0/24via theexit-vpncontainer’s OpenVPN tunnel (gateway92.119.122.32), re-exported to the tailnet - “VPN-only hosts” are a routing problem, not DNS — “VPN-only” FaceKom hosts (
npm.facekom.net) are public IPs behind an nginx source-IP ACL, identical DNS answers everywhere: 403 from home WAN, 200 from the VPN
OpenWrt Configuration
- telep-router — UCI-based config; hostname drift fixed 2026-07-13 (
uci set system.@system[0].hostname); 174 packages, essentially stock
Power & Reliability
- 2026-07-23-mains-power-shutdowns —
telep-mainframe’s recurring overnight shutdowns root-caused to brief mains power interruptions, confirmed by the telep-router (separate PSU) dying at the same instant; the PC only “stays off” because BIOSRestore on AC Power Loss= stay-off. Fix: ~600–900 VA UPS + NUT (logs sags, graceful shutdown); stopgap: flip the BIOS AC-loss policy (physical access only); also rule out an overloaded shared circuit - Host — all sleep/suspend/hibernate targets masked (relevant when ruling out a software-initiated poweroff)
- 2026-07-24-psu-load-resets — a SECOND, distinct power fault: the PSU can’t sustain peak combined i9-12900K + RTX 3080 draw and hard-resets the box under full load (~3× in 30 min); NOT thermal, NOT mains (the router stayed up 14h+); the default 16-thread CPU embedding was the reliable trigger; mitigate with a 4-thread cap + serialized jobs, real fix is a bigger PSU. A UPS does NOT fix this (it fixes mains, 2026-07-23-mains-power-shutdowns)
- 2026-07-24-luks-tpm-autounlock — the reboot-recovery follow-up: root was LUKS2 passphrase-only so an unattended reboot stalled at the unlock prompt (no dropbear-initramfs); clevis TPM2 auto-unlock now unseals the disk at boot. But auto-unlock only helps once the box BOOTS — the BIOS AC-loss flip is still the prerequisite; Debian stock initramfs ignores
systemd-cryptenrollTPM tokens (use clevis); reboot test PASSED in production (self-recovered through the 2026-07-24-psu-load-resets reboot storm) - 2026-07-24-psu-load-resets — the PSU-under-load resets, a SECOND power problem distinct from the mains outages; the router-uptime cross-check discriminates the two; a UPS fixes mains, NOT this — serialize heavy jobs / cap CPU threads / bigger PSU
- Since last handover (2026-07-24) — a daily ~06:00 mains die-off pattern (NEW, UNCONFIRMED): the box + router die together ~06:00 most mornings (Jul 19/23/24) = mains-level, suspect a scheduled utility relay (vezérelt/GEO tariff) or a timed high-draw appliance; confirm via
journalctl --list-bootsvs router reboots. Also: remote-wake (WOL) is NOT possible as configured (BIOS+NIC WOL off, no router wake tool, MAC unknown after lease expiry) → the real fix is BIOSRestore on AC Power Loss → Power On
Presence & Automation
- 2026-07-17-intruder-alarm — auto-arming alarm; presence = union of router WiFi association table (
iwinfo assoclist) +arp-scanonenp5s0; dormant until ≥1 trusted device, arms after all absent 10 min, disarms instantly on return; TV siren viaaplay -D plughw:1,3(NVIDIA HDMI = ALSA card 1 dev 3) - Device naming & enrollment — device names via mDNS
avahi-resolve→ dnsmasq reverse DNS →eszköz-<last4>; confirm-each enrollment over Telegram inline buttons - Untrusted input: LAN device names — reuses the alarm’s
~/alarm/trusted.jsonnames rather than inventing a second naming system; LAN-supplied names are an untrusted input path — ASS-escape and cap at 22 chars, and decode witherrors="replace"
Tailscale / Tailnet
- telep-router — Tailscale hand-upgraded 1.80.3 → 1.98.9 (static arm64 build; opkg still records
1.80.3-r1→ a futureopkg upgrademay clobber it, backup/overlay/ts-backup/), nftables mode,100.115.194.51; the workaround for having no public IP - Since last handover (2026-07-24) — router tailscale upgrade done out-of-band via a
setsid-detached self-reverting swap (busybox has nonohup); persist a binary backup on/overlay+ auto-revert so a bad swap can’t lock you out of the router - Access — Tailscale Serve as the TLS front door (needs HTTPS certs enabled in the tailnet admin console); persists across reboots
- Exposure — one
tailscale serveport per app ontelep-mainframe::443Frigate,:8443top4 picker,:8445Filestash - homelab — tailnet peer list and cross-project role
- 2026-07-23-frigate-viewer-alert —
tailscale servewrites the tailnet client IP into the proxied request’sX-Forwarded-For→ a100.xXFF in an nginx access line is a real human viewer,-is internal automation; map the IP → device name withtailscale status. The basis for identifying who opened the Frigate UI - 2026-07-24-knowledgebase — a separate tailnet identity on one host = a second
tailscaled(--tun=userspace-networking, own--socket/--statedir) thenup --hostname=+serve; givesknowledgebase.<tailnet>.ts.netas its own device without a container or GPU passthrough.serve --httpsneeds--statedirnot--state=<file>or it fails “no TailscaleVarRoot” (no var root for the LE cert; TLS000while TCP/ping succeed) - 2026-07-24-global-dashboard —
home.taild4189d.ts.net, a secondtag:telepnode using the same separate-tailscaled-identity pattern; the knowledgebase became its owntag:telepnode too - Tailscale exit node —
exit-vpn/100.98.208.98advertises an exit node +192.168.105.0/24subnet route (two separate admin-console checkboxes); off by default,tailscale set --exit-node=exit-vpnto use; exit nodes do not carry RFC1918 traffic; full-tunnel route changes strandtailscaledoffline → oneshot unit restarts it after the tunnel
VPN
- 2026-07-22-facekom-vpn-exit-node — FaceKom “VirtualOffice” OpenVPN on the
exit-vpnIncus container:tcp-clientto92.119.122.32:1194, AES-256-CBC/SHA1, full tunnel viaredirect-gateway def1, persistent throughopenvpn-client@farm(symlink into/etc/openvpn/client/— thett/subdir isn’t scanned andopenvpn.serviceis a/bin/truestub) - Three root causes (all previously misdiagnosed) — the “bad CA” that stalled this for weeks was really a wrong
remoteIP; plus wrong ciphers and a label-corrupted password file - SESSION-HANDOVER — one-screen current state in the
exit-vpn containersection
WiFi
- telep-router — SSID
telep1on both radios; radio0 5 GHz ch36 HE80, radio1 2.4 GHz ch1 HE20 - Camera VLAN (telep-cc) — hidden SSID, WPA2-PSK forced (Tapo has no WPA3-SAE), client isolation on; hidden-SSID rejoin tested and works
- Presence detection — AP map used for presence:
telep1=phy0-ap0(5 GHz) +phy1-ap0(2.4 GHz);telep-cccamera SSID =phy1-ap1(excluded) - 2026-07-22-wifi-usage-strip — same
telep1AP map for per-station byte counters (iw dev <ap> station dump);telep-ccexcluded by construction, never referenced at all