Compare commits

...

12 Commits

Author SHA1 Message Date
f3fc9a3a92 fix(image): non-interactive conffile handling for secubox-full install
Some checks are pending
License Headers / check (push) Waiting to run
secubox-mesh's mesh.toml is an auto-detected conffile that triggers an
interactive dpkg prompt (*** mesh.toml [Y/I/N/O/D/Z]) during configure,
failing the headless chroot install in build-live-usb.sh (amd64 USB build).
Install secubox-full with DEBIAN_FRONTEND=noninteractive + --force-confold/
--force-confdef + a follow-up dpkg --configure -a, in build-live-usb.sh and
build-image.sh.
2026-06-28 09:15:35 +02:00
4398ebe654 Merge #760: LAN 192.168.10.0/24 standardization + build-pipeline fixes (dearmor, golang-go, arch=both, -d) + 1.10.0 2026-06-28 09:10:47 +02:00
1a60f82de9 fix(ci): build pure-Go pkgs with -d (golang-go metapackage dep-check) (ref #760)
dpi/toolbox-ng/waf-ng are CGO_ENABLED=0 cross-compiles; the go toolchain is
present (golang-1.22-go) but dpkg-checkbuilddeps trips on the golang-go
metapackage. Skip the dep check for just these three (-mod=vendor, self-contained).
2026-06-28 09:10:45 +02:00
bb9208cbcc Merge p2p fixes: master-link statedir, www path, no-self-peer, invite ownership (#762 substrate) 2026-06-28 09:09:08 +02:00
119771eadb fix(p2p): sbx-mesh-invite re-owns token store to secubox when run as root
Root-owned tokens.json made the secubox-user p2p (and the in-process
aggregator) crash with EACCES. chown -R secubox the master-link dir if root.
2026-06-28 09:06:36 +02:00
973c9e3a78 fix(p2p): don't count/list the local node as a peer
list_peers inserted+persisted get_self_peer() into PEERS_FILE, so peer_count
and online_peers counted the node itself (showed '<host> (local)' as a phantom
peer). /status and /peers now exclude is_local/self; self info stays available
via /discover/self for announcements.
2026-06-28 08:47:41 +02:00
675c4806ea fix(p2p): install web UI to /usr/share/secubox/www (fixes Module Not Found)
p2p shipped its UI to /var/www/secubox/p2p, but the dashboard vhost serves
modules from /usr/share/secubox/www (root + try_files). So /p2p/ fell through
to the unknown-module page. Install p2p + master-link UIs there like all other
modules; update nginx aliases to match.
2026-06-28 08:27:07 +02:00
255677c219 fix(p2p): postinst creates /var/lib/secubox/p2p/master-link owned secubox
The app's master-link init mkdir's master-link/ and failed EACCES when
/var/lib/secubox/p2p was root-owned (it was never created by the package),
500-ing /api/v1/p2p/status and breaking mesh-join enrollment. Create p2p/ +
master-link/ as secubox in postinst (mirroring the log-dir pattern) and chown
to repair pre-existing installs. Never touches the shared parent (#494/#511).
2026-06-28 08:22:54 +02:00
8d5627567d fix(ci): build-packages arch=both must expand to both arches (ref #760)
The discover matrix filter only compared requested_arch against amd64/arm64/
empty, so the 'both' workflow_dispatch option produced an EMPTY matrix (no
builds, collect failed). Normalize 'both' -> empty (= all arches).
2026-06-28 06:57:25 +02:00
8bbc573149 fix(ci): install golang-go so arm64 pure-Go packages build (ref #760)
secubox-dpi and secubox-toolbox-ng are CGO_ENABLED=0, GOARCH=arm64,
-mod=vendor offline cross-compiles. They failed the arm64 build only
because golang-go was never installed, so dpkg-checkbuilddeps aborted on
their `Build-Depends: golang-go (>= 1.22)`. Not a CGO cross-toolchain
gap. ubuntu-24.04 ships golang-go >= 1.22; installing it lets the pure-Go
arm64 cross-compile run on the amd64 runner.

Unblocks a complete amd64+arm64 package set for the apt repo + arm64 images.
2026-06-28 06:52:40 +02:00
6a557cbe2c fix(image): dearmor apt keyring for signed-by (apt rejects armored) (ref #760)
build-image.sh / build-installer-iso.sh / validate-staged-repo.sh fetched the
ASCII-armored secubox-keyring.gpg and used it directly as
`signed-by=/usr/share/keyrings/secubox.gpg`. apt's signed-by requires a
DEARMORED (binary) keyring, so the chroot apt-get update failed with
"NO_PUBKEY 44E50F0178E8BC7E / repository not signed" even though the repo
signature and key are correct. Pipe the key through `gpg --dearmor`.

Root cause of all image-build failures since the keyring became armored;
not a key desync (repo signer == published keyring == 44E50F0178E8BC7E).
2026-06-27 17:44:13 +02:00
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
28 changed files with 181 additions and 48 deletions

View File

@ -3,6 +3,39 @@
---
## 2026-06-27 — LAN standardisé 192.168.10.0/24 + c3box/gk2 live Freebox + bump 1.10.0 (#760)
Session terrain "c3box derrière Freebox" : la LAN SecuBox par défaut (`br-lan 192.168.1.1/24`)
entrait en collision avec la LAN d'un routeur opérateur courant (Freebox/Livebox en
`192.168.1.0/24`). En aval d'une Freebox, le WAN DHCP et la LAN se retrouvaient sur le **même
sous-réseau** → route dupliquée, ARP ambigu, IP de management injoignable.
### A. Constat live + remédiation immédiate
- **c3box** (second MOCHAbin) derrière Freebox : WAN `eth2=192.168.1.94` (bail Freebox) +
`br-lan=192.168.1.1/24``.94` injoignable depuis le LAN. Corrigé live : `br-lan → 192.168.10.1/24`.
SSH root activé, webadmin `https://192.168.1.94/` OK, `/dev/sda1` (931 G) monté sur `/data`
(style gk2 : UUID + nofail), partition eMMC retirée (`emmc-data`).
- **gk2** (live PoC) : uplink déplacé de `lan0` (DSA) vers le port cuivre WAN `eth2` ; netplan
réparé via **série** (gk2 hors-réseau le temps du switch) → `eth2 dhcp4: true`, `lan0` dépouillé.
Bail Freebox réservé sur le MAC eth2 `f0:ad:4e:27:88:9b` → gk2 reprend `192.168.1.200`. Persisté.
### B. Standardisation source (LAN = 192.168.10.0/24, gw .10.1) — 17 fichiers
- Netplans board : mochabin, espressobin-v7, espressobin-ultra, x64-vm, x64-live (`br-lan`),
+ unification VM vm-x64/vm-arm64 (`192.168.100.1 → 192.168.10.1`).
- Générateurs de netplan : `secubox-netmodes`, `secubox-hub` (preview), `secubox-net-detect`.
- dnsmasq (`espressobin-v7.conf`) : `dhcp-range` + `option:router` + `option:dns-server`.
- Scripts live-usb (mochabin/ebin) + SAN des certs auto-signés (`firstboot`, `build-image`,
`build-rpi-usb`, `build-live-usb`) → `IP:192.168.10.1`.
- **Hors scope (intacts)** : `192.168.255.1` (whitelist mgmt/trusted-proxy WAF/mail/wg/mitm),
listes `GATEWAYS` de sonde WAN, exemples remote-ui/round + tests.
### C. Release
- Bump mineur (« medium ») **1.9.0 → 1.10.0** : `build-image.sh`, `build-live-usb.sh`,
`build-ebin-live-usb.sh`, `build-rpi-usb.sh` (mochabin-live reste sur sa piste 2.0.0).
- Artefacts amd64 (x64) reconstruits depuis cette base.
---
## 2026-06-27 — Netboot live PROUVÉ + première install SecuBox Debian sur c3box (second MOCHAbin) (#748 #737)
Grande session hardware : netboot gk2→c3box validé de bout en bout, premier SecuBox Debian installé

View File

@ -63,6 +63,11 @@ jobs:
# Build the flat {package, arch} matrix. Honour the workflow_dispatch
# `arch` and `package` filters if set (empty on `push: tags` events).
requested_arch="${REQUESTED_ARCH:-}"
# `both` means build every arch — same as the empty (push: tags)
# case. Without this the matrix filter (which only compares against
# amd64/arm64/empty) yields an EMPTY matrix, so no package builds and
# `collect` fails.
[ "$requested_arch" = "both" ] && requested_arch=""
requested_pkg="${REQUESTED_PKG:-}"
combos=$(find packages/secubox-* -path "*/debian/control" -not -path "*/debian/*/DEBIAN/control" \
@ -152,7 +157,12 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -y -qq \
build-essential dpkg-dev debhelper devscripts fakeroot \
dh-python python3-all python3-setuptools
dh-python python3-all python3-setuptools golang-go
# golang-go satisfies Build-Depends of the pure-Go packages
# (secubox-dpi, secubox-toolbox-ng: CGO_ENABLED=0, GOARCH=arm64,
# -mod=vendor offline cross-compile). ubuntu-24.04 ships >= 1.22.
# Without it dpkg-checkbuilddeps aborts the arm64 build — this was
# the real cause of the "arm64 red" runs, not a CGO toolchain gap.
# arm64 cross-toolchain — dh_strip and dh_makeshlibs invoke
# aarch64-linux-gnu-{strip,objdump} when -a arm64 is passed.
# Without these, arch-specific packages shipping prebuilt
@ -213,7 +223,18 @@ jobs:
# no-op; for arm64 jobs that don't compile native code (Python +
# prebuilt arm64 binaries — like sentinelle-gsm), -a arm64 is
# enough to cross-stamp the .deb.
dpkg-buildpackage -us -uc -b -a ${{ matrix.arch }}
#
# Pure-Go packages (CGO_ENABLED=0, GOARCH cross) only need the `go`
# toolchain, which is present via golang-1.22-go. But their
# `Build-Depends: golang-go (>= 1.22)` trips dpkg-checkbuilddeps
# because apt registers golang-1.22-go, not the golang-go
# metapackage, on the runner. Skip the dep check (-d) for just these
# — the compiler is there and the build is self-contained (-mod=vendor).
DEPFLAG=""
case "${{ matrix.package }}" in
secubox-dpi|secubox-toolbox-ng|secubox-waf-ng) DEPFLAG="-d" ;;
esac
dpkg-buildpackage -us -uc -b $DEPFLAG -a ${{ matrix.arch }}
echo "✅ Build OK: ${{ matrix.package }} (${{ matrix.arch }})"

View File

@ -19,7 +19,7 @@ network:
bridges:
br-lan:
interfaces: [lan0, lan1, lan2, lan3]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -44,7 +44,7 @@ network:
bridges:
br-lan:
interfaces: [lan0, lan1]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -37,7 +37,7 @@ network:
# Bridge LAN
br-lan:
interfaces: [eth1, eth3, eth4]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -13,7 +13,7 @@ network:
# LAN — Interface 2 QEMU (si configurée)
enp0s2:
addresses: [192.168.100.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
optional: true

View File

@ -14,7 +14,7 @@ network:
# LAN — Interface 2 VirtualBox (Internal Network ou Host-Only)
enp0s8:
addresses: [192.168.100.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
optional: true

View File

@ -64,7 +64,7 @@ network:
br-lan:
interfaces: []
addresses:
- 192.168.1.1/24
- 192.168.10.1/24
dhcp4: false
optional: true
parameters:

View File

@ -63,7 +63,7 @@ network:
bridges:
br-lan:
interfaces: [enp0s8]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -10,7 +10,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
# ── Version & Build Info ──────────────────────────────────────────
SECUBOX_VERSION="1.9.0"
SECUBOX_VERSION="1.10.0"
BUILD_DATE=$(date '+%Y-%m-%d')
BUILD_TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
@ -310,7 +310,7 @@ network:
bridges:
br-lan:
interfaces: [lan0, lan1]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -26,7 +26,7 @@ LOCAL_REPO_PORT="8080"
SLIPSTREAM_DEBS=1 # Intégrer les .deb locaux dans l'image (default: ON)
# SecuBox versioning
SECUBOX_VERSION="1.9.0"
SECUBOX_VERSION="1.10.0"
BUILD_TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
RED='\033[0;31m'; CYAN='\033[0;36m'; GOLD='\033[0;33m'
@ -643,7 +643,13 @@ EOF
SECUBOX_REPO_OK=1
log "Repo local SecuBox configuré (trusted=yes)"
fi
elif curl -sf "${APT_SECUBOX}/secubox-keyring.gpg" -o "${ROOTFS}/usr/share/keyrings/secubox.gpg" 2>/dev/null; then
elif curl -sf "${APT_SECUBOX}/secubox-keyring.gpg" 2>/dev/null \
| gpg --dearmor > "${ROOTFS}/usr/share/keyrings/secubox.gpg" 2>/dev/null \
&& [ -s "${ROOTFS}/usr/share/keyrings/secubox.gpg" ]; then
# apt's signed-by= requires a DEARMORED (binary) keyring; the published
# secubox-keyring.gpg is ASCII-armored, so dearmor it on the way in.
# Feeding the armored file directly yields "NO_PUBKEY 44E50F0178E8BC7E
# / repository not signed" even though the key is correct.
cat > "${ROOTFS}/etc/apt/sources.list.d/secubox.list" <<EOF
deb [signed-by=/usr/share/keyrings/secubox.gpg] ${APT_SECUBOX} ${SUITE} main
EOF
@ -652,7 +658,13 @@ fi
if [[ $SECUBOX_REPO_OK -eq 1 ]]; then
chroot "${ROOTFS}" apt-get update -q
chroot "${ROOTFS}" apt-get install -y -q secubox-full || warn "secubox-full non disponible"
# Non-interactive conffile handling: secubox-mesh's mesh.toml triggers a dpkg
# conffile prompt that fails the headless chroot install (#USB-build). Keep
# the packaged conffile, never prompt.
chroot "${ROOTFS}" bash -c 'DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
-o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef secubox-full' \
|| warn "secubox-full non disponible"
chroot "${ROOTFS}" dpkg --configure -a --force-confold 2>/dev/null || true
else
warn "APT repo SecuBox non disponible — skip (Phase 4)"
fi
@ -989,7 +1001,7 @@ openssl req -x509 -newkey rsa:2048 -days 365 \
-keyout "${ROOTFS}/etc/secubox/tls/key.pem" \
-out "${ROOTFS}/etc/secubox/tls/cert.pem" \
-nodes -subj "/CN=secubox/O=CyberMind SecuBox/C=FR" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.1.1" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.10.1" \
2>/dev/null
if [[ -f "${ROOTFS}/etc/secubox/tls/cert.pem" ]]; then

View File

@ -376,7 +376,10 @@ EOF
SECUBOX_REPO_OK=1
log "Local SecuBox repo configured (trusted=yes)"
fi
elif curl -sf "${APT_SECUBOX}/secubox-keyring.gpg" -o "${ROOTFS}/usr/share/keyrings/secubox.gpg" 2>/dev/null; then
elif curl -sf "${APT_SECUBOX}/secubox-keyring.gpg" 2>/dev/null \
| gpg --dearmor > "${ROOTFS}/usr/share/keyrings/secubox.gpg" 2>/dev/null \
&& [ -s "${ROOTFS}/usr/share/keyrings/secubox.gpg" ]; then
# apt signed-by= needs a DEARMORED keyring; published key is ASCII-armored.
cat > "${ROOTFS}/etc/apt/sources.list.d/secubox.list" <<EOF
deb [signed-by=/usr/share/keyrings/secubox.gpg] ${APT_SECUBOX} ${SUITE} main
EOF

View File

@ -14,7 +14,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
# ── Version & Build Info ──────────────────────────────────────────
SECUBOX_VERSION="1.9.0"
SECUBOX_VERSION="1.10.0"
BUILD_TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
BUILD_DATE=$(date '+%Y%m%d')
@ -786,7 +786,7 @@ cat > "${ROOTFS}/etc/netplan/00-secubox.yaml" <<'NETPLAN'
# and router-mode br-lan later via secubox-net-* tools.
#
# Earlier versions baked an empty `br-lan` bridge with a static
# 192.168.1.1/24 address into the bootstrap. On bare-metal real
# 192.168.10.1/24 address into the bootstrap. On bare-metal real
# hardware the physical NIC went silent and only the phantom br-lan
# showed an IP — networkd was honouring the static bridge but
# something (predictable rename? secubox-net-detect leftover?)
@ -1226,7 +1226,7 @@ openssl req -x509 -newkey rsa:2048 -days 365 \
-keyout "${ROOTFS}/etc/secubox/tls/key.pem" \
-out "${ROOTFS}/etc/secubox/tls/cert.pem" \
-nodes -subj "/CN=secubox-live/O=CyberMind SecuBox/C=FR" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.1.1" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.10.1" \
2>/dev/null
if [[ -f "${ROOTFS}/etc/secubox/tls/cert.pem" ]]; then
@ -1438,7 +1438,13 @@ else
deb [trusted=yes] ${APT_SECUBOX} ${SUITE} main
EOF
chroot "${ROOTFS}" apt-get update -q
chroot "${ROOTFS}" apt-get install -y -q secubox-full 2>/dev/null || true
# Non-interactive conffile handling: secubox-mesh ships mesh.toml as a
# conffile and triggers a dpkg prompt (*** mesh.toml [Y/I/N/O/D/Z]) during
# configure, which fails the whole install in the headless chroot. Keep the
# packaged conffile and never prompt.
chroot "${ROOTFS}" bash -c 'DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
-o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef secubox-full' 2>/dev/null || true
chroot "${ROOTFS}" dpkg --configure -a --force-confold 2>/dev/null || true
# Verify secubox-core installed (dependency of secubox-full)
if ! chroot "${ROOTFS}" dpkg -l secubox-core 2>/dev/null | grep -q "^ii"; then

View File

@ -331,7 +331,7 @@ network:
bridges:
br-lan:
interfaces: [eth1, eth2, eth3, eth4]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -13,7 +13,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
# ── Version ───────────────────────────────────────────────────────
SECUBOX_VERSION="1.9.0"
SECUBOX_VERSION="1.10.0"
# ── Defaults ──────────────────────────────────────────────────────
SUITE="bookworm"
@ -702,7 +702,7 @@ openssl req -x509 -newkey rsa:2048 -days 365 \
-keyout "${ROOTFS}/etc/secubox/tls/key.pem" \
-out "${ROOTFS}/etc/secubox/tls/cert.pem" \
-nodes -subj "/CN=secubox-rpi/O=CyberMind SecuBox/C=FR" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.1.1" \
-addext "subjectAltName=DNS:localhost,DNS:secubox.local,IP:127.0.0.1,IP:192.168.10.1" \
2>/dev/null
if [[ -f "${ROOTFS}/etc/secubox/tls/cert.pem" ]]; then

View File

@ -359,7 +359,7 @@ if [[ ! -f "${TLS_DIR}/cert.pem" ]]; then
-keyout "${TLS_DIR}/key.pem" \
-out "${TLS_DIR}/cert.pem" \
-nodes -subj "/CN=${HOSTNAME}/O=CyberMind SecuBox/C=FR" \
-addext "subjectAltName=DNS:${HOSTNAME},DNS:secubox.local,IP:192.168.1.1" \
-addext "subjectAltName=DNS:${HOSTNAME},DNS:secubox.local,IP:192.168.10.1" \
2>/dev/null
chown -R secubox:secubox "${TLS_DIR}"
chmod 640 "${TLS_DIR}/key.pem"
@ -378,7 +378,7 @@ log "=== Network Detection ==="
# Short-circuit when the image was built with --static-ip: build-live-usb.sh
# wrote a fixed netplan AND pre-touched /var/lib/secubox/.net-configured.
# Running net-detect here would clobber the static config with router-mode
# defaults (WAN + br-lan 192.168.1.1/24), the exact regression in #128.
# defaults (WAN + br-lan 192.168.10.1/24), the exact regression in #128.
if [[ -f /var/lib/secubox/.net-configured ]]; then
log "Static netplan in effect (.net-configured present) — skipping net-detect"
elif [[ -x /usr/sbin/secubox-net-detect ]]; then

View File

@ -127,7 +127,7 @@ network:
bridges:
br-lan:
interfaces: [lan0, lan1]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
EOF
@ -135,8 +135,8 @@ EOF
cat > "$root/etc/dnsmasq.d/secubox.conf" << 'EOF'
interface=br-lan
bind-interfaces
dhcp-range=192.168.1.100,192.168.1.250,24h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,192.168.1.1
dhcp-range=192.168.10.100,192.168.10.250,24h
dhcp-option=option:router,192.168.10.1
dhcp-option=option:dns-server,192.168.10.1
EOF
}

View File

@ -337,7 +337,7 @@ generate_netplan() {
bridges=" bridges:
br-lan:
interfaces: [${lan_array}]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
optional: true
parameters:
@ -346,7 +346,7 @@ generate_netplan() {
"
else
# No LAN interfaces — DON'T create an empty br-lan with
# 192.168.1.1/24. A member-less bridge with a static IP
# 192.168.10.1/24. A member-less bridge with a static IP
# squats the .1 address without routing anything, makes
# systemd-networkd think the interface is "configured",
# and frequently breaks DHCP on the real WAN NIC (the

View File

@ -1754,7 +1754,7 @@ async def preview_network_mode(mode: str, user=Depends(require_jwt)):
bridges:
br-lan:
interfaces: [{lan_str}]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
"""
elif mode in ("sniffer-inline", "sniffer-passive"):

View File

@ -526,7 +526,7 @@ network:
bridges:
br-lan:
interfaces: [{lan_list}]
addresses: [192.168.1.1/24]
addresses: [192.168.10.1/24]
dhcp4: false
parameters:
stp: false

View File

@ -9,13 +9,13 @@ network:
dhcp6: false
{{ lan | default('eth1') }}:
addresses:
- 192.168.100.1/24
- 192.168.10.1/24
bridges:
br0:
interfaces:
- {{ lan | default('eth1') }}
addresses:
- 192.168.100.1/24
- 192.168.10.1/24
dhcp4: false
parameters:
stp: false

View File

@ -628,6 +628,10 @@ async def get_status():
threats = load_json(THREATS_FILE, {})
peers = peers_data.get("peers", []) if isinstance(peers_data, dict) else peers_data
# A node is not its own peer — exclude the local entry from the counts
# (older versions persisted get_self_peer() into PEERS_FILE, inflating these).
local_id = get_node_id()
peers = [p for p in peers if not p.get("is_local") and p.get("id") != local_id]
online_peers = [p for p in peers if p.get("status") == "online"]
# Get master-link status
@ -699,13 +703,12 @@ async def list_peers():
peers_data = load_json(PEERS_FILE, {"peers": []})
peers = peers_data.get("peers", []) if isinstance(peers_data, dict) else peers_data
# Ensure local node is in the list
# A node is not its own peer: never insert/persist the local node here.
# (Older versions did, which inflated peer_count and listed "<host> (local)"
# as a phantom peer.) Drop any self entry a prior version may have saved.
# Use /discover/self for the local node's announcement payload instead.
local_id = get_node_id()
has_local = any(p.get("id") == local_id or p.get("is_local") for p in peers)
if not has_local:
peers.insert(0, get_self_peer())
save_json(PEERS_FILE, {"peers": peers})
peers = [p for p in peers if not p.get("is_local") and p.get("id") != local_id]
return {"peers": peers, "count": len(peers)}

View File

@ -1,3 +1,39 @@
secubox-p2p (1.7.5-1~bookworm1) bookworm; urgency=medium
* sbx-mesh-invite: re-own the master-link token store to secubox when run as
root. A root-owned tokens.json made the secubox-user services (incl. the
in-process aggregator) crash with EACCES, taking down the API.
-- Gerald KERMA <devel@cybermind.fr> Sun, 28 Jun 2026 07:30:00 +0000
secubox-p2p (1.7.4-1~bookworm1) bookworm; urgency=medium
* Stop counting/listing the local node as a peer. /peers no longer inserts
and persists get_self_peer() into PEERS_FILE (it inflated peer_count and
showed "<host> (local)" as a phantom online peer); /status and /peers now
exclude the local entry. Use /discover/self for the local announcement.
-- Gerald KERMA <devel@cybermind.fr> Sun, 28 Jun 2026 07:00:00 +0000
secubox-p2p (1.7.3-1~bookworm1) bookworm; urgency=medium
* Install the p2p + master-link web UIs to /usr/share/secubox/www/ (the
dashboard's served root, like every other module) instead of
/var/www/secubox/. They were unreachable -> the dashboard rendered
"Module Not Found" for /p2p/. nginx alias paths updated to match.
-- Gerald KERMA <devel@cybermind.fr> Sun, 28 Jun 2026 06:45:00 +0000
secubox-p2p (1.7.2-1~bookworm1) bookworm; urgency=medium
* postinst: create /var/lib/secubox/p2p and master-link/ owned by secubox
(and repair pre-existing root-owned installs on upgrade). The master-link
init mkdir'd master-link/ and failed EACCES when p2p/ was root-owned,
500-ing /api/v1/p2p/status and blocking mesh enrollment. Does NOT chown
the shared /var/lib/secubox parent (#494/#511).
-- Gerald KERMA <devel@cybermind.fr> Sun, 28 Jun 2026 06:30:00 +0000
secubox-p2p (1.7.1-1~bookworm1) bookworm; urgency=medium
* #494/#511: postinst no longer chowns the shared parents /run/secubox and

View File

@ -18,6 +18,16 @@ case "$1" in
mkdir -p /var/log/secubox
install -d -o secubox -g secubox -m 0750 /var/log/secubox/p2p
# State dir: own p2p/ and the master-link store, but NEVER chown the
# shared /var/lib/secubox parent (#494/#511). The app's master-link
# init mkdir's master-link/ and fails EACCES when p2p/ is root-owned,
# 500-ing /api/v1/p2p/status and breaking mesh enrollment. chown too so
# pre-existing root-owned installs are repaired on upgrade.
mkdir -p /var/lib/secubox
install -d -o secubox -g secubox -m 0755 /var/lib/secubox/p2p
install -d -o secubox -g secubox -m 0755 /var/lib/secubox/p2p/master-link
chown secubox:secubox /var/lib/secubox/p2p /var/lib/secubox/p2p/master-link 2>/dev/null || true
# Enable and start the service
systemctl daemon-reload
systemctl enable secubox-p2p.service

View File

@ -9,12 +9,12 @@ override_dh_auto_install:
cp -r $(CURDIR)/api/* $(CURDIR)/debian/secubox-p2p/usr/lib/secubox/p2p/api/
# Install web interface
install -d $(CURDIR)/debian/secubox-p2p/var/www/secubox/p2p
cp -r $(CURDIR)/www/p2p/* $(CURDIR)/debian/secubox-p2p/var/www/secubox/p2p/
install -d $(CURDIR)/debian/secubox-p2p/usr/share/secubox/www/p2p
cp -r $(CURDIR)/www/p2p/* $(CURDIR)/debian/secubox-p2p/usr/share/secubox/www/p2p/
# Install master-link join page
install -d $(CURDIR)/debian/secubox-p2p/var/www/secubox/master-link
cp -r $(CURDIR)/www/master-link/* $(CURDIR)/debian/secubox-p2p/var/www/secubox/master-link/
install -d $(CURDIR)/debian/secubox-p2p/usr/share/secubox/www/master-link
cp -r $(CURDIR)/www/master-link/* $(CURDIR)/debian/secubox-p2p/usr/share/secubox/www/master-link/
# Install nginx configuration
install -d $(CURDIR)/debian/secubox-p2p/etc/nginx/secubox.d

View File

@ -16,14 +16,14 @@ location /api/v1/p2p/ {
# P2P static files
location /p2p/ {
alias /var/www/secubox/p2p/;
alias /usr/share/secubox/www/p2p/;
index index.html;
try_files $uri $uri/ /p2p/index.html;
}
# Master-Link join page (accessible without auth for new nodes)
location /master-link/ {
alias /var/www/secubox/master-link/;
alias /usr/share/secubox/www/master-link/;
index index.html;
try_files $uri $uri/ /master-link/index.html;
}

View File

@ -151,6 +151,14 @@ else
echo "[$NEW_TOKEN]" > "$TOKENS_FILE"
fi
# secubox-p2p / the aggregator's in-process p2p run as user 'secubox' and read
# this token store. sbx-mesh-invite is often run as root, which would leave
# tokens.json root-owned -> the secubox services crash with EACCES (this took
# down the in-process aggregator once). Re-own the store when running as root.
if [ "$(id -u)" = "0" ]; then
chown -R secubox:secubox "$(dirname "$TOKENS_FILE")" 2>/dev/null || true
fi
# Output the invite
echo ""
echo "╔══════════════════════════════════════════════════════════════════╗"

View File

@ -47,7 +47,8 @@ if [[ -z "${SKIP_CHROOT:-}" ]]; then
log " debootstrap failed (network?) — skipping chroot test"
else
sudo install -d -m 0755 "$CHROOT/etc/apt/sources.list.d" "$CHROOT/usr/share/keyrings"
sudo install -m 0644 "$OUT/secubox-keyring.gpg" "$CHROOT/usr/share/keyrings/secubox.gpg"
# dearmor: apt signed-by= needs a binary keyring, not the ASCII-armored export
gpg --dearmor < "$OUT/secubox-keyring.gpg" | sudo tee "$CHROOT/usr/share/keyrings/secubox.gpg" >/dev/null
echo "deb [signed-by=/usr/share/keyrings/secubox.gpg] file://$OUT $SUITE main" \
| sudo tee "$CHROOT/etc/apt/sources.list.d/secubox.list" >/dev/null
sudo mkdir -p "$CHROOT$OUT"