Commit Graph

215 Commits

Author SHA1 Message Date
da09fa6987 fix(live-usb): mask sentinelle-gsm + fmrelay; cap their restart storm
Both modules need physical hardware (RTL-SDR, EP06 modem) and crash
on `import gr_osmosdr` when those aren't there. On the live USB
amd64 build neither is present, so the service died at startup,
systemd restarted in 5s under `Restart=on-failure`, and the cycle
repeated until /var/log filled with hundreds of FAILED lines —
visible on the boot console and blocking the kiosk target from
ever finishing.

Two fixes layered:

1. systemd unit (sentinelle-gsm.service): add StartLimitIntervalSec=30
   + StartLimitBurst=3 + StartLimitAction=none. If start fails 3
   times in 30 s, give up instead of looping forever. The kiosk's
   multi-user.target settles even when the SDR is missing.

2. build-live-usb.sh: mask secubox-sentinelle-gsm + secubox-fmrelay
   in the INCOMPLETE_MODULES list alongside other hardware-gated
   modules. Operators enable + unmask by hand once they wire the
   physical RTL-SDR / GSM modem.

Operator quick fix on an already-flashed live USB:

  sudo systemctl stop secubox-sentinelle-gsm
  sudo systemctl mask secubox-sentinelle-gsm
  sudo systemctl mask secubox-fmrelay
  sudo systemctl daemon-reload

Then `secubox-kiosk-setup enable --x11` should complete normally.
2026-05-25 06:33:45 +02:00
e1a532975b fix(live-usb): harden GRUB EFI build — fail-fast + Secure Boot shim
v2.12.1 booted in VBox dropped to the EFI Shell PXE prompt: BOOTX64.EFI
was built but the module set lacked `disk` / `usb` / `usbms` so OVMF
couldn't hand off block IO once GRUB took over. Same image worked in
BIOS mode — the i386-pc grub didn't need those modules.

Hardening:

* GRUB_MODS now includes `disk usb usbms ahci ata` + `loadenv` +
  `gfxterm_background gzio png jpeg font sleep reboot halt true exfat
  iso9660 ntfs search_fs_uuid search_fs_file` — the full toolbox a
  USB / VM EFI handoff needs.

* `grub-mkimage` failure aborts the build instead of warning. The
  embed-cfg's `search` chain falls back through label-ESP →
  label-LIVE → `$cmdpath/../../boot/grub` so the bootloader still
  finds the menu when the partition label was lost (some flashers
  rewrite it).

* `--compress=xz` on the EFI binary shaves ~40% off its size.

