Compare commits

..

25 Commits

Author SHA1 Message Date
kitadmin 30953399b6 fix: null gateway latency; skip aiwanbal generic modem_type for carrier detection
- Gateway ping latency is LAN RTT (<1ms), not WAN latency; set to null so
  dashboards don't show misleading sub-ms values for Eyeride-NAT'd interfaces
- aiwanbal reports modem_type=generic for wired ISP ports; treat same as none
  so carrier detection falls through to gateway IP pattern matching (AT&T etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:48:32 +00:00
kitadmin 088c256f58 fix: ping local gateway instead of curl when ICMP gives 100% loss
curl --interface fails for root on Synology due to policy routing. Pinging the
local gateway (e.g. Eyeride at 192.168.10.1) works reliably and confirms the
WAN path is up even when internet ICMP is NAT-blocked.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:38:03 +00:00
kitadmin bbbc873bdb fix: HTTP fallback probe when ICMP reports 100% loss (Eyeride NAT blocks ICMP)
Eyeride 5G device passes HTTP traffic but drops ICMP, causing false 100% loss.
When ping gives 100% loss, try curl --interface to confirm connectivity; if
HTTP probe succeeds, correct loss to 0% and derive latency from connect time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:31:47 +00:00
kitadmin 8f2d6a7cbd fix: sanitize _mtime with tr to prevent ash arithmetic crash on Synology
stat output can include non-numeric chars on some RT2600ac firmware versions,
causing 0 to fail. Strip with tr -cd '0-9' before arithmetic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:29:10 +00:00
kitadmin a4ba9f8fcd fix: ash-compatible arithmetic in _cached_speedtest; clean up speedtest null guards
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:26:04 +00:00
kitadmin 8ea704f7e3 fix: use ingest HTTP API instead of direct Postgres for VPS telemetry; cache speedtest results per interface
- hub/server.py: replace psycopg2 Postgres connection with urllib HTTP call to
  ingest /api/devices endpoint (fleet Postgres is Docker-internal, not reachable
  from the VPS directly)
- telemetry-synology.sh: run_speedtest() now writes per-interface cache files
  (speedtest-result-<iface>); _cached_speedtest() reads cache if < 35 min old;
  _collect_wan() uses cached result so throughput shows in telemetry without
  blocking every 1-min cycle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 03:06:08 +00:00
kitadmin 8a648dc637 feat: smart WAN role detection, aiwanbal integration, speedtest support
- Auto-detect cellular vs fiber/Starlink regardless of physical port:
  aiwanbal modem_type → Eyeride subnet (192.168.10.x) → gateway patterns
- Integrate aiwanbal/SmartAiBalancer state as primary data source when
  available (fresh <120s); fall back to self-collected ping metrics
- Add carrier detection: AT&T for fiber gateways, Eyeride for cellular
- Add run_speedtest() with speedtest-cli/iperf3/curl download fallback
- Extract jitter (mdev) from ping output for richer metrics
- Consistent canonical GL format: modem_0001=cellular, wan=ethernet/fiber

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 02:29:49 +00:00
kitadmin 8dba04a1d0 fix: auto-detect WAN roles — cellular vs fiber
- Detect Eyeride cellular interface by checking 192.168.10.x subnet
- Map correctly: ethernet/fiber → wan, Eyeride 5G → modem_0001
- Add carrier detection: AT&T for fiber gateways, Eyeride for cellular
- Fix sel_primary: fiber is active by default unless cellular route exists
- Fixes console showing 'on cellular' when actually on AT&T fiber

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 02:19:18 +00:00
kitadmin 58ac96fd3c fix: prevent double-ping fallback corrupting WAN metrics
- sudo ping returns exit 1 on any packet loss, which triggered the
  || fallback to direct ping, causing duplicate output concatenation
- Now check exit code explicitly: only fall back on exit >= 2 (real error)
- Fixes loss_pct showing 100100 instead of 100 on failed WANs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 02:10:35 +00:00
kitadmin 91373df27d fix: sanitize newlines in telemetry output for valid JSON
- ipgeo_gps: pipe curl output through tr -d to strip newlines
- _ping_iface: pipe printf output through tr -d for newline safety

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 01:57:56 +00:00
kitadmin db04341f7c feat: unified fleet telemetry — canonical format, GPS/IP geo, WAN health dashboard
- Rewrite telemetry-synology.sh: canonical GL format (modem_0001/wan keys),
  self-contained metrics (no aiwanbal), Eyeride GPS with IP geo fallback
- Add /api/fleet-telemetry to hub: joins tunnel status with fleet Postgres
- Update dashboard.html: per-device WAN health bars, GPS, signal strength
- Fix hub/ingest.sh normalisation: remap old wan1/wan2 → modem_0001/wan
- Bump SPK version: 0.1-0001 → 0.5.0-0001 for GL parity

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 01:47:02 +00:00
kitadmin d86a7e49b5 feat: BusyBox-compatible telemetry script for Synology
Uses sed instead of grep -P for BusyBox ash compatibility.
Writes JSON to temp file to avoid shell escaping issues.
Posts to fleet hub ingest at 167.172.237.162:8080.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 23:13:57 +00:00
kitadmin 879f97c843 fix: x4078 remote recovery + daemon wait-wedge bug + SPK rebuild
- docs/incident-log: mark x4078 recovered remotely via Tailscale (no
  physical access needed); document the recovery steps and root cause
- connect-daemon.sh: remove bare `wait` that wedged the retry loop
  forever on the setsid'd tailscaled child — once the tunnel failed the
  daemon could not self-heal until the package was restarted; now the
  main loop falls through start_tunnel (already blocking+retrying) and
  restarts the whole cycle cleanly
- SPK rebuilt (32839680 bytes) with the daemon fix included
- Also documents the two latent lessons: (1) a field router is only
  inaccessible when ALL three paths fail; (2) always check Tailscale +
  QuickConnect before assuming a truck roll is required

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 22:23:53 +00:00
kitadmin 24d8fbd366 fix: revert TUNNEL_LOCAL_SSH_PORT to 2223, fix registry, add incident docs
- wizard.sh + connect.conf: TUNNEL_LOCAL_SSH_PORT back to 2223 (Synology SSH port)
- port-registry: renamed x6340 → x4662 (matches QuickConnect ID)
- port-registry: added MR2200ac mesh satellite note for x4662
- deployment checklist: added kit-connect section, post-deployment rules,
  incident log, and complete fleet port registry table
- memory: added fleet-router-inventory.md with full fleet state
- hub README: updated with current status and locations

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:20:08 +00:00
kitadmin 44566d9563 chore: add built kit-connect SPK for direct download
Includes fixes: which-vs-command-v for SRM busybox compat,
TUNNEL_LOCAL_SSH_PORT default 22, merged authorized_keys.
32MB SPK for Synology RT2600ac/RT6600ax (ipq806x).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 20:22:18 +00:00
kitadmin c8bb08ed35 feat: fleet hub dashboard + /api/fleet endpoint with direct access links
server.py:
- GET / serves dashboard.html (dark-themed fleet console)
- GET /api/fleet returns all registered devices with tunnel status,
  SSH commands, and web dashboard access instructions
- Static file serving via serve_file()

dashboard.html:
- Shows all registered devices from port-registry.json
- Live tunnel status (port-open check on VPS)
- Platform badges (Synology vs GL-XE3000)
- Copy-to-clipboard SSH commands per device
- Web dashboard access via SSH port-forwarding instructions
- Auto-refreshes every 15s

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 16:11:10 +00:00
kitadmin 68306dcb14 fix: use -x file test instead of command -v for tailscale binaries
SRM default PATH is /usr/bin:/bin:/usr/sbin:/sbin:/usr/syno/bin — /usr/local/bin
is NOT included. 'command -v /usr/local/bin/tailscaled' fails on busybox ash
even when the file exists and is executable. Replaced with '[ ! -x "$BIN" ]'
which is always reliable for absolute paths.

Found during x5925 deployment testing. Daemon logged 'binary not found' despite
the files being present at /usr/local/bin/tailscale[d].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 14:01:39 +00:00
kitadmin 8bd157b0de fix: GL wizard indentation + balancer depends on kit-connect
- GL connect-wizard.sh: fixed key authorization block indentation (was at 3 tabs instead of 2)
- GL kit-busrouter Makefile: added +kit-connect to DEPENDS so installing the balancer auto-pulls connectivity

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 13:10:16 +00:00
kitadmin 34f8074ee7 fix: audit gaps — GL local keyword, key authorization in wizards, register script parity
GL daemon: removed remaining 'local ts_ip' (busybox ash compat)
Synology wizard: auto-authorizes tunnel key via POST /api/authorize-key
GL wizard: same key authorization flow added
Synology: added connect-register.sh for parity with GL
syno-balance build.sh: removed deprecated checksum file (same lesson as kit-connect)

All four curl hubs (wizards + register scripts) now have --max-time 15.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 04:20:40 +00:00
kitadmin 14d46d96a4 fix: daemon hang, postinst mkdir, hub key authorization, boot persistence
SPK daemon fixes (x5925 testing feedback):
- register_with_hub: added --max-time 15 to prevent indefinite hang
- Removed bash 'local' keyword for busybox ash compatibility
- postinst: mkdir -p /usr/local/bin before copying Tailscale binaries
- postinst: chmod +x all bin/*.sh (fixes 644 execute bit bug)
- Added x5925-boot.sh for reboot persistence (stopgap until daemon fixed)

Hub security hardening:
- Added POST /api/authorize-key endpoint with device_id + pubkey
- Keys auto-authorized with restrict,port-forwarding,permitlisten="<port>"
- No shell access allowed — only tunnel forwarding to assigned port
- Server.py updated with input validation on key format
- register.sh --authorize-key subcommand for secure key management

GL daemon: same --max-time fix applied for curl timeout

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 04:09:49 +00:00
kitadmin de871acce9 fix: bundle Tailscale ARM binaries + fix execute bits in SPK
- Bundled tailscale 1.98.9 + tailscaled ARMv7 (ELF 32-bit, statically linked)
- Fixed connect-daemon.sh 644 → 755 (was preventing daemon from starting)
- Postinst now chmod +x all bin/*.sh and bundled binaries
- Postinst copies tailscale/tailscaled to /usr/local/bin if not present
- Hub firewall: opened ports 8080 (API) and 2230-2299 (SSH tunnels)
- Hub systemd service restarted after firewall fix

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 03:19:04 +00:00
kitadmin 52e7e478e4 feat: GL kit-connect ipk + one-button wizard + web dashboard for both platforms
Synology kit-connect (SPK):
- wizard.sh — one-button Keylink IT fleet setup (auto-runs on install)
- www/index.html — dark-themed local dashboard (same design as busrouter)
- bin/serve-dashboard.sh — busybox httpd on port 8089 with CGI endpoints
- start-stop-status updated to manage dashboard alongside daemon
- INFO updated: RT2600ac + RT6600ax compatibility noted
- postinst now runs wizard --auto for first-time setup

GL kit-connect (OpenWrt ipk):
- Makefile — DEPENDS: +curl +openssh-client +tailscale
- procd init — USE_PROCD=1, respawn with 5s delay
- connect-daemon.sh — Tailscale + reverse SSH (same as Synology version)
- connect-wizard.sh — one-button setup, idempotent, UCI config
- connect-register.sh — standalone hub registration
- www/kitconnect/index.html — dark-themed dashboard with wizard button
- www/kitconnect/wizard.cgi — web-triggered wizard endpoint
- UCI config at /etc/config/kitconnect

Both platforms share: same hub protocol, same Tailscale key, same port pool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 03:10:32 +00:00
kitadmin 0c68fb2461 feat: kit-connect + syno-balance SPK builds, busfleet hub registration endpoint
- kit-connect SPK (ipq806x): postinst with hub registration, start-stop-status,
  connect-daemon management, Tailscale + reverse SSH tunnel integration
- syno-balance SPK (noarch, test build): SmartWAN-aware dual-WAN load
  balancer with 6-factor scoring engine, syno-daemon lifecycle
- Busfleet hub: register.sh (port pool 2230-2299), Python HTTP server,
  systemd service, port-registry.json with x4078/x5925 assignments
- .gitignore: exclude SSH keys (*_id_ed25519), SPK artifacts (*.spk)

Gitea releases:
- kit-connect v0.1-0001 → x5925-kit-connect-v1 (production)
- syno-balance v0.1-0001 → syno-balance-test-v1 (prerelease)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 00:55:32 +00:00
kitadmin f207c09920 docs: v1.2 — security hardening + traffic control for deployment checklist
Adds sections 2b (Safe Access) and 2c (Traffic Control):
- Disable WPS, login page title = DEVICE_ID
- Synology Account sign-in for QuickConnect relay
- Google Safe Browsing via API key, Threat Intelligence DB
- DoS protection enabled, NO DoH servers
- Traffic Control: per-client 80% cap, auto-speedtest on new WAN
- Update preflight memory with all security requirements

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 00:34:29 +00:00
kitadmin 1005269239 feat: weekly config backup + unified telemetry schema + fleet dashboard
- scripts/backup-config.sh: weekly router config backup to hub (SRM + OpenWrt)
  Runs via cron, exports platform-specific config, POSTs to /api/backup
  Keeps last 10 backups per device on hub

- hub/ingest.sh: fleet hub telemetry normalizer + backup receiver
  Normalises GL (openwrt) and Synology telemetry into single schema
  Adds platform field to GL telemetry for unified dashboard

- hub/dashboard.html: single-pane fleet console
  Shows all routers (GL + Synology) with scores, WAN state, GPS, uptime
  Auto-refreshes every 10s from /api/status endpoint

- 62-point checklist updated with weekly backup section 9b

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 00:18:27 +00:00
224 changed files with 4106 additions and 261 deletions
+1
View File
@@ -0,0 +1 @@
{"sessionId":"a109bdc4-2fd1-49a3-803f-c3c3b4858c99","pid":3141099,"procStart":"375768368","acquiredAt":1784001797642}
@@ -0,0 +1,2 @@
x¥’_OÛ0Å÷œOq±˜(ÚÒ$‚í)h
R¥2¡6Û BVÚÜ.V
@@ -0,0 +1,3 @@
x‘ËnÛ@ E»ÖWÜE6”ÚÖkd9mQ7)QÂÚ ó "ÁÒŒª!ñßw MÖåŽä½Ä!)Í0tY}p$㉊“8I ÑÈ‚1Ê ¡R’‘o™mrÁ‹¦Éƒ‘O¤ØÖw“DåÉF0•SœJƔܲ´ˆYá
‰hD¢XÀgך û¾'R>´\ã3¿dßNtî;}êÜJšá+¢|i¶IS„¯zFGÿçÄl'3{û·'d«(ÌV1žŽᨧÜtÆÓáXá¥s-ÄÜ44­§K9>½iV¶Ýáy´uÓ½b±¯Âß~ÈãáîK¼¼ySÕÒø½¤Ãâçñð ÖqGhºžìò&À;Ýh¬[×M?Ûvý£¶¤Õ•Cu÷
£ÑÎʼh×
@@ -0,0 +1,2 @@
x²▌1nц0 E;Кэ"-≥TQИ■)[/@K4bь√WzШ:WхъчПС╤╝S
Ьжv3И)▄Х┴╓0&
@@ -0,0 +1,2 @@
xŽ;nÃ0D]óÛ0(rù3ŒÀ©R¥óVË%,H¢…)|{3WÈtóðÞÖuj`p8µCuEbò)S±â9C]ô±ƒµAµÓ!µA.˜\²Áø<æ"ztK×3
f¶FLzPôÛžÛŸË"¾ùëInô×î³¼–©ÎS»ð¶~À¢I¼pÖ=ªÓþ±ÉÿÖj_¨^a¥c†ýÌ/ä­ŠzÑ#LŠ
@@ -0,0 +1,3 @@
x};0ù¤³1ª$nº¸øJ`7
4bÛ´÷ÆÃ·a±CÓœóûhÞª<¤kºøaHJa›#‡ %»Ð‹NV¹ƒ%½59Ϋ ëëá¥ËE«hÙGP 1\Bûžk-ï‘n I©^²ò‘5FaÝh„ƒöÆZõ_+}²>1à²xŸça…Àj>îäch½@.×{ºÏR2ŽlÈÄ“»ÇS_|!'›˜ÒdMg
”h˜ÿÒhØÊÝ]Ð_ùc
@@ -0,0 +1,3 @@
xťŹÁNä0 †÷ܧřOhŃ2¨iÚÎĐ
¸ěi/\Ń’ÔŮF“¦Uś€Fw'x|ňoű·?ež]BW÷?R$ÂĐ!¬>ŘFŽ]×R'{Ó´µPÝa¬{­MOµäP­*RH{a„´¶¤ŃŇĘúAěűZ7µmmßÚşé›ao*•Ó´DÜyOÍźIܨwu{¤“wáčŇĄYćßűC3´ť~Ő%ŞR-ډľç®tć¸äbżB"O3Ąxşä Ć“
yeěŔĘ8©D;ë<!ůš‚™đDŃYGcUíđ@«W†đ˛Ť\ăĎ.MxÄÎ~Č8;ŰFľúiçuŤÄ\<‘÷xV1¸đź±ĚŽąäŰĆOU( RH×?uXźÎ Íý;߬r>G‚ÎÖRd”[Łăă¬ĎeĂHŢ•*ŚŰÓ%-§¬ aĘ1Toq§n
@@ -0,0 +1 @@
xŽAjÃ0E»Ö)f0òH²¬RB®ºëÆ£llËÁQ¹}Ü+ôo>ïÃÏÛºNº‹€%õCÌ:8ÙEQç]VßöQضˆÒ%ÅÁYs§]J…¾sž¬Ud
@@ -0,0 +1,4 @@
xŽAjÃ0E»Ö)fÒXòH!”
]e× ŒFcblËÁQ¹}Ý+äo>ïÃ/벌
¶©BJ¢¡d‹ÒGÒeè˜óà|Áœ V
±ÅÜyÓÚ€„<†0ÆÜÇΫƂ=e$0u„ÒÙèÊ`øÙnë—yÖ

Some files were not shown because too many files have changed in this diff Show More