From 08568e52fa40402e36e5c29ed111dff80fa43171 Mon Sep 17 00:00:00 2001 From: Mitchell R Date: Wed, 20 May 2026 05:18:18 +0200 Subject: [PATCH] feat(kiosk): harden field image defaults --- .github/workflows/build.yml | 4 +++- .../01-install-kiosk/01-run-chroot.sh | 7 +++++++ deploy/scripts/setup-pi-kiosk.sh | 8 ++++++++ deploy/udev/90-betterframe-no-hid.rules | 7 +++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 deploy/udev/90-betterframe-no-hid.rules diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 32f7819..faee79a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,6 +174,8 @@ jobs: deploy/pi-gen/stage-betterframe-client/01-install-kiosk/files/ cp deploy/tmpfiles/betterframe-kiosk.conf \ deploy/pi-gen/stage-betterframe-client/01-install-kiosk/files/ + cp deploy/udev/90-betterframe-no-hid.rules \ + deploy/pi-gen/stage-betterframe-client/01-install-kiosk/files/ cp deploy/pam.d/cage \ deploy/pi-gen/stage-betterframe-client/01-install-kiosk/files/cage.pam cp deploy/plymouth/betterframe/betterframe.plymouth \ @@ -191,7 +193,7 @@ jobs: image-name: betterframe-client-${{ inputs.version }} stage-list: stage0 stage1 stage2 ./deploy/pi-gen/stage-betterframe-client # pi-gen default release is trixie (Debian 13). - enable-ssh: 1 + enable-ssh: 0 username: bfadmin password: betterframe locale: en_US.UTF-8 diff --git a/deploy/pi-gen/stage-betterframe-client/01-install-kiosk/01-run-chroot.sh b/deploy/pi-gen/stage-betterframe-client/01-install-kiosk/01-run-chroot.sh index c926d8d..2fbd7e6 100755 --- a/deploy/pi-gen/stage-betterframe-client/01-install-kiosk/01-run-chroot.sh +++ b/deploy/pi-gen/stage-betterframe-client/01-install-kiosk/01-run-chroot.sh @@ -28,6 +28,8 @@ install -m 755 /tmp/bf-files/betterframe-rauc-mark-good.sh \ /usr/local/sbin/betterframe-rauc-mark-good.sh install -d -m 755 /etc/tmpfiles.d install -m 644 /tmp/bf-files/betterframe-kiosk.conf /etc/tmpfiles.d/betterframe-kiosk.conf +install -d -m 755 /etc/udev/rules.d +install -m 644 /tmp/bf-files/90-betterframe-no-hid.rules /etc/udev/rules.d/90-betterframe-no-hid.rules # Default env file — operator may edit on first boot to point at their server. cat > /etc/default/betterframe-kiosk <<'EOF' @@ -56,6 +58,11 @@ for dm in lightdm gdm gdm3 sddm; do systemctl mask "${dm}.service" 2>/dev/null || true done systemctl disable getty@tty1.service 2>/dev/null || true +systemctl mask getty@tty1.service ctrl-alt-del.target 2>/dev/null || true +systemctl disable ssh.service ssh.socket 2>/dev/null || true +systemctl mask ssh.service ssh.socket 2>/dev/null || true +systemctl disable bluetooth.service hciuart.service 2>/dev/null || true +systemctl mask bluetooth.service hciuart.service 2>/dev/null || true # piwiz first-run wizard + userconf-pi → out. apt-get -y purge piwiz userconf-pi 2>/dev/null || true diff --git a/deploy/scripts/setup-pi-kiosk.sh b/deploy/scripts/setup-pi-kiosk.sh index e1b7758..9fb42dd 100755 --- a/deploy/scripts/setup-pi-kiosk.sh +++ b/deploy/scripts/setup-pi-kiosk.sh @@ -216,6 +216,11 @@ if [ "${INSTALL_KIOSK}" = "1" ]; then done systemctl set-default multi-user.target systemctl disable --now getty@tty1.service 2>/dev/null || true + systemctl mask getty@tty1.service ctrl-alt-del.target 2>/dev/null || true + systemctl disable --now ssh.service ssh.socket 2>/dev/null || true + systemctl mask ssh.service ssh.socket 2>/dev/null || true + systemctl disable --now bluetooth.service hciuart.service 2>/dev/null || true + systemctl mask bluetooth.service hciuart.service 2>/dev/null || true # piwiz = "Welcome to Raspberry Pi" first-run wizard. userconf-pi runs at # first boot if no user is configured. Purge both so they can't fire. @@ -242,6 +247,9 @@ if [ "${INSTALL_KIOSK}" = "1" ]; then install -d -m 755 /etc/tmpfiles.d install -m 644 "${REPO_ROOT}/deploy/tmpfiles/betterframe-kiosk.conf" \ /etc/tmpfiles.d/betterframe-kiosk.conf + install -d -m 755 /etc/udev/rules.d + install -m 644 "${REPO_ROOT}/deploy/udev/90-betterframe-no-hid.rules" \ + /etc/udev/rules.d/90-betterframe-no-hid.rules if [ ! -e /etc/default/betterframe-kiosk ]; then cat > /etc/default/betterframe-kiosk <<'EOF' diff --git a/deploy/udev/90-betterframe-no-hid.rules b/deploy/udev/90-betterframe-no-hid.rules new file mode 100644 index 0000000..75d838d --- /dev/null +++ b/deploy/udev/90-betterframe-no-hid.rules @@ -0,0 +1,7 @@ +# BetterFrame field kiosks are appliances, not interactive desktops. +# Block userspace access to keyboard/mouse event devices by default. Future +# controlled input should arrive as authenticated high-level kiosk commands, +# not raw HID events. +KERNEL=="event*", ENV{ID_INPUT_KEYBOARD}=="1", MODE="0000", GROUP="root" +KERNEL=="event*", ENV{ID_INPUT_MOUSE}=="1", MODE="0000", GROUP="root" +KERNEL=="event*", ENV{ID_INPUT_TOUCHPAD}=="1", MODE="0000", GROUP="root"