* Secure Boot: if `shimx64.efi.signed` + `grubx64.efi.signed` are
  available on the builder (they're already installed by CI line 108),
  ship the Microsoft-trusted shim AS BOOTX64.EFI and the signed grub
  alongside. Falls through to plain unsigned grub when those packages
  are missing locally, with a noisy warn explaining how to install
  them.

* `grub-install --target=i386-pc` failures now propagate via err
  instead of warn — silent BIOS install failure was the v2.10.x
  "boots into nothing" footgun.

* Mirror BOOTX64.EFI to /EFI/secubox/grubx64.efi so a later
  `efibootmgr -c` can register a named entry without clobbering
  /EFI/BOOT.

* Local apt-get install adds `grub-efi-amd64-signed` + `shim-signed`
  so dev-host builds get the same Secure Boot output as CI.
2026-05-24 15:53:20 +02:00
27645f0a1b fix(live-usb): IP static fallback + kiosk firstboot safety net for x64 live
Two bugs surfaced on the v2.12.0 amd64 live USB build (user-tested on
both VirtualBox + bare-metal amd64 2026-05-24):

1. **IP**: the static fallback added to board/x64-live/netplan/
   00-secubox.yaml in commit 264e23e4 never reached the booted image
   because image/build-live-usb.sh writes its OWN inline netplan
   template (line 782, here-doc) that's a copy of the board file
   without the static block. Both DHCP-only matches `en*` and `eth*`
   now also carry `addresses: [192.168.1.55/24]` + gw 192.168.1.254 +
   nameservers, with a high route metric (1000) so DHCP still wins
   when available — but the appliance stays reachable on .55 when it
   doesn't (the original #370 intent).

2. **Kiosk**: build-live-usb.sh touches /var/lib/secubox/.kiosk-
   enabled + symlinks secubox-kiosk.service into multi-user.target.
   wants at build time, but operators reported having to run
   `secubox-kiosk-setup enable` manually on first boot. Suspected
   cause is a live-boot persistence layer that masks parts of /var,
   needs more digging. As a safety net firstboot.sh now invokes
   `secubox-kiosk-setup enable --x11` whenever it can't find the
   sentinel — idempotent, no-op on a working image, recovers a
   broken one without needing console intervention.
2026-05-24 11:09:33 +02:00
CyberMind
b6923cd051
fix(image): replace emojis in /etc/issue with VT102-safe ASCII tags (#339)
Symptom: pre-login banner on ttyS0 (Minicom 2.9 VT102) rendered as
trailing `�` after every emoji line. The console driver couldn't
decode the UTF-8 multi-byte sequences for  🔐 🌐 📡 and emitted the
replacement character instead.

The `█` box-block characters (U+2588) DO render correctly in VT102+
UTF-8 — they're a single-byte-class glyph in most modern fonts. We
keep those so the SECUBOX wordmart still looks like SecuBox.

Replacements (compatible with VT102 minicom AND SSH UTF-8 alike):
     ->  >>
  🔐   ->  [user]
  🌐   ->  [web]
  📡   ->  [ssh]

The /etc/motd block (shown after SSH login) is left untouched — SSH
sessions have proper UTF-8 terminals so the rich emojis are fine
there.

Also add scripts/build-kernel-local.sh (new): the local kernel build
script that I authored today for #255. Documented; runs the same
defconfig + merge_config + scripts/config + olddefconfig + sed ZRAM
override + bindeb-pkg flow as .github/workflows/build-kernel.yml,
without the 20-min GitHub Actions ping-pong.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-22 10:07:15 +02:00
CyberMind
e2df52ae16
fix(build-live-usb): default --iface to en*, skip net-detect when static netplan is baked (closes #128) (#330)
Two regressions on a --static-ip image:

1. Default match `name: "eth0"` matched nothing on modern Debian. The
   booted kiosk ended up on `enp0s31f6` with link-local 169.254.x.x
   because the static stanza was inert.
   Fix: default STATIC_IFACE="en*" (covers enp*/eno*/ens*/enx*).

2. firstboot.sh ran `secubox-net-detect apply router` unconditionally
   if the binary was present, even though build-live-usb.sh's
   --static-ip branch pre-touches /var/lib/secubox/.net-configured to
   short-circuit the systemd unit. That re-injected the router-mode
   bootstrap (WAN + br-lan 192.168.1.1/24), colliding with the user's
   gateway.
   Fix: gate the firstboot net-detect block on the marker file.

Also clarify --help wording about glob semantics.

Closes #128.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-22 07:09:41 +02:00
CyberMind
0b7a25f179
fix(splash): single ROOT-green SECUBOX banner per charter (closes #314) (#315)
* image/splash/tui-splash.sh: collapse alternating G1/G2 per-letter
  coloring to a single ROOT-green (ANSI 29 ~ Charte #0A5840) across
  the whole SECUBOX word.
* image/build-image.sh + image/build-live-usb.sh: pre-login /etc/issue
  banner switched from 256-color orange (38;5;214) to ROOT green
  (38;5;29). Post-login MOTD untouched (it keeps cyan-on-orange-frame
  for contrast on console).

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-21 11:12:56 +02:00
CyberMind
f300b632e4
fix(image): install flash/TUI tools + kiosk-tui alias on all images (closes #228) (#229)
Three operator tools and one discoverable alias were missing from the
shipped images:

- `secubox-flash-disk` and `secubox-flash-emmc` — internal disk/eMMC
  flashing from a running system. Both exist in `image/sbin/` but only
  flash-disk was installed by build-live-usb.sh (and neither by
  build-image.sh).
- `secubox-console-tui` and `secubox-factory-reset` — console-side
  dashboard + factory-reset. Live image installed them; the system
  image didn't.
- `secubox-kiosk-tui` — operator-expected discovery name for the
  kiosk-mode fallback TUI. Now ships as a symlink to
  `secubox-console-tui` (matches the `kiosk` operating mode in
  `secubox-mode`).

build-image.sh now installs all four tools + the symlink for every
board (mochabin/espressobin/vm-* — eMMC flashing is just as relevant
on arm64 SBCs as on x86_64).

build-live-usb.sh extends its existing first install loop with
`secubox-flash-emmc` and adds the same `secubox-kiosk-tui` symlink.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-20 06:45:06 +02:00
CyberMind
5b11e51698
fix(image): silence Pi-only services on x64 + broaden X11 driver set (closes #226) (#227)
Bare-metal x86_64 validation of v2.10.1 surfaced two ergonomic issues:

1) Three Pi-hardware services [FAILED] in a tight loop on x86_64:
   secubox-healthbump (I2C), secubox-led-trigger (LEDs), secubox-picobrew
   (1-Wire fermentation sensors). The boot console got flooded with
   restart attempts until systemd's StartLimit kicked in. The sibling
   `secubox-led-heartbeat.service` already uses ConditionPathExists to
   skip silently — apply the same pattern.

   Use `ConditionArchitecture=arm64` since all Pi/MOCHAbin/ESPRESSObin
   targets are arm64. systemd skips the unit with a "condition failed"
   line in journal but no [FAILED] noise on the console.

2) image/build-image.sh:606-607 installed only xserver-xorg-video-fbdev,
   leaving modern Intel/AMD/Nvidia bare-metal at the 30-90s X11 cold-init
   fallback path. Expand the install line to xorg's standard set:
   fbdev, vesa, intel, amdgpu, radeon, nouveau, qxl, vmware. ~15 MB
   extra; KMS modesetting picks the right one at boot for both bare-metal
   and VM targets.

Validated path: VBox amd64 kiosk still loads in ~5s (vmware/qxl drivers
present). Bare-metal x86_64 USB boot should hit X11 init under 15s,
boot console no longer shows recurring healthbump/led-trigger/picobrew
[FAILED] lines.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-19 14:38:20 +02:00
CyberMind
e0e3a335d4
fix(kiosk): always pass --no-sandbox on Debian 12 AppArmor (closes #224) (#225)
On bare-metal x86_64 with the v2.10.0 image, chromium's zygote crashes
in a restart loop:

  ERROR:content/browser/zygote_host/zygote_host_impl_linux.cc(...):
  ... disabled unprivileged user namespaces with AppArmor,
  ... you can try using --no-sandbox.

Debian 12 ships AppArmor with the `unprivileged_userns` profile that
restricts the unprivileged user namespace creation chromium's zygote
needs to set up its renderer sandbox. The kernel sysctl
`kernel.unprivileged_userns_clone` is `1`, but the AppArmor profile
whitelists only known binaries — chromium launched as the
`secubox-kiosk` user doesn't match.

`secubox-kiosk-launcher:443-451` only passed `--no-sandbox` for VM
targets (`systemd-detect-virt` non-`none`). On bare metal it omitted
the flag, so the zygote died on every launch → systemd restart loop
until MAX_FAILURES=3 disabled the kiosk and left X11 stranded on VT7.

Drop `--no-sandbox` from both branches. The SecuBox kiosk runs as a
dedicated unprivileged user on a single VT, AppArmor still enforces
its per-process chromium profile, and the appliance sits behind its
own WAF — chromium's internal sandbox provides marginal additional
security here while breaking the kiosk entirely.

Validated path: VBox kiosk continues to work; bare-metal x86_64 will
reach the SecuBox login form after this fix.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-19 13:16:51 +02:00
CyberMind
081d058d86
fix(image): pull Debian deps for slipstreamed packages (#218) (#219)
* fix(image): pull Debian deps for slipstreamed packages (closes #218)

dpkg -i --force-depends in the slipstream step left python3-argon2,
python3-pyotp, python3-qrcode, python3-jsonschema, python3-jose,
python3-cryptography, python3-maxminddb and ~8 other declared deps
uninstalled. firstboot.sh then crashed on `from argon2 import
PasswordHasher`, users.json was never created, secubox-portal failed
to start, and the kiosk fell into a /portal/login.html redirect loop
on every fresh image.

Two-step fix in build-image.sh:
  1. Pre-install the auth/crypto/observability deps via INCLUDE_PKGS
     so they exist before any .deb is unpacked.
  2. After `dpkg -i --force-depends`, run `apt-get install -f -y` to
     resolve whatever else the slipstreamed packages declared. The
     misleading "pip provides Python deps" comment is replaced.

Validated against amd64 CI run 26079813517 (commit 53a630e9) where
the redirect loop was observable in the VBox kiosk and the boot
journal showed secubox-firstboot.service / secubox-portal.service
FAILED.

* fix(image): drop kernel-touching deps from INCLUDE_PKGS (ref #218)

CI run 26081463597 failed: python3-zmq postinst aborts in debootstrap
second-stage (touches kernel/devfs before the rootfs is mountable).

Trim INCLUDE_PKGS to bootstrap-critical only: keep python3-argon2 (used
by firstboot.sh before any service starts) and rely on the new
`apt-get install -f -y` step to pull the long tail (python3-zmq,
pyroute2, evdev, serial, jose, cryptography, maxminddb, websockets,
qrcode, pyotp, jsonschema, rich) once /proc and /sys are real.

apt-get install -f remains the real fix from the previous commit —
this commit only narrows what's pre-staged at debootstrap time.

* fix(image): no C-extension Python pkgs in INCLUDE_PKGS (ref #218)

CI run 26081721762 still failed: python3-argon2 also breaks debootstrap
second-stage. Same root cause as python3-zmq — any Python package with
a compiled C extension fails to configure in the second-stage chroot
where /proc and /sys aren't fully set up yet.

Revert all new INCLUDE_PKGS entries from this branch. The first commit
(apt-get install -f -y after dpkg -i) is the real and sufficient fix —
once /proc and /sys are real, apt happily resolves every secubox-*.deb
declared dep including argon2, jose, cryptography, maxminddb, zmq, etc.

---------

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-19 11:44:40 +02:00
CyberMind
2a015569c1
fix(firstboot): users.json v2 schema + argon2 (closes #210) (#211)
Fresh images had admin / secubox login always failing because
image/firstboot.sh wrote users.json with:

  - Flat schema {"admin": {...}} instead of v2 {"users": [{...}]}
    that secubox_core.user_store expects.
  - SHA256 hash instead of argon2 that verify_password uses.
  - And no /etc/secubox/auth.toml so the fallback path was also dead.

End result: locked out of every fresh image at the web UI; only root /
secubox shell login worked (unrelated chpasswd path earlier in firstboot).

Fix: replace the broken sha256sum + flat-dict heredoc with an inline
Python that uses argon2.PasswordHasher (already a secubox-core dep) and
writes the v2 schema directly. must_change_password is true so the very
first successful login is gated on a real password change — bypassing
password_policy.validate() (which would reject "secubox" as too weak)
is acceptable for the seed because the next interaction forces the upgrade.

Verified roundtrip locally:
  ph.hash("secubox") -> argon2id$v=19$...
  ph.verify(h, "secubox") -> True

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 07:42:35 +02:00
382b4cb7dc fix(image): build-mochabin-live-usb.sh accepts --slipstream (no-op match w/ other live-USB scripts)
Some checks failed
License Headers / check (push) Failing after 6s
build-all-live-usb.yml workflow passes `--slipstream` to every live-USB
build script when there are .deb files in output/debs/, but
build-mochabin-live-usb.sh only knew `--no-slipstream` (with slipstream
ON by default). The workflow's `--slipstream` therefore hit the `*) err
\"Unknown argument: \$1\"` branch and the job failed after ~50 min of
chroot setup — which is why mochabin live-USB was missing from v2.9.0
while x64 + rpi400 shipped fine (their scripts already accept both
forms).

This adds the no-op match, identical to what build-live-usb.sh and
build-rpi-usb.sh do at the same place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 05:35:52 +02:00
d177662c52 fix(image): isolate chroot /dev + VBox guest additions (ref #124 #125)
#124 — Don't bind-mount the host's /dev into the chroot.

The previous `mount --bind /dev "${ROOTFS}/dev"` exposed the host's
/dev to every chroot process. A killed build mid-debootstrap can
leave the host's /dev with regular files in place of device nodes,
or wipe entries the kernel can't auto-recreate. Effect today: every
shell on the host failed with `/bin/bash: /dev/null: Permission denied`
because bash startup uses `2>/dev/null`. Full recovery required
manual `mknod` for each missing node — there is no undo for damaged
devtmpfs without a reboot.

Switch to an isolated tmpfs at "${ROOTFS}/dev" with manually-created
minimal device nodes (null, zero, full, random, urandom, tty,
console, ptmx) + symlinks for stdin/stdout/stderr/fd. Chroot ops
can no longer reach host device nodes.

Additional safety nets:
- Startup sanity check: refuses to run if host /dev/null is not a
  character device (with the exact recovery command in the error).
- Cleanup fallback: if /dev/null is missing/corrupted at exit
  (despite isolation), recreate it.
- Trap extended to INT and TERM, not just EXIT.

#125 — VBox guest additions actually install now.

contrib is enabled in the chroot's sources.list at step 3 (already
on master), but the install at step 6 was silenced with `2>/dev/null`,
hiding any real failure. Remove the swallow, refresh apt indices
before the install, and emit a structured OK / WARN line so we know
exactly what happened.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:31:42 +02:00
800c858f85 feat(image): --static-ip + --hostname flags for build-live-usb.sh (ref #122)
When --static-ip CIDR is set:
- Replaces the bootstrap DHCP netplan with a fixed-IP config on the
  interface chosen by --iface (default: eth0)
- Honors --gateway (required), --dns (default: gateway, comma list ok)
- Pre-touches /var/lib/secubox/.net-configured so secubox-net-detect
  short-circuits at first boot and doesn't overwrite the static config

--hostname NAME overrides the baked-in "secubox-live" hostname in both
/etc/hostname and /etc/hosts.

When --static-ip is absent, behavior is unchanged (DHCP bootstrap +
secubox-net-detect at first boot).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:10:11 +02:00
2d46c7d733 feat(image): Add u-boot-tools and fw_env.config for MOCHAbin
- Add u-boot-tools and libubootenv-tool to image packages
  (includes mkimage, fw_printenv, fw_setenv)
- Create fw_env.config for MOCHAbin SPI NOR environment access
  - Environment at offset 0x3F0000, size 64KB
  - Standard Marvell U-Boot layout

This allows reading/modifying U-Boot environment from Linux:
  fw_printenv bootcmd
  fw_setenv bootargs "root=/dev/mmcblk0p2 ..."

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-08 10:25:20 +02:00
144ee6288d feat(image): Add MOCHAbin USB live boot builder with LED kernel
- New build-mochabin-live-usb.sh for ARM64 live USB images
- Includes LED kernel support (IS31FL3199 driver)
- Recovery tools and diagnostics built-in
- extlinux boot configuration for Tow-Boot/U-Boot
- Network config for 10GbE + SFP+ + 4x GbE

Recovery documentation added to issue #39

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-07 10:42:59 +02:00
ebdc5c08c0 fix(rpi-usb): Remove python3-cryptography from debootstrap
python3-cryptography fails to configure under QEMU ARM64 emulation
during debootstrap due to Rust compilation requirements.

It's already installed via pip later in the build process, which
works reliably cross-architecture.

Fixes rpi400 image build failure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-06 19:32:30 +02:00
46770abee7 fix(image): Add missing Python deps (python-multipart, email-validator)
Services were failing in restart loops due to missing dependencies:
- python-multipart: required for FastAPI file upload endpoints
- email-validator: required for Pydantic email field validation

Updated build scripts:
- build-image.sh: added both packages
- build-rpi-usb.sh: added email-validator (multipart was present)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-05 07:32:47 +02:00
76a2a1fe71 fix(image): Activate .dpkg-new nginx configs after package slipstream
dpkg leaves .dpkg-new suffix on conffiles when installing over existing
configs. This caused nginx API routing to fail as the module configs
(system.conf, etc.) were not loaded.

Added activation step to all build scripts that renames .dpkg-new files
to their proper .conf names after package installation.

Affected scripts:
- build-image.sh
- build-live-usb.sh
- build-rpi-usb.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-04 13:10:06 +02:00
b1c77a871e fix(slipstream): Filter packages by architecture during image build
Build scripts copied ALL .deb packages without architecture filtering.
When building arm64 images, amd64-only packages (secubox-daemon,
secubox-c3box) were included and dpkg failed with "package architecture
does not match system".

Fixed in:
- build-image.sh: filter by $DEBIAN_ARCH variable
- build-ebin-live-usb.sh: filter for _all.deb and _arm64.deb
- build-live-usb.sh: filter for _all.deb and _amd64.deb

This fixes GitHub Actions workflow failures on arm64 boards.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-02 17:26:37 +02:00
8a0aa57f70 fix(net-detect): Separate VirtualBox VM handling from baremetal x64
VMs with multiple interfaces (NAT + host-only) now correctly configure
all interfaces with DHCP instead of creating a br-lan bridge that
conflicts with VBox's host-only DHCP server.

Changes:
- Add dedicated x64-vm case in get_interface_config()
- Set profile="vm" for VMs to trigger single mode (no bridge)
- In generate_netplan(), detect x64-vm board and configure ALL
  physical interfaces with DHCP instead of WAN-only
- VM profile forces mode="single" in main() to skip bridge creation

This fixes host-only network access for VirtualBox VMs while
preserving router/bridge functionality for baremetal deployments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-01 17:33:31 +02:00
254b9df528 feat(live-usb): Improve kiosk launcher and network detection
- Fix vm_type variable sanitization in kiosk launcher
- Enhance network detection for AMD64 hardware
- Improve build-live-usb service configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-01 09:29:58 +02:00
106fd61af3 fix(network): Fix x64-live netplan for real AMD64 hardware
Problem: IP assignment failures on bare metal AMD64 due to broken
netplan wildcard syntax - using wan0: with match: name: "e*" but
no set-name: directive caused conflicts on multi-interface systems.

Solution:
- Split single e* pattern into separate en* and eth* matches
- Different route metrics (100/200) for deterministic routing
- Added br-lan bridge pre-definition for router mode
- Enhanced secubox-net-detect with better logging and patterns
- New secubox-net-reset utility for forcing re-detection

Changes:
- board/x64-live/netplan/00-secubox.yaml: Fixed bootstrap config
- image/build-live-usb.sh: Updated embedded netplan with same fix
- image/sbin/secubox-net-detect: Enhanced interface detection
- image/sbin/secubox-net-reset: New utility script
- CLAUDE.md: Added Debian shell scripting guidelines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-01 06:44:08 +02:00
c4b7ac0f7f feat(eye-remote): Add multi-mode display system v1.9.0
Eye Remote Interactive UI enhancements:
- TTY mode: Serial terminal display from /dev/ttyGS0
- Flash mode: Progress bar with speed/ETA for USB transfers
- Auth mode: QR code generation for backup authentication
- Mode detection via /etc/secubox/gadget-mode

Hub service VM compatibility fix:
- Changed from Unix socket to TCP port 8001
- Updated nginx configs for TCP proxy
- Fixes 502 errors in VirtualBox VMs

Also includes:
- FAQ/Troubleshooting wiki page with GitHub issue links
- Kiosk launcher --no-sandbox fix for VMs
- Profile Generator GUI mockup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-29 10:24:02 +02:00
33304e7b6f feat(build): Add kiosk mode + VirtualBox setup + Profile Generator architecture
VM-x64 Build Improvements:
- Enable kiosk mode by default with GRUB menu entries
- Increase image size to 8GB (5.5GB root) for full package set
- Add proper EFI boot configuration with 3 boot modes
- Pre-generate SSL certificates during build
- Add TTY2 autologin for emergency console access

VirtualBox Support:
- Add scripts/vbox-setup.sh for automated VM setup
- Add wiki/VirtualBox-Setup.md with comprehensive guide
- Support bridged, NAT, and host-only network modes
- Auto-detect network adapter for bridged mode

Architecture Documentation:
- Add docs/architecture/profile-generator.md (v0.2)
- Define tier × board × flavors resolution model
- Document 3 CLI tools: secubox-gen, secubox-build, secubox-fetch
- Add Phase 12-14 roadmap alignment for Ulule Campaign 1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-29 09:16:36 +02:00
a697925a3f fix(build): Upgrade Python deps + CORS + login endpoint fixes
- Add CORS headers to nginx secubox-proxy.conf for cross-origin API requests
- Fix login.html endpoints: /auth/login -> /login
- Upgrade Python deps in build scripts: pydantic>=2.0, fastapi>=0.100, uvicorn>=0.25
- Add pip upgrade in secubox-core postinst for Debian bookworm compatibility
- Fix display/__init__.py to import existing modules only

Fixes authentication and API issues in VBox and ebin builds.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-28 20:53:40 +02:00
dd384da66a feat(eye-remote): Add display state machine with splash and fallback modes
Display system for Pi Zero Eye Remote (HyperPixel 2.1 Round 480x480):

Splash Screen (splash.py):
- Animated phoenix logo for boot/halt/start/reboot states
- Pulsing glow effects with fire colors
- Progress indicator ring with rotating dots
- Fallback phoenix symbol if logo image missing

Fallback Display Manager (fallback_manager.py):
- Connection state detection (OTG 10.55.0.1, WiFi secubox.local)
- Four modes: OFFLINE, CONNECTING, ONLINE, COMMUNICATING
- Local metrics radar with 6 concentric rings
- 3D rotating cube with module icons when connected
- Rainbow sweep line animation

Touch Analysis Tools:
- touch_analyzer.py: Noise pattern analysis (Y-axis oscillation at stable X)
- touch_calibrate.py: Corner target display for manual calibration
- touch_filter.py: X-stable noise filtering

Radar Variants:
- radar_flashy.py: Vibrant colors with 3D cube
- radar_concentric.py: Balanced metric arcs centered at 12 o'clock
- radar_rainbow.py: Rainbow colorization with sweep
- radar_full.py: Complete feature set

Also includes:
- Hardware Smart-Strip module specs (SBX-STR-01)
- Host configuration for USB OTG network
- Systemd service for USB auto-mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-28 14:48:00 +02:00
555600d5dd fix(multiboot): Ensure kernel files are properly copied to EFI partition
- Fix glob pattern in bash test (glob in [[ -f ]] doesn't work correctly)
- Use find command instead of glob for reliable kernel detection
- Add fallback to extract ARM64 kernel from live USB image if not in rootfs
- Add verification step in GitHub Actions to check boot files after build
- Sort kernel files by version to get latest when multiple exist

Fixes missing vmlinuz/Image on multiboot USB issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 19:29:09 +02:00
32fecbf010 feat(hardware): Add Smart-Strip HMI module (SBX-STR-01) + fix lite profile build
Smart-Strip v1.1:
- RP2350A MCU with TrustZone-M + AT42QT2120 touch IC
- 6× RGB LEDs (SK6812-MINI-E) + 6 capacitive touch zones
- Dual-mode: USB-C 2.0 (HID+CDC) / I²C (0x42)
- Hamiltonien sweep AUTH→MESH following SecuBox charte
- Parser CDC with whitelist grammar (no eval, no dynamic alloc)
- Interactive HTML simulator included

Build fixes:
- Skip X11/kiosk packages for SECUBOX_LITE=1 profiles
- Skip netdata/glances for lite profiles (ESPRESSObin)
- Skip LXC for lite profiles (limited storage)
- ESPRESSObin image now fits in 3584M (548M compressed)

Files:
- docs/hardware/smart-strip-v1.1.md (550-line spec)
- docs/hardware/smart-strip/simulator.html
- packages/secubox-smart-strip/firmware/{parser,ring_buffer}.{c,h}
- packages/secubox-smart-strip/host/secubox_smart_strip.py
- wiki/Smart-Strip.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 19:03:08 +02:00
55166bb258 fix(build): Move complex Python packages to post-debootstrap
python3-cryptography and python3-jose fail during debootstrap due
to complex dependencies. Moving to post-debootstrap apt-get install.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 17:12:21 +02:00
bfe2e9cb98 release: Version 1.9.0
Changes in this release:
- Added comprehensive package dependencies to all build scripts
- Firmware images now fully ready with all deps pre-installed
- Fixed package conflicts (iputils-arping, python3-zmq)
- Build scripts include: Python deps, network tools, security
  services (crowdsec, netdata, glances), X11 packages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 17:09:29 +02:00
6149354fed fix(build): Move python3-zmq to post-debootstrap installation
python3-zmq has complex dependencies that fail during debootstrap.
Moving it to post-debootstrap apt-get installation resolves this.

Also removed from INCLUDE_PKGS in build-image.sh - installed via pip.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 17:06:47 +02:00
b4415de8a7 fix(build): Use iputils-arping instead of arping
The 'arping' and 'iputils-arping' packages conflict with each other.
Using iputils-arping which provides the arping command needed by
the network fallback scripts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 17:00:32 +02:00
cadd993862 fix(build): Add all missing package dependencies to build scripts
All build scripts now include comprehensive package lists so firmware
images are fully ready with all dependencies pre-installed. No need
for apt --fix-broken install after boot.

Added packages:
- Python deps: python3-fastapi, python3-uvicorn, python3-httpx,
  python3-psutil, python3-aiosqlite, python3-cryptography,
  python3-jinja2, python3-jwt, python3-aiofiles, python3-pil,
  python3-tomli, python3-pydantic, python3-jose, python3-toml,
  python3-netifaces, python3-zmq
- Network tools: bridge-utils, traceroute, dnsutils, whois, mtr-tiny,
  nmap, arping, avahi-daemon, avahi-utils, haproxy, qrencode
- Services: crowdsec, glances, netdata, mosquitto, coturn, lxc
- X11 packages: kbd, xinit, xserver-xorg-core, chromium, unclutter,
  x11-xserver-utils
- Additional pip: pillow, zmq, pyjwt, textual

Files updated:
- image/build-image.sh (main ARM/x64 builder)
- image/build-live-usb.sh (x64 live USB)
- image/build-rpi-usb.sh (Raspberry Pi ARM64)
- image/build-ebin-live-usb.sh (ESPRESSObin ARM64 live)
- image/profiles/x64-live.conf (profile with package lists)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 16:51:56 +02:00
b115e966b1 fix(network): Remove dummy0 interface causing routing issues
The dummy0 interface was creating unwanted default routes that
interfered with proper network connectivity.

Removed from:
- board/espressobin-v7/netplan/00-secubox.yaml
- board/espressobin-ultra/netplan/00-secubox.yaml
- board/mochabin/netplan/00-secubox.yaml
- image/build-image.sh (systemd-networkd config)
- image/build-live-usb.sh (systemd-networkd config)
- image/profiles/x64-live.conf (kiosk dummy network)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 16:45:31 +02:00
d42745aac3 feat(live-boot): Complete live RAM boot implementation v2.2.4-live
- Install live-boot package and rebuild initramfs with live-boot scripts
- Create squashfs filesystem (878MB) on data partition sda4
- Update boot.scr with live boot parameters (boot=live, toram)
- Fix wiki sidebar links from [[Page|Display]] to [Display](Page)
- Add Eye-Remote wiki page documentation
- Add sync-wiki.sh script for wiki repository sync
- Add patch-multiboot-efi.sh for post-build EFI patching

Partition layout:
- sda1 (512MB): EFI with kernel, initrd, dtbs, boot.scr
- sda2 (3GB): ARM64 rootfs reference
- sda3 (3GB): x86 rootfs for VirtualBox/QEMU
- sda4 (9.5GB): Data + /live/filesystem.squashfs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 13:30:50 +02:00
8a473cc1c2 docs(wiki): Add Multiboot Live OS announcement and documentation
- Add announcement banner on wiki home for v2.2.3 multiboot release
- Create wiki/Multiboot.md with full multiboot documentation
- Add Multiboot and Eye Remote links to sidebar navigation
- Update sidebar version to v2.2.3
- Document Eye Remote Pi Zero as USB gadget for ESPRESSObin boot
- Add partition layout, boot flow, and troubleshooting docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 11:22:41 +02:00
6d58ae0ac6 fix(multiboot): Use local deb slipstream instead of apt repo
- Removed apt.secubox.in dependency (not ready)
- Install SecuBox packages from output/debs/ directory
- Handles missing debs gracefully

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 10:40:04 +02:00
494e6def67 fix(multiboot): Fix set -e early exit with [[ ]] && pattern
- Changed [[ -z "$VAR" ]] && err to if/then/fi pattern
- This prevents early exit when condition is false with set -e
- Removed --minimal flag to install full SecuBox packages

Note: SecuBox packages on AMD64 still require apt.secubox.in SSL fix

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 10:39:04 +02:00
5cf69c0ce1 feat(multiboot): Add multi-architecture boot system with shared data
Create a multi-boot storage system for Pi Zero Eye Remote that supports:
- ARM64: ESPRESSObin/MOCHAbin via U-Boot boot.scr
- AMD64: Any x86_64 UEFI system via GRUB
- Shared data: Cross-architecture application data on partition 4

Partition layout (16GB+ recommended):
- P1: EFI/FAT32 (512MB) - Boot files for both architectures
- P2: ext4 (3GB) - ARM64 rootfs
- P3: ext4 (3GB) - AMD64 rootfs
- P4: ext4 (remaining) - Shared SecuBox configs, state, logs

Features:
- Automatic bind mounts for /etc/secubox, /var/lib/secubox, /srv/secubox
- eMMC flasher image included in EFI partition
- Debootstrap-based AMD64 rootfs builder
- U-Boot script with USB/MMC detection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-27 10:13:31 +02:00
8c07f0f90a feat(eye-remote): v1.8.0 - Eye Remote multi-mode USB gadget
- Add 5 USB gadget modes: Normal, Flash, Debug, TTY, Auth
- Add HID keyboard emulation for U-Boot automation
- Add FIDO2/U2F security key mode (Eye Remote)
- Add x64/amd64 live boot support
- Update README.md with Eye Remote documentation
- Update WIKI.md with mode mockups and technical details
- Add INFOGRAPHIC-PROMPT.md for Claude.ai image generation
- Bump version from 1.7.0 to 1.8.0

New files:
- secubox-hid-keyboard.sh: Virtual HID keyboard driver
- INFOGRAPHIC-PROMPT.md: 7 prompts for publicity infographics

Eye Remote transforms the Round UI from a status display
into a full remote control device with debugging, flashing,
and authentication capabilities.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-20 11:33:26 +02:00
3240e441c7 fix(ebin): EspressoBin eMMC boot fixes
- secubox-haproxy: Remove ReadWritePaths sandboxing causing NAMESPACE errors
- secubox-net-fallback: Skip lan* interfaces (DSA downstream ports)
- netplan: Add dummy0 with 10.55.255.1/24 to all board configs
- flash-emmc: Fix eMMC detection using boot0 partition
- flash-emmc.cmd: Support multiple image filenames

Fixes issues encountered when booting SecuBox from EspressoBin V7 eMMC.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-20 07:59:42 +02:00
76cd7c0d96 feat(remote-ui): Add HyperPixel 2.1 Round dashboard for RPi Zero W
Complete Remote UI implementation for SecuBox status display:

- Python/PIL dashboard with direct framebuffer rendering (no Chromium)
- KMS overlay support (vc4-kms-dpi-hyperpixel2r) - tested working
- USB OTG composite gadget (CDC-ECM + CDC-ACM) for host connection
- 6 concentric rings showing CPU, MEM, DISK, LOAD, TEMP, WiFi metrics
- Auto-start systemd service (secubox-dashboard.service)
- install_zerow.sh for SD card preparation with all fixes

Key fixes discovered during debugging:
- Use KMS overlay, not non-KMS (GPIO conflicts on Bookworm)
- Framebuffer is RGB565 (16-bit), not BGRA
- RPi OS Bookworm requires userconf file for SSH credentials
- NetworkManager ignores ifupdown; use direct IP config

Files:
- secubox_dashboard.py: PIL-based live metrics dashboard
- install_zerow.sh: SD card flasher with KMS overlay
- secubox-dashboard.service: Auto-start systemd unit
- 24 module icons (AUTH/WALL/BOOT/MIND/ROOT/MESH)

Tested on: RPi Zero W + HyperPixel 2.1 Round 480x480

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 17:54:09 +02:00
d5fd350e88 fix(kiosk): Skip X11 config on bare metal in kiosk launcher too
Same fix as build-live-usb.sh X11 setup - the kiosk launcher was also
creating X11 config files that corrupted on bare metal.

- Skip config creation entirely for bare metal (vm_type=none)
- Intel/AMD/NVIDIA auto-detection works perfectly without configs
- Sanitize gpu_info for VMs (remove special chars)
- Only create explicit driver configs for VMs that need them

Fixes: "M2G_" parse error in /etc/X11/xorg.conf.d/10-kiosk.conf

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 10:09:09 +02:00
529fcce5a1 fix(network): Skip local IPs in gateway discovery (avoid self-ping)
The fallback script was pinging 192.168.255.1 (dummy0 interface) and
thinking it found a gateway, then assigning 192.168.255.250 to the
ethernet interface - which doesn't provide internet connectivity.

- Add check to skip gateway IPs that are already assigned locally
- Verify ARP discovery results aren't local IPs
- Prevents self-discovery of dummy0 (192.168.255.1)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 09:59:33 +02:00
b226233520 feat(network): Smarter IP auto-discovery with ARP scanning
- Add iputils-arping for ARP-based gateway discovery
- Add arp_discover() function to scan for responding devices
- Expand gateway probe list: .254 variants, 10.x, 172.16.x subnets
- Try ARP discovery before slower ping-based gateway probing
- More reliable network auto-configuration on diverse networks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 09:57:00 +02:00
cf7ea44c78 fix(kiosk): Skip X11 config on bare metal, disable service sandboxing
- X11 setup now exits early for bare metal (VM_TYPE=none) without
  creating config files - Intel/AMD/NVIDIA auto-detect perfectly
- Remove static fallback 10-modesetting.conf that caused conflicts
- Sanitize GPU_INFO in config comments to remove special chars
- Disable PrivateTmp and ProtectSystem for haproxy, metrics, threats
  services - causes Python symlink namespace errors on some kernels
- Add fix-namespace-errors.sh script for quick fixes on running systems

Fixes: X11 "no screens found" on Intel HD Graphics 630
Fixes: "Failed to set up mount namespacing" for Python services

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 09:52:20 +02:00
f4806bf7fa fix(ci): Fix eMMC image check and RPi multi-initrd copy
- build-all-live-usb.yml: Check for .img.gz first since build-image.sh
  already compresses and removes the .img file
- build-rpi-usb.sh: Handle multiple kernel/initrd files by selecting
  the latest version instead of globbing which breaks cp

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 09:22:23 +02:00
0f970bb8de fix(kiosk): Add VirtualBox VMSVGA graphics driver support (v1.6.7.14)
- Create secubox-x11-setup.service for boot-time VM/driver detection
- VirtualBox VMSVGA controller requires vmware X11 driver (not modesetting)
- Add driver selection: VBox+VMSVGA→vmware, VBox+VBoxVGA→modesetting
- Update secubox-kiosk.service to depend on x11-setup service
- Update secubox-kiosk-launcher v3.3 to defer to setup service
- Change SLIPSTREAM_DEBS default to 1 (126 packages by default)
- Fix EspressoBin live USB boot partition sizing for embedded images

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 09:16:37 +02:00
6d8127433a fix(build): Fix DTB copy in EspressoBin live USB build
- Use find instead of glob to locate DTB directory reliably
- Copy only EspressoBin DTBs (armada-3720-espressobin*.dtb)
- Add logging for DTB count and warning if missing
- Fixes boot failure due to missing device tree files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-15 06:03:37 +02:00