Compare commits

...
13 Commits
Author SHA1 Message Date
gandalf 2ddb28d2dc fix(net-detect): no empty br-lan when LAN ifaces list is empty
secubox-net-detect.service runs on first boot (gated by
!/var/lib/secubox/.net-configured) and REWRITES /etc/netplan/00-secubox.yaml
based on the detected board layout. The "no LAN interfaces" branch
in generate_netplan() was emitting an empty br-lan bridge with a
static 192.168.1.1/24 address. On single-NIC live USB hardware that
made systemd-networkd happily honour the phantom bridge while the
real WAN NIC fell off the DHCP path — the operator saw a working
br-lan in `ip a` but no upstream IP and no internet.

Same shape of bug as the v2.12.7 build-live-usb.sh static-in-DHCP
regression (commit a88c1773): a useless static IP on a non-routing
interface confused networkd into "I'm done, no DHCP needed". Fix:
when there are no LAN interfaces, emit NO bridges block at all.
Operators wire br-lan later via secubox-net-* tools once they've
decided the box is a router vs an endpoint.
2026-05-26 11:56:28 +02:00
gandalf 24000d67ea fix(services): add RuntimeDirectoryPreserve=yes to 96 secubox-* units
Hub + portal stayed `inactive (dead)` on real-hardware boot. The
journal error was `Failed to set up mount namespacing: /run/systemd/
unit-root/run/secubox: No such file or directory` at the NAMESPACE
step. Root cause: 96 services declare `RuntimeDirectory=secubox`
without the matching `RuntimeDirectoryPreserve=yes`. When any of them
stops (including any of the LXC-backed services that fail their
health probe and Restart=on-failure for a few cycles), systemd
removes /run/secubox on the way out. The next service with the same
RuntimeDirectory= that tries to namespace its inputs hits the gap
and falls into 226/NAMESPACE failure — Restart hammers a few times,
then the unit goes failed-permanent.

Earlier fmrelay + sentinelle units got the fix individually
(v2.12.0/v2.12.3 era). Now applied to all 96 remaining units in a
single sweep via:

  sed -i '/^RuntimeDirectory=secubox/a RuntimeDirectoryPreserve=yes' "$f"

No version bumps in changelog — `dpkg -i --force-depends` in the
live-USB slipstream picks up the new .deb regardless of version
number.
2026-05-26 09:50:22 +02:00
gandalf 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
gandalf 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
gandalf f61932c6c6 revert(live-usb): restore v2.10.3 verbatim GRUB EFI + label-based search
Real UEFI hardware kept landing in grub rescue / grub shell across every
v2.12.x iteration: shim swap, hardened module list, $cmdpath embed,
search --fs-uuid bake-in. None of them shipped a working real-UEFI
boot. v2.10.3 was the last tag the operator confirmed booted his
hardware in both BIOS and UEFI mode.

Drop the experimental UUID capture + the embed-cfg fallback chain.
Restore EXACTLY what v2.10.3 had:

  # embed-cfg
  search --no-floppy --label ESP --set=root
  set prefix=($root)/boot/grub
  configfile $prefix/grub.cfg

  # main grub.cfg LIVE search
  search --no-floppy --label LIVE --set=live

Validated other v2.12.x improvements stay (mass-mask LXC services,
dynamic MOTD, modesetting for VBox, kiosk --no-block) — they don't
touch the boot path.
2026-05-25 17:18:42 +02:00
gandalf ff806523b7 fix(live-usb): use baked-in UUIDs for ESP/LIVE search (label lookups fail on real HW)
Real UEFI hardware v2.12.7/v2.12.8 still landed in the grub> rescue
shell, and the user reported the same happening in legacy BIOS mode
too — both code paths share the /boot/grub/grub.cfg which begins with
`search --no-floppy --label LIVE --set=live`. If that label lookup
fails (some firmware doesn't surface FAT/ext4 labels, or the firmware
exposes the disk through a path GRUB's label table doesn't recognise)
\$live stays unset, every menuentry's `linux (\$live)/live/vmlinuz`
becomes `linux ()/live/vmlinuz`, the kernel doesn't load, GRUB
drops the operator at the rescue prompt. Same root cause as the
EFI embed-cfg's `search --label ESP` failure.

Capture the ESP + LIVE UUIDs with blkid right after mkfs.* and
substitute them into both configs:

  * grub.cfg uses `search --fs-uuid <LIVE_UUID> --set=live` as
    primary; falls back to `search --label LIVE` for firmware that
    DOES prefer labels (no-op if UUID already resolved).
  * embed-cfg uses `\$cmdpath/grub.cfg` first, then falls back to
    `search --fs-uuid <ESP_UUID>` + configfile from that root.

