mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-08-16 11:04:01 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff806523b7 | ||
|
|
dcb4ce828b | ||
|
|
a88c177372 | ||
|
|
36612f622d | ||
|
|
930a885f04 | ||
|
|
24d6f28dab | ||
|
|
faa5f5d84a | ||
|
|
da09fa6987 |
+121
-182
@@ -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,17 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# Capture UUIDs — labels failed to resolve on at least one real UEFI
|
||||
# box (v2.12.x grub> shell symptom). Bake UUIDs into the embed-cfg
|
||||
# and grub.cfg so `search --fs-uuid` is used everywhere instead of
|
||||
# the fragile `search --label`. blkid is read AFTER mkfs.* so the
|
||||
# values are guaranteed fresh.
|
||||
udevadm settle 2>/dev/null || sleep 1
|
||||
ESP_UUID=$(blkid -s UUID -o value "${LOOP}p2" 2>/dev/null || echo "")
|
||||
LIVE_UUID=$(blkid -s UUID -o value "${LOOP}p3" 2>/dev/null || echo "")
|
||||
[[ -z "$ESP_UUID" || -z "$LIVE_UUID" ]] && err "Failed to read ESP/LIVE UUIDs from ${LOOP} after mkfs"
|
||||
log "ESP UUID=${ESP_UUID} LIVE UUID=${LIVE_UUID}"
|
||||
|
||||
# Mount for file copy
|
||||
MNT="${WORK_DIR}/mnt"
|
||||
mkdir -p "${MNT}/esp" "${MNT}/live"
|
||||
@@ -3600,7 +3582,15 @@ insmod all_video
|
||||
insmod echo
|
||||
insmod gfxterm
|
||||
|
||||
search --no-floppy --label LIVE --set=live
|
||||
# Resolve LIVE partition by UUID — `search --label` failed silently on
|
||||
# real UEFI hardware (v2.12.x grub> shell). UUIDs are baked at build
|
||||
# time from blkid after mkfs.ext4, so this lookup is deterministic.
|
||||
search --no-floppy --fs-uuid ${LIVE_UUID} --set=live
|
||||
# Fallback: keep the label search as a second chance for firmware
|
||||
# that prefers labels (no-op if already set above).
|
||||
if [ -z "\$live" ]; then
|
||||
search --no-floppy --label LIVE --set=live
|
||||
fi
|
||||
|
||||
# CRT-style menu colors (cyan on black, gold highlights)
|
||||
set menu_color_normal=cyan/black
|
||||
@@ -3717,103 +3707,52 @@ 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 — use $cmdpath, the variable EFI firmware sets to the
|
||||
# directory it loaded BOOTX64.EFI from. /EFI/BOOT/grub.cfg sits right
|
||||
# next to BOOTX64.EFI on the ESP (script copies it there above), so
|
||||
# `configfile $cmdpath/grub.cfg` is a single-step lookup that doesn't
|
||||
# depend on filesystem labels or partition search — both of which
|
||||
# have failed on different real-hardware firmware over the v2.12.x
|
||||
# series. The full grub.cfg itself still does `search --label LIVE
|
||||
# --set=live` to find the squashfs partition, so that part is
|
||||
# unchanged.
|
||||
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
|
||||
cat > "${WORK_DIR}/grub-embed.cfg" <<EMBEDCFG
|
||||
# Try \$cmdpath first (set by firmware to dir of loaded .EFI). Falls
|
||||
# back to UUID-based search if \$cmdpath isn't usable.
|
||||
if [ -n "\$cmdpath" ]; then
|
||||
configfile \$cmdpath/grub.cfg
|
||||
fi
|
||||
if [ -n "$root" ]; then
|
||||
set prefix=($root)/boot/grub
|
||||
else
|
||||
set prefix=($cmdpath)/../../boot/grub
|
||||
search --no-floppy --fs-uuid ${ESP_UUID} --set=root
|
||||
if [ -n "\$root" ]; then
|
||||
configfile (\$root)/EFI/BOOT/grub.cfg
|
||||
fi
|
||||
configfile $prefix/grub.cfg
|
||||
echo "GRUB embed-cfg fallback failed: cmdpath=\$cmdpath root=\$root"
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user