Commit Graph

12 Commits

Author SHA1 Message Date
a52af3b50a feat(netplan): standardize SecuBox LAN to 192.168.10.0/24; bump 1.10.0 (ref #760)
Default br-lan 192.168.1.1/24 collided with common ISP-router LANs
(Freebox/Livebox 192.168.1.0/24) when the appliance sits behind one:
WAN(DHCP)+LAN land on the same subnet -> duplicate route, ARP ambiguity,
unreachable mgmt IP. Observed live on c3box behind a Freebox.

- All board netplans (mochabin, espressobin-v7/ultra, x64-vm, x64-live)
  + VM LANs (vm-x64, vm-arm64) -> br-lan/LAN 192.168.10.1/24
- Generators: secubox-netmodes (inline + router.yaml.j2 template),
  secubox-hub preview, secubox-net-detect
- dnsmasq (espressobin-v7.conf): dhcp-range + option:router + dns-server
- live-usb build scripts + self-signed cert SANs -> IP:192.168.10.1
- Out of scope (untouched): 192.168.255.1 mgmt/trusted-proxy whitelist,
  WAN-probe GATEWAYS lists, remote-ui/round + tests
- Minor "medium" bump 1.9.0 -> 1.10.0 (core build scripts; mochabin-live
  stays on its 2.0.0 track)

Live: c3box br-lan already 192.168.10.1/24 + netmodes template aligned;
gk2 WAN moved to eth2 DHCP @ .200 (Freebox reservation on eth2 MAC).
2026-06-27 17:11:23 +02:00
40b5837262 fix(soc): move nft cache into secubox-hub + realtime fallback
The v2.12.16 fix put the nft cache populator in firstboot.sh, which
broke the rule "cron lives next to the module that consumes it" — the
SOC firewall_summary endpoint is owned by secubox-hub, so the timer
that feeds its cache belongs in the same package.

This commit:
  * removes the inline cache populator from image/firstboot.sh
  * ships /usr/sbin/secubox-nft-cache + secubox-nft-cache.{service,timer}
    inside the secubox-hub package, with the timer auto-enabled via the
    timers.target.wants/ symlink
  * adds a sudoers fragment authorising user secubox to run
    `nft list *`, `nft -j list *`, and `systemctl --no-block start
    secubox-nft-cache.service` (and only that one unit)
  * rewrites the /firewall_summary endpoint so the cache is a speed
    optimisation, not the source of truth: if the cache file is missing
    or older than 60 s, fall back to a realtime `sudo nft list`,
    surface `source: "realtime"` in the JSON, and nudge the cache
    populator via systemctl so the next request lands on a hot cache

Per the operator directive: "les cache double buffer ne doivent pas
tomber et permettre juste d'aller plus vite... un echec de cron et de
cache doit forcer le cron et faire du realtime".
2026-05-26 12:43:55 +02:00
27f9cd9db0 fix(soc): populate nft cache + add status field to firewall_summary
Operator screenshot: SOC dashboard "🔥 FIREWALL nftables / Status
INACTIVE / Tables 7 / Chains 10 / Rules 19" with all counters at 0
(Accept/CAPI/CrowdSec/Manual).

Two bugs found:

1. The /api/v1/hub/public/firewall_summary endpoint docstring says
   it reads cache files `/var/cache/secubox/nft-*.txt` "updated by
   cron every 30s" — but the cron never existed in the repo. The
   table/chain/rule counts were getting populated somehow (probably
   a one-shot at firstboot) while the counters file stayed empty,
   hence 7/10/19 visible but all hit-counts zero.

2. The endpoint never returned a `status` field, so the React
   bundle (secubox-soc-web) defaulted to "INACTIVE" regardless of
   whether nftables.service was active or rules were loaded.

Fixes:

* firstboot.sh installs `/usr/local/bin/secubox-nft-cache` +
  `secubox-nft-cache.service` + `.timer` (oneshot, every 30s,
  OnBootSec=10s). Runs as root via systemd so it can call
  `nft -j list ruleset` + `nft list counters`. Writes the JSON
  ruleset + counters dump + a `.lastrun` sentinel into
  /var/cache/secubox/.

* hub `/firewall_summary` endpoint now:
  - calls `systemctl is-active nftables.service` and returns a
    `status` field ("active" | "inactive" | "active-manual" | "error")
  - "active-manual" = systemd reports inactive but the kernel has
    rules loaded (happens when firstboot.sh did `nft -f` directly
    and the systemd unit didn't get re-enabled). Treat as active
    for dashboard purposes — operator wants to see "firewall is up"
    when there ARE rules.
  - returns `cache_last_run` so the dashboard can warn on stale
    cache.

WAF metrics empty is by design on a live USB without mitmproxy LXC
(THREATS_LOG never gets written → zero counters). Not addressed
here. Operator runs install-lxc.sh once to enable WAF traffic.
2026-05-26 12:35:37 +02:00
1f51d1818d fix(live-usb): nft rule syntax — udp dport 68 (drop the redundant udp sport)
v2.12.11's rule `udp sport 67 udp dport 68 accept` was invalid nft
syntax — protocol prefix can't be repeated inside a single rule, the
firstboot.sh-generated /etc/nftables.conf failed to load and the
firewall stayed in its previous state (or empty), defeating the
whole point of the DHCP fix.

Just match the destination port: `udp dport 68 accept`. DHCPOFFER /
DHCPACK from any server (sport 67) lands on dport 68 of the client,
so the inbound match is sufficient and unambiguous.

Live-system workaround (no rebuild needed):
  nft add rule inet secubox_filter input udp dport 68 accept
2026-05-26 07:20:33 +02:00
8b0ec6884c fix(live-usb): nftables — accept DHCP replies (udp sport 67 dport 68)
Bare-metal box ended up with 192.168.10.250 (assigned by secubox-net-
fallback's ARP-probe loop) instead of the real DHCP lease from the
LAN router. Operator confirmed DHCP server is healthy on the LAN
(dev box on same switch got 192.168.1.13 via DHCP without issue).

Root cause: firstboot.sh writes /etc/nftables.conf with policy=drop
on the input chain and no explicit DHCP allowance. The `ct state
established,related accept` rule does NOT cover DHCP because the
client request leaves from 0.0.0.0:68 and the server reply comes back
broadcast (or unicast direct to the offered IP before it's bound).
Neither matches the original 5-tuple → conntrack treats the reply
as a new packet → policy drop → DHCPOFFER lost → networkd times out.
secubox-net-fallback then picks a random gateway from its probe
list and lands the box on the wrong subnet.

Add `udp sport 67 udp dport 68 accept` to the input chain. This
matches DHCPv4 server-to-client replies specifically (port 67/68
are reserved BOOTP/DHCP). DHCPv6 would need a sibling `udp dport
546 accept` rule but is out of scope here.
2026-05-26 07:16:27 +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
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
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
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
71787e94f5 fix(auth): Add portal users.json reset in firstboot
- Create /etc/secubox/users.json with admin user on firstboot
- Default password: secubox (instead of random)
- SHA256 hash password same as portal expects
- Hide Chromium --ignore-certificate-errors warning with --test-type

Credentials: admin / secubox

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-12 18:36:45 +02:00
3d85870a1e feat(image): Add network auto-detection and kiosk mode support
Network detection (secubox-net-detect):
- Board detection: MochaBin, ESPRESSObin v7/Ultra, x64 VM/baremetal
- Interface mapping based on device model (eth0=WAN, lan*=LAN)
- Netplan generation for router/bridge/single modes
- Link detection for x64 auto-discovery

Kernel cmdline handler:
- secubox.netmode=router|bridge|single for boot-time network mode
- secubox.kiosk=1 for GUI kiosk mode
- secubox.debug=1 for debug mode

Kiosk mode (secubox-kiosk-setup):
- Minimal GUI: Cage Wayland + Chromium fullscreen
- Displays SecuBox WebUI on connected screen
- Commands: install, enable, disable, status

Board configs:
- board/x64-live/ for Live USB
- board/x64-vm/ for VM environments

Live USB updates:
- GRUB entries for Kiosk Mode and Bridge Mode
- Installs all detection scripts and services

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-28 17:20:25 +01:00
bf1babb37c Initial commit: SecuBox-DEB migration from OpenWrt to Debian
Includes all package APIs with public dashboard endpoints:
- secubox-system: System Hub with /info, /resources, /security
- secubox-crowdsec: CrowdSec dashboard with /status, /hub, /metrics, actions
- secubox-wireguard: WireGuard VPN with /interfaces, /peers, start/stop
- secubox-netdata: Monitoring with /stats, /processes, /alerts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-21 09:41:06 +01:00