UUIDs are deterministic at build time, can't be shadowed by similarly
labelled partitions, and don't depend on the firmware's label
indexing — should work on any firmware that surfaces the disk to
GRUB's block IO at all.
2026-05-25 15:48:34 +02:00
gandalf dcb4ce828b fix(live-usb): EFI embed uses \$cmdpath so it doesn't depend on label search
Real UEFI hardware v2.12.7 reported landing at the grub> rescue
prompt even with the simple pre-e1a53297 embed-cfg restored. Cause:
`search --no-floppy --label ESP --set=root` failed silently on that
firmware (FAT label not recognised, predictable rename, etc.), so
\$root stayed unset, prefix was empty, configfile fell through to
the rescue shell.

Replace the embed with a single-line `configfile \$cmdpath/grub.cfg`.
\$cmdpath is set by the EFI firmware itself to the directory it
loaded BOOTX64.EFI from — for us that's (hdX,gptY)/EFI/BOOT, where
the build copies grub.cfg already. The full menu at /EFI/BOOT/grub.cfg
still does its own `search --label LIVE --set=live` to locate the
squashfs partition (unchanged), so this only changes the very first
lookup hop.

Legacy BIOS grub-install --target=i386-pc untouched — it never had
the issue.
2026-05-25 11:00:44 +02:00
gandalf a88c177372 fix(live-usb): simplify bootstrap netplan — DHCP on e* only
Real-hardware report: only the phantom `br-lan` (interfaces: [] +
static 192.168.1.1/24) showed an IP, the physical ethernet stayed
sec. The old netplan declared three separate interface groups
(en*, eth*, all-wifi with empty SSID) plus a member-less bridge with
a static address — that was enough to confuse networkd into
honouring the bridge while dropping the real DHCP request on the
floor.

Cut to the bone: one `eth-all` block matching `e*` (which covers
enpXsY, enoX, ensX, enxAABBCC and ethX), DHCP only, no static, no
bridge, no wifi-with-empty-SSID. Operators wire router-mode br-lan
or wifi later via the secubox-net-* tooling once they've decided
this is an endpoint vs a router.

For the no-DHCP fallback case, secubox-net-fallback.service is
already shipped and runs after networkd to ARP-probe common gateways
and assign a free .250 IP — that remains unchanged.

This means v2.12.6 has both a clean EFI build AND a netplan that
actually requests DHCP on the physical NIC instead of squatting on
the bridge.
2026-05-25 09:40:57 +02:00
gandalf 36612f622d revert(live-usb): restore simple GRUB EFI build (pre-e1a53297)
Real UEFI hardware boot was broken by my e1a53297 "hardening" — the
gold-plated module list (disk/usb/usbms/ahci/ata/...) and multi-stage
embed-cfg search fallback that I added to chase a VBox EFI Shell drop
turned out to break legitimate UEFI firmware too. None of those
modules exist in x86_64-efi (block IO comes from the EFI firmware
itself), and the if/else cmdpath fallback landed users in a `grub>`
rescue shell on hardware that worked fine with the original config.

Revert the EFI section to the v2.10.x layout that v2.10/v2.11 booted
cleanly on real amd64 boxes: 14 modules, single-line search, plain
grub-mkimage with no compress/no Secure Boot shim. Also drop the
shim-signed + grub-efi-amd64-signed from the host apt install — they
were only there to feed the SB swap that's now removed.

VBox EFI drops to the GRUB rescue shell with this config; that's
acceptable per operator direction ("je m'en fous de booter en legacy
sur vbox, ca marche sur real hw") — VBox testing has always used the
BIOS firmware path which still works perfectly.
2026-05-25 09:39:15 +02:00
gandalf 930a885f04 fix(kiosk): --no-block start so firstboot.sh's enable doesn't deadlock
Live USB v2.12.4 boot showed `secubox-kiosk-setup enable --x11` running
for 5+ minutes while the kiosk.service stayed `inactive (dead)`. The
synchronous `systemctl start secubox-kiosk.service` at the end of
enable_kiosk was hanging.

Root cause: secubox-kiosk.service declares
  Conflicts=getty@tty7.service
  TTYPath=/dev/tty7

systemd waits for tty7 to be released and for the conflicting unit's
JobsToStart to clear before kiosk's ExecStart can fire. When the call
comes from a process running inside the tty1 autologin shell (which
is what firstboot.sh's `secubox-kiosk-setup enable --x11` safety net
does), systemd deadlocks itself waiting on a tty operation the caller
can't unblock. The kiosk service appears to start fine when triggered
manually from SSH (proven during debug — once the stuck setup PID was
killed, `systemctl start secubox-kiosk.service` returned in <1s and
the service activated cleanly).

Fix: pass --no-block so systemctl returns as soon as the job is
queued, regardless of the tty wait. systemd then runs the start in
the background after the parent autologin shell exits, breaking the
loop. The exit-code branch is preserved for legitimate failures.
2026-05-25 08:59:28 +02:00
gandalf 24d6f28dab fix(live-usb): IP shown live in MOTD + modesetting fallback for VBox kiosk
Three regressions surfaced on the v2.12.3 live USB amd64 boot console:

1. /etc/issue + /etc/motd had `<IP>` as literal text — nothing was
   substituting at runtime, so operators saw `https://<IP>:9443`
   instead of the actual address. The bashrc splash showed real IP
   via `hostname -I` but was masked by the static MOTD on top.

   Fixes:
   * /etc/issue: switch to getty's `\4` escape (resolves to first
     IPv4 address at TTY render time).
   * /etc/motd: blank out the static file + ship the banner as
     /etc/update-motd.d/10-secubox, which pam_motd regenerates on
     every interactive login. The script substitutes the live
     `hostname -I` first address (falls back to `no-ip` while DHCP
     hasn't completed).

2. Kiosk Xorg failed under VirtualBox VMSVGA. The auto-detect picked
   the `vmware` Xorg driver, which loads vmwgfx kernel module — vmwgfx
   tries to talk to a VMware Workstation host channel that doesn't
   exist on VBox, prints "Failed to send host log message" then
   bails. The kiosk launcher then logs Xorg failure, retries 3 times,
   self-disables. Operator sees no kiosk even after running
   `secubox-kiosk-setup enable` (because the launcher disabled the
   sentinel again).

   Fix: secubox-x11-setup unconditionally picks `modesetting` on
   oracle (VirtualBox), regardless of VMSVGA vs VBoxVGA. modesetting
   uses DRM/KMS through vmwgfx but skips the broken host channel.
   Real VMware Workstation users (VM_TYPE=vmware) still get `vmware`
   via the dedicated case branch — only the VBox path changed.

Note: didn't tag yet — wait for user retest after CI rebuilds. If the
boot console comes up with the right IP + the kiosk paints pixels, we
tag v2.12.4 next.
2026-05-25 08:10:28 +02:00
gandalf faa5f5d84a fix(live-usb): drop netplan static-in-DHCP (regressed all IPs) + mass-mask LXC modules
VBox + bare-metal v2.12.2 amd64 tests showed the live USB had no IP at
all (DHCP nor static fallback worked) and ~10 [FAILED] secubox-*
services on the boot console.

Two independent fixes layered together:

1. Inline netplan: my v2.12.1 commit (27645f0a) baked
   `addresses: [192.168.1.55/24]` + gw 192.168.1.254 into both
   eth-dhcp (match en*) and eth-legacy (match eth*). On a single-NIC
   box both interface defs match the same kernel interface and try to
   claim 192.168.1.55 simultaneously → systemd-networkd refuses the
   apply and the link gets NO IP at all. Even DHCP was broken.

   Drop the static block entirely; let secubox-net-fallback.service
   (already shipped, runs after networkd) handle the no-DHCP case via
   ARP-probe gateway discovery + free .250 IP assignment.

2. INCOMPLETE_MODULES list: extended with the host-side control planes
   that proxy to an LXC container — without `install-lxc.sh` having
   run, the container at 10.100.0.X doesn't exist, the health probe
   fails immediately, and Restart=on-failure spins the service into a
   FAILED loop that fills the console and blocks multi-user.target.

   Added: grafana, yacy, rustdesk, lyrion, authelia (host), mail,
   gitea, matrix, horde, mitmproxy, nextcloud, rbs-sensor.

   Operator workflow stays unchanged on real installs: run
   `bash install-lxc.sh` to provision the container, then
   `systemctl unmask secubox-<name>` + enable + start.
2026-05-25 07:00:20 +02:00
gandalf 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
92 changed files with 216 additions and 194 deletions
+91 -181
View File
@@ -141,8 +141,7 @@ fi
# Required tools
log "Checking dependencies..."
apt-get install -y -qq debootstrap squashfs-tools \
grub-efi-amd64-bin grub-efi-amd64-signed grub-pc-bin shim-signed \
apt-get install -y -qq debootstrap squashfs-tools grub-efi-amd64-bin grub-pc-bin \
xorriso mtools dosfstools parted e2fsprogs live-boot 2>/dev/null || true
for cmd in debootstrap parted mkfs.fat mkfs.ext4 mksquashfs grub-mkimage; do
@@ -781,103 +780,37 @@ else
# Uses two separate match patterns to avoid conflicts when multiple interfaces match
# secubox-net-detect.service will generate proper config at first boot
cat > "${ROOTFS}/etc/netplan/00-secubox.yaml" <<'NETPLAN'
# /etc/netplan/00-secubox.yaml — SecuBox Live USB (Bare Metal) — Bootstrap Config
# This is a minimal bootstrap configuration for real AMD64 hardware.
# secubox-net-detect.service will generate the proper config at first boot.
# /etc/netplan/00-secubox.yaml — SecuBox Live USB bootstrap.
#
# Strategy: Enable DHCP on ALL detected Ethernet interfaces initially.
# secubox-net-detect will refine this to router mode (WAN + br-lan).
# DHCP on every ethernet interface. That's it. Operators wire WiFi
# 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
# 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?)
# stopped the DHCP request reaching the real cable. Stripping the
# bridge + the wifi-with-empty-SSID block restores classic DHCP.
# secubox-net-detect.service (disabled by default, no .wants/ link)
# can still be run by hand once the operator has decided whether
# this box is a router vs an endpoint.
network:
version: 2
renderer: networkd
ethernets:
# Bootstrap: Enable DHCP on all ethernet interfaces for initial connectivity
# This ensures we get an IP regardless of interface naming (eno1, enp2s0, etc.)
# After first boot, secubox-net-detect rewrites this with proper WAN/LAN split.
# Match modern interface patterns (enp*, eno*, ens*, enx*).
# WAN fallback (closes #370): static 192.168.1.55/24 + gw
# 192.168.1.254 carried alongside DHCP. systemd-networkd accepts
# both — DHCP routes get the low metric (100), the static gets
# metric 1000, so DHCP wins when available and the static keeps
# the appliance reachable when DHCP fails. Caveat: if multiple
# interfaces match, both will try to claim 192.168.1.55 and one
# will fail with address-in-use; bare-metal boxes typically have
# one primary NIC, and multi-NIC operators run net-detect to
# refine the layout anyway.
eth-dhcp:
# Match everything that *looks* like ethernet — covers enpXsY /
# enoX / ensX / enxAABBCC (USB ethernet) / ethX. All get DHCP.
eth-all:
match:
name: "en*"
name: "e*"
dhcp4: true
dhcp6: false
dhcp4-overrides:
use-dns: true
use-routes: true
route-metric: 100
optional: true
addresses: [192.168.1.55/24]
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
routes:
- to: default
via: 192.168.1.254
metric: 1000
# Match legacy interface patterns (eth0, eth1, etc.) — same static
# WAN fallback rationale.
eth-legacy:
match:
name: "eth*"
dhcp4: true
dhcp6: false
dhcp4-overrides:
use-dns: true
use-routes: true
route-metric: 200
optional: true
addresses: [192.168.1.55/24]
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
routes:
- to: default
via: 192.168.1.254
metric: 1000
wifis:
# All WiFi interfaces (wlp*, wlan*, wl*)
all-wifi:
match:
name: "wl*"
dhcp4: true
dhcp4-overrides:
route-metric: 300
use-dns: true
use-routes: true
optional: true
access-points:
# Open networks (fallback)
"": {}
bridges:
# br-lan: Pre-defined but empty - secubox-net-detect populates interfaces
br-lan:
interfaces: []
addresses:
- 192.168.1.1/24
dhcp4: false
optional: true
parameters:
stp: false
forward-delay: 0
# Note: At first boot, secubox-net-detect.service will:
# 1. Detect board type (x64-baremetal) and available interfaces
# 2. Determine WAN (first interface with link/DHCP response)
# 3. Assign remaining interfaces to br-lan
# 4. Rewrite this file with explicit interface names
#
# To force re-detection: rm /var/lib/secubox/.net-configured && reboot
NETPLAN
chmod 600 "${ROOTFS}/etc/netplan/00-secubox.yaml"
fi # end static-IP branch
@@ -2241,17 +2174,17 @@ DRIVER="modesetting" # Safe default
case "$VM_TYPE" in
oracle)
# VirtualBox - check graphics controller type
if echo "$GPU_INFO" | grep -qi "SVGA\|VMware"; then
# VMSVGA controller (default in VBox 6+) - use vmware driver
DRIVER="vmware"
log "VirtualBox VMSVGA detected → vmware driver"
else
# VBoxVGA or VBoxSVGA - modesetting works
DRIVER="modesetting"
log "VirtualBox VBoxVGA detected → modesetting driver"
fi
# Load VirtualBox kernel modules
# VirtualBox: use modesetting unconditionally. The previous
# "vmware" branch for VMSVGA controllers triggered vmwgfx kernel
# ERRORs ("Failed to send host log message") because vmwgfx
# expects a real VMware Workstation host — on VBox it half-loads
# then fails on the Xorg side, kiosk launcher gives up after 3
# retries and self-disables. modesetting talks DRM/KMS through
# the same vmwgfx kmod but ignores the broken host channel and
# actually paints pixels.
DRIVER="modesetting"
log "VirtualBox detected → modesetting driver (works for both VMSVGA + VBoxVGA)"
# Load VirtualBox kernel modules so Guest Additions integration works
modprobe vboxguest 2>/dev/null || true
modprobe vboxvideo 2>/dev/null || true
;;
@@ -2803,6 +2736,31 @@ INCOMPLETE_MODULES=(
secubox-newsbin
secubox-ui-manager
secubox-ui-health
# Hardware-gated modules — restart-storm on live USB without the
# physical RTL-SDR + GSM modem present. Operators install + enable
# them by hand once they wire the SDR / EP06.
secubox-sentinelle-gsm
secubox-fmrelay
# LXC-backed modules — their host control plane immediately tries to
# probe the container at 10.100.0.X over the br-lxc bridge. On live
# USB the LXC stack isn't initialised + the container doesn't exist,
# so the service fails the health probe and goes into restart-fail
# loop. Filled the boot console with [FAILED] lines and held up the
# multi-user target. Operators run install-lxc.sh once on a real
# install to provision the container, then `secubox-lxc-modules
# enable <name>` to lift the mask.
secubox-grafana
secubox-yacy
secubox-rustdesk
secubox-lyrion
secubox-authelia
secubox-mail
secubox-gitea
secubox-matrix
secubox-horde
secubox-mitmproxy
secubox-nextcloud
secubox-rbs-sensor
)
for svc in "${INCOMPLETE_MODULES[@]}"; do
chroot "${ROOTFS}" systemctl disable ${svc}.service 2>/dev/null || true
@@ -2994,14 +2952,25 @@ printf '%b' "\e[38;5;29m
\e[38;5;242m Build: ${BUILD_TIMESTAMP}\e[0m
\e[38;5;250m 🔐 Default: \e[38;5;214mroot\e[38;5;250m / \e[38;5;214msecubox\e[0m
\e[38;5;250m 🌐 Web UI: \e[38;5;45mhttps://<IP>:9443\e[0m
\e[38;5;250m 🌐 Web UI: \e[38;5;45mhttps://\\4:9443\e[0m
\e[38;5;250m 📡 SSH: \e[38;5;45mport 22\e[0m
\e[38;5;242m─────────────────────────────────────────────────────────────\e[0m
" > "${ROOTFS}/etc/issue"
# Post-login MOTD - use printf %b for real escape sequences
# Post-login MOTD via update-motd.d so the IP can be substituted live
# at login time (pam_motd runs /etc/update-motd.d/* on every interactive
# session). Static /etc/motd kept blank — without it, pam_motd printed
# the literal `<IP>:9443` because nothing was substituting the placeholder.
# Operators see the box's actual IPv4 (or `no-ip` when DHCP hasn't fired).
: > "${ROOTFS}/etc/motd"
mkdir -p "${ROOTFS}/etc/update-motd.d"
cat > "${ROOTFS}/etc/update-motd.d/10-secubox" <<MOTD_DYN
#!/bin/sh
# Generated by build-live-usb.sh — dynamic MOTD with live IP.
ip=\$(hostname -I 2>/dev/null | awk '{print \$1}')
[ -z "\$ip" ] && ip="no-ip"
printf '%b' "\e[38;5;214m
╔═══════════════════════════════════════════════════════════════╗
║\e[38;5;45m ███████╗███████╗ ██████╗██╗ ██╗██████╗ ██████╗ ██╗ ██╗ \e[38;5;214m║
@@ -3015,13 +2984,15 @@ printf '%b' "\e[38;5;214m
\e[38;5;242m Build: ${BUILD_TIMESTAMP}\e[0m
\e[38;5;250m 🌐 Web UI: \e[38;5;45mhttps://<IP>:9443\e[0m
\e[38;5;250m 🌐 Web UI: \e[38;5;45mhttps://\${ip}:9443\e[0m
\e[38;5;250m 🔐 Credentials: \e[38;5;214mroot\e[38;5;250m / \e[38;5;214msecubox\e[0m
\e[38;5;250m 📖 Docs: \e[38;5;45mhttps://secubox.in/docs\e[0m
\e[38;5;242m Type \e[38;5;82msecubox-status\e[38;5;242m for system overview\e[0m
" > "${ROOTFS}/etc/motd"
"
MOTD_DYN
chmod +x "${ROOTFS}/etc/update-motd.d/10-secubox"
# Dynamic status script for interactive use
cat > "${ROOTFS}/usr/bin/secubox-status" <<'STATUS_SCRIPT'
@@ -3550,6 +3521,7 @@ else
fi
fi
# Mount for file copy
MNT="${WORK_DIR}/mnt"
mkdir -p "${MNT}/esp" "${MNT}/live"
@@ -3717,103 +3689,41 @@ fi
cp "${MNT}/esp/boot/grub/grub.cfg" "${MNT}/esp/EFI/BOOT/grub.cfg"
# ── Build GRUB EFI ────────────────────────────────────────────────────────
# Module set tuned for booting from a USB stick / VM disk under both
# OVMF (VirtualBox + qemu) and real UEFI firmware. The list MUST include
# `disk`, `usb`, `usbms` so the firmware can hand off block IO; without
# them OVMF drops to the EFI Shell PXE prompt instead of loading GRUB
# (this was the v2.12.0/v2.12.1 regression — see issue #382 followup).
GRUB_MODS="part_gpt part_msdos fat ext2 ntfs iso9660 normal linux boot \
configfile loopback chain efi_gop efi_uga ls cat echo test help \
search search_label search_fs_uuid search_fs_file \
gfxterm gfxterm_background all_video gzio png jpeg font \
fat exfat read sleep reboot halt true \
disk usb usbms ahci ata loadenv minicmd terminal"
# Build GRUB EFI — verbatim from v2.10.3 (last known-good real UEFI
# boot). Do NOT optimise this block: every "improvement" attempted in
# the v2.12.x series (Secure Boot shim, $cmdpath, search --fs-uuid,
# extra modules, multi-stage fallbacks) broke at least one piece of
# hardware. Stay simple, stay shipped.
GRUB_MODS="part_gpt part_msdos fat ext2 normal linux boot configfile loopback chain efi_gop efi_uga ls search search_label gfxterm all_video"
cat > "${WORK_DIR}/grub-embed.cfg" <<'EMBEDCFG'
# Fallback chain — label first (set by mkfs.fat -n ESP), then UUID,
# then EFI's $cmdpath (the directory the .EFI was loaded from). Last
# resort: hardcode the relative prefix so configfile can still find the
# menu even if no var resolution worked.
search --no-floppy --label ESP --set=root --no-floppy
if [ -z "$root" ]; then
search --no-floppy --label LIVE --set=root --no-floppy
fi
if [ -n "$root" ]; then
set prefix=($root)/boot/grub
else
set prefix=($cmdpath)/../../boot/grub
fi
search --no-floppy --label ESP --set=root
set prefix=($root)/boot/grub
configfile $prefix/grub.cfg
EMBEDCFG
# Build the EFI binary. Bail loudly if grub-mkimage fails — silent
# failure leaves the ESP without BOOTX64.EFI and the box drops to PXE
# at first boot, which is exactly the bug we just hit.
if ! grub-mkimage -o "${MNT}/esp/EFI/BOOT/BOOTX64.EFI" \
-O x86_64-efi \
-c "${WORK_DIR}/grub-embed.cfg" \
-p /boot/grub \
--compress=xz \
${GRUB_MODS}; then
err "grub-mkimage failed — the image will not boot under EFI"
fi
[[ -s "${MNT}/esp/EFI/BOOT/BOOTX64.EFI" ]] || err "BOOTX64.EFI missing or empty after grub-mkimage"
EFI_SIZE=$(stat -c%s "${MNT}/esp/EFI/BOOT/BOOTX64.EFI")
ok "BOOTX64.EFI built (${EFI_SIZE} bytes)"
grub-mkimage -o "${MNT}/esp/EFI/BOOT/BOOTX64.EFI" \
-O x86_64-efi \
-c "${WORK_DIR}/grub-embed.cfg" \
-p /boot/grub \
${GRUB_MODS}
# Mirror to /EFI/BOOT/grubx64.efi (some firmware looks for this name)
# and to /EFI/secubox/grubx64.efi (lets `efibootmgr` register a named
# entry once the live system is running, without clobbering /BOOT).
cp "${MNT}/esp/EFI/BOOT/BOOTX64.EFI" "${MNT}/esp/EFI/BOOT/grubx64.efi"
mkdir -p "${MNT}/esp/EFI/secubox"
cp "${MNT}/esp/EFI/BOOT/BOOTX64.EFI" "${MNT}/esp/EFI/secubox/grubx64.efi"
# Secure Boot: ship the Debian-signed shim + grub if they're available
# on the builder. shim is what Microsoft trusts; it then verifies the
# signed grubx64.efi we copy alongside. Firmware looks for
# /EFI/BOOT/BOOTX64.EFI first, so when shim is present, point that at
# shim and let it chainload grub.
SHIM_SRC="/usr/lib/shim/shimx64.efi.signed"
GRUB_SIGNED_SRC="/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed"
if [[ -f "$SHIM_SRC" && -f "$GRUB_SIGNED_SRC" ]]; then
log "Secure Boot assets present — installing shim as BOOTX64.EFI"
cp "$SHIM_SRC" "${MNT}/esp/EFI/BOOT/BOOTX64.EFI"
cp "$GRUB_SIGNED_SRC" "${MNT}/esp/EFI/BOOT/grubx64.efi"
cp "$GRUB_SIGNED_SRC" "${MNT}/esp/EFI/secubox/grubx64.efi"
ok "Secure Boot shim wired (shimx64 -> grubx64.efi.signed)"
else
warn "Secure Boot shim not found — image won't boot with SB on"
warn " missing: $SHIM_SRC OR $GRUB_SIGNED_SRC"
warn " (install: apt-get install shim-signed grub-efi-amd64-signed)"
fi
# EFI shell fallback — some OVMF builds drop into the shell on first
# boot if no BootOrder is set. startup.nsh auto-runs the bootloader.
# Add startup.nsh for EFI shell auto-boot (VirtualBox/OVMF compatibility)
cat > "${MNT}/esp/startup.nsh" <<'STARTUPNSH'
@echo -off
echo "SecuBox Live — handing off to BOOTX64.EFI..."
\EFI\BOOT\BOOTX64.EFI
STARTUPNSH
# Copy GRUB modules — only the bits BOOTX64.EFI's embedded prefix
# might want to load on demand. Failure is non-fatal: we statically
# linked everything we need above, this is belt-and-suspenders.
# Copy GRUB modules
cp /usr/lib/grub/x86_64-efi/*.mod "${MNT}/esp/boot/grub/x86_64-efi/" 2>/dev/null || true
# ── BIOS GRUB ──────────────────────────────────────────────────────────────
# Fail loudly here too — BIOS-only systems (older laptops, VBox legacy
# default) silently won't boot if i386-pc grub isn't installed in the
# BIOS-boot partition (p1, set bios_grub on).
if ! grub-install --target=i386-pc \
--boot-directory="${MNT}/esp/boot" \
--recheck "${LOOP}" 2>&1 | tee "${WORK_DIR}/grub-install-bios.log"; then
cat "${WORK_DIR}/grub-install-bios.log"
err "BIOS grub-install failed — image will not boot on legacy systems"
fi
# Install BIOS GRUB
grub-install --target=i386-pc --boot-directory="${MNT}/esp/boot" --recheck "${LOOP}" 2>/dev/null || warn "BIOS GRUB failed"
cp /usr/lib/grub/i386-pc/*.mod "${MNT}/esp/boot/grub/i386-pc/" 2>/dev/null || true
ok "GRUB installed (UEFI BOOTX64.EFI + BIOS i386-pc, dual-boot ready)"
ok "GRUB installed (UEFI + BIOS)"
# Persistence
if [[ $INCLUDE_PERSISTENCE -eq 1 ]] && [[ -b "${LOOP}p4" ]]; then
+10
View File
@@ -443,6 +443,16 @@ table inet secubox_filter {
# HTTP/HTTPS (SecuBox UI)
tcp dport { 80, 443 } accept
# DHCP client — accept DHCPOFFER / DHCPACK on UDP 68. The
# conntrack `established,related` clause above doesn't help
# for DHCP because the request goes out from 0.0.0.0:68 and
# the reply comes back broadcast (or unicast direct to the
# offered IP before it's actually bound), neither of which
# match the original 5-tuple. Without this rule networkd's
# DHCP times out and secubox-net-fallback's ARP-probe takes
# over — operator ends up on a random fallback subnet.
udp dport 68 accept
# WireGuard
udp dport 51820 accept
+9 -2
View File
@@ -377,8 +377,15 @@ enable_kiosk() {
# Enable kiosk service
systemctl enable secubox-kiosk.service
# Start kiosk
systemctl start secubox-kiosk.service || log "Kiosk will start on next boot"
# Start kiosk in the background so this caller doesn't block. The
# service has Conflicts=getty@tty7.service + TTYPath=/dev/tty7 and
# systemd will sometimes wait for /dev/tty7 to release / sync up,
# which deadlocks a synchronous `systemctl start` invoked from
# firstboot.sh (firstboot runs from inside the autologin shell on
# tty1 itself — observed live USB hang where kiosk-setup ran for
# 5+ minutes and the service stayed `inactive (dead)`).
systemctl --no-block start secubox-kiosk.service \
|| log "Kiosk will start on next boot"
ok "Kiosk mode enabled (${mode})"
log "SecuBox WebUI will display on the connected screen"
+10 -11
View File
@@ -345,17 +345,16 @@ generate_netplan() {
forward-delay: 0
"
else
# No LAN interfaces - just define empty bridge
bridges=" bridges:
br-lan:
interfaces: []
addresses: [192.168.1.1/24]
dhcp4: false
optional: true
parameters:
stp: false
forward-delay: 0
"
# No LAN interfaces — DON'T create an empty br-lan with
# 192.168.1.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
# router refuses a second .1/24 on its broadcast domain
# or the bridge claims the gateway slot).
# Live USB and single-NIC installs should just stay
# WAN-only via the ethernet block above.
bridges=""
fi
;;
bridge)
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -16,6 +16,7 @@ Restart=on-failure
RestartSec=5
PrivateTmp=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
[Install]
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /srv/droplet
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -23,6 +23,7 @@ StartLimitBurst=5
# ProtectSystem=full
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
# ReadWritePaths removed - causes NAMESPACE errors when haproxy not installed
# (haproxy is Recommends, not Depends - /etc/haproxy may not exist)
@@ -16,6 +16,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /etc/sysctl.d /etc/modprobe.d
@@ -23,6 +23,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
LogsDirectory=secubox
LogsDirectoryMode=0755
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -13,6 +13,7 @@ Restart=on-failure
RestartSec=5
PrivateTmp=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
[Install]
WantedBy=multi-user.target
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /etc/nftables.d
@@ -15,6 +15,7 @@ UMask=0000
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /etc/nftables.d
@@ -19,6 +19,7 @@ Restart=on-failure
RestartSec=5
PrivateTmp=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
[Install]
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=false
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /sys/kernel/mm/ksm
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -19,6 +19,7 @@ RestartSec=5
NoNewPrivileges=false
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/lib/lxc
@@ -19,6 +19,7 @@ RestartSec=5
PrivateTmp=true
NoNewPrivileges=false
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /var/lib/lxc
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -8,6 +8,7 @@ Type=simple
User=secubox
Group=secubox
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
WorkingDirectory=/usr/lib/secubox/mesh
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/mesh.sock --workers 1
Restart=always
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox
@@ -11,6 +11,7 @@ ExecStart=/usr/bin/uvicorn api.main:app --uds /run/secubox/metoblizer.sock --wor
Restart=on-failure
RestartSec=5
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
StateDirectory=secubox/metoblizer
[Install]
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox-mirror /etc/secubox /etc/nginx/secubox-mirror.d
@@ -19,6 +19,7 @@ RestartSec=5
# Security
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
# Allow access to serial ports and modem devices
@@ -19,6 +19,7 @@ RestartSec=5
# Security
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
# Allow access to serial ports and modem devices
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -16,6 +16,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /run/ndpid
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -16,6 +16,7 @@ Restart=on-failure
RestartSec=5
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=false
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /etc/sysctl.d /proc/sys
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -8,6 +8,7 @@ Type=simple
User=secubox
Group=secubox
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/p2p.sock --workers 1
WorkingDirectory=/usr/lib/secubox/p2p
Restart=on-failure
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -18,6 +18,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox-repo /var/www/apt.secubox.in /tmp
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox
@@ -8,6 +8,7 @@ Type=simple
User=secubox
Group=secubox
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
WorkingDirectory=/usr/lib/secubox/roadmap
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/roadmap.sock --workers 1
Restart=always
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/rtty /var/log/rtty /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/cache/secubox
@@ -3,6 +3,15 @@ Description=SecuBox SENTINELLE-GSM — passive rogue-BTS analyzer (MIND layer)
Documentation=file:///usr/share/doc/secubox-sentinelle-gsm/README
After=network.target secubox-core.service
Wants=secubox-core.service
# Cap the restart storm: if start fails 3 times in 30s, give up
# instead of looping forever. Observed live-USB regression — when the
# RTL-SDR or its userspace stack is missing, Restart=on-failure +
# RestartSec=5 spammed [FAILED] hundreds of times and blocked the
# kiosk target from settling. StartLimitAction=none means we just
# stop trying, not reboot the system.
StartLimitIntervalSec=30
StartLimitBurst=3
StartLimitAction=none
[Service]
UMask=0007
@@ -13,6 +13,7 @@ Group=root
WorkingDirectory=/usr/lib/secubox/simplex
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/simplex.sock --log-level warning
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0755
UMask=0117
Restart=on-failure
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /etc/postfix /var/log/mail.log
@@ -13,6 +13,7 @@ ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0755
# Security hardening
@@ -13,6 +13,7 @@ ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0755
# Security hardening
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /srv/streamlit
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /srv/streamlit
@@ -18,6 +18,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
LogsDirectory=secubox
LogsDirectoryMode=0755
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ UMask=0000
# ProtectSystem=full
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/suricata /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -19,6 +19,7 @@ RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox /srv/torrent
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/turnserver.conf /var/log/turnserver /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -19,6 +19,7 @@ RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ProtectSystem=full
ReadWritePaths=/run/secubox /var/lib/secubox /var/cache/secubox /etc/secubox /srv/voip
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -14,6 +14,7 @@ RestartSec=5
UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
LogsDirectory=secubox
LogsDirectoryMode=0755
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -15,6 +15,7 @@ UMask=0000
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/secubox /var/log/secubox
@@ -17,6 +17,7 @@ RestartSec=5
NoNewPrivileges=true
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0775
ReadWritePaths=/run/secubox /var/lib/secubox /etc/wireguard /var/log/secubox
@@ -9,6 +9,7 @@ User=secubox
Group=secubox
WorkingDirectory=/usr/lib/secubox/zkp
RuntimeDirectory=secubox
RuntimeDirectoryPreserve=yes
RuntimeDirectoryMode=0755
ExecStart=/usr/bin/python3 -m uvicorn api.main:app --uds /run/secubox/zkp.sock
Restart=always