From 5f79d7a3b65fbeefb39cf09344c6aa78146bdd71 Mon Sep 17 00:00:00 2001 From: Markus Zehnder Date: Sat, 2 Aug 2025 18:51:01 +0200 Subject: [PATCH] docs: add systemd unit service to switch off LCD on boot (#4) --- .github/workflows/build.yml | 1 + README.md | 3 + linux/README.md | 121 ++++++++++++++++++++++++++++++++++++ linux/lcd-off.service | 46 ++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 linux/README.md create mode 100644 linux/lcd-off.service diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ebc7a72..9a3e14c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,6 +102,7 @@ jobs: ls -la target/release mkdir -p ${GITHUB_WORKSPACE}/${{env.BIN_OUTPUT_PATH }} cp target/release/${{ env.APP_NAME }} ${GITHUB_WORKSPACE}/${{ env.BIN_OUTPUT_PATH }} + cp linux/*.service ${GITHUB_WORKSPACE}/${{ env.BIN_OUTPUT_PATH }} cp Monitor3.json ${GITHUB_WORKSPACE}/${{ env.BIN_OUTPUT_PATH }} echo "VERSION=${{ env.APP_VERSION }}" > ${GITHUB_WORKSPACE}/${{ env.BIN_OUTPUT_PATH }}/version.txt echo "TIMESTAMP=$(date +"%Y%m%d_%H%M%S")" >> ${GITHUB_WORKSPACE}/${{ env.BIN_OUTPUT_PATH }}/version.txt diff --git a/README.md b/README.md index 2487da9..92938cb 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,9 @@ A release build is highly recommended, as it significantly improves graphics per cargo build --release ``` +### Install + +See [Linux systemd Service](linux/) on how to automatically switch off the LCD at boot up. ## Demo App Usage diff --git a/linux/README.md b/linux/README.md new file mode 100644 index 0000000..a566a12 --- /dev/null +++ b/linux/README.md @@ -0,0 +1,121 @@ +# Linux systemd Service + +The systemd unit [lcd-off.service](lcd-off.service) can be installed to automatically switch off the embedded LCD on boot. + +The unit file has been tailored to Debian based Linux distros and has been tested on Proxmox 8.4 and Ubuntu 25.04. + +Requirements: +- `/dev/ttyACM0`: `dialout` group with rw permissions. + - To run as root: remove `DynamicUser` and `Group` settings. + + +## Install + +As root user, otherwise `sudo` is required: +```shell +cp asterctl /usr/bin/ +cp lcd-off.service /etc/systemd/system/ +systemctl daemon-reload +systemctl enable lcd-off +``` + +## Security + +The systemd unit file uses strong security settings to only allow operations required for `asterctl`: + +```shell +systemd-analyze security lcd-off.service +``` + +
+ +``` + NAME DESCRIPTION EXPOSURE +✓ SystemCallFilter=~@swap System call allow list defined for service, and @swap is not included +✓ SystemCallFilter=~@resources System call allow list defined for service, and @resources is not included +✓ SystemCallFilter=~@reboot System call allow list defined for service, and @reboot is not included +✓ SystemCallFilter=~@raw-io System call allow list defined for service, and @raw-io is not included +✓ SystemCallFilter=~@privileged System call allow list defined for service, and @privileged is not included +✓ SystemCallFilter=~@obsolete System call allow list defined for service, and @obsolete is not included +✓ SystemCallFilter=~@mount System call allow list defined for service, and @mount is not included +✓ SystemCallFilter=~@module System call allow list defined for service, and @module is not included +✓ SystemCallFilter=~@debug System call allow list defined for service, and @debug is not included +✓ SystemCallFilter=~@cpu-emulation System call allow list defined for service, and @cpu-emulation is not included +✓ SystemCallFilter=~@clock System call allow list defined for service, and @clock is not included +✓ RemoveIPC= Service user cannot leave SysV IPC objects around +✗ RootDirectory=/RootImage= Service runs within the host's root directory 0.1 +✓ User=/DynamicUser= Service runs under a transient non-root user identity +✓ RestrictRealtime= Service realtime scheduling access is restricted +✓ CapabilityBoundingSet=~CAP_SYS_TIME Service processes cannot change the system clock +✓ NoNewPrivileges= Service processes cannot acquire new privileges +✓ AmbientCapabilities= Service process does not receive ambient capabilities +✗ PrivateDevices= Service potentially has access to hardware devices 0.2 +✓ CapabilityBoundingSet=~CAP_BPF Service may not load BPF programs +✗ SystemCallArchitectures= Service may execute system calls with all ABIs 0.2 +✓ ProtectSystem= Service has strict read-only access to the OS file hierarchy +✓ ProtectProc= Service has restricted access to process tree (/proc hidepid=) +✓ SupplementaryGroups= Service has no supplementary groups +✓ CapabilityBoundingSet=~CAP_SYS_RAWIO Service has no raw I/O access +✓ CapabilityBoundingSet=~CAP_SYS_PTRACE Service has no ptrace() debugging abilities +✓ CapabilityBoundingSet=~CAP_SYS_(NICE|RESOURCE) Service has no privileges to change resource use parameters +✓ CapabilityBoundingSet=~CAP_NET_ADMIN Service has no network configuration privileges +✓ CapabilityBoundingSet=~CAP_NET_(BIND_SERVICE|BROADCAST|RAW) Service has no elevated networking privileges +✗ DeviceAllow= Service has no device ACL 0.2 +✓ CapabilityBoundingSet=~CAP_AUDIT_* Service has no audit subsystem access +✓ CapabilityBoundingSet=~CAP_SYS_ADMIN Service has no administrator privileges +✓ PrivateNetwork= Service has no access to the host's network +✓ PrivateTmp= Service has no access to other software's temporary files +✓ ProcSubset= Service has no access to non-process /proc files (/proc subset=) +✓ CapabilityBoundingSet=~CAP_SYSLOG Service has no access to kernel logging +✓ ProtectHome= Service has no access to home directories +✓ KeyringMode= Service doesn't share key material with other services +✓ Delegate= Service does not maintain its own delegated control group subtree +✓ PrivateUsers= Service does not have access to other users +✗ IPAddressDeny= Service does not define an IP address allow list 0.2 +✓ NotifyAccess= Service child processes cannot alter service state +✓ ProtectClock= Service cannot write to the hardware clock or system clock +✓ CapabilityBoundingSet=~CAP_SYS_PACCT Service cannot use acct() +✓ CapabilityBoundingSet=~CAP_KILL Service cannot send UNIX signals to arbitrary processes +✓ ProtectKernelLogs= Service cannot read from or write to the kernel log ring buffer +✓ CapabilityBoundingSet=~CAP_WAKE_ALARM Service cannot program timers that wake up the system +✓ CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER) Service cannot override UNIX file/IPC permission checks +✓ ProtectControlGroups= Service cannot modify the control group file system +✓ CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE Service cannot mark files immutable +✓ CapabilityBoundingSet=~CAP_IPC_LOCK Service cannot lock memory into RAM +✓ ProtectKernelModules= Service cannot load or read kernel modules +✓ CapabilityBoundingSet=~CAP_SYS_MODULE Service cannot load kernel modules +✓ CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG Service cannot issue vhangup() +✓ CapabilityBoundingSet=~CAP_SYS_BOOT Service cannot issue reboot() +✓ CapabilityBoundingSet=~CAP_SYS_CHROOT Service cannot issue chroot() +✓ PrivateMounts= Service cannot install system mounts +✓ CapabilityBoundingSet=~CAP_BLOCK_SUSPEND Service cannot establish wake locks +✓ MemoryDenyWriteExecute= Service cannot create writable executable memory mappings +✓ RestrictNamespaces=~user Service cannot create user namespaces +✓ RestrictNamespaces=~pid Service cannot create process namespaces +✓ RestrictNamespaces=~net Service cannot create network namespaces +✓ RestrictNamespaces=~uts Service cannot create hostname namespaces +✓ RestrictNamespaces=~mnt Service cannot create file system namespaces +✓ CapabilityBoundingSet=~CAP_LEASE Service cannot create file leases +✓ CapabilityBoundingSet=~CAP_MKNOD Service cannot create device nodes +✓ RestrictNamespaces=~cgroup Service cannot create cgroup namespaces +✓ RestrictNamespaces=~ipc Service cannot create IPC namespaces +✓ ProtectHostname= Service cannot change system host/domainname +✓ CapabilityBoundingSet=~CAP_(CHOWN|FSETID|SETFCAP) Service cannot change file ownership/access mode/capabilities +✓ CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP) Service cannot change UID/GID identities/capabilities +✓ LockPersonality= Service cannot change ABI personality +✓ ProtectKernelTunables= Service cannot alter kernel tunables (/proc/sys, …) +✓ RestrictAddressFamilies=~AF_PACKET Service cannot allocate packet sockets +✓ RestrictAddressFamilies=~AF_NETLINK Service cannot allocate netlink sockets +✓ RestrictAddressFamilies=~AF_UNIX Service cannot allocate local sockets +✓ RestrictAddressFamilies=~… Service cannot allocate exotic sockets +✓ RestrictAddressFamilies=~AF_(INET|INET6) Service cannot allocate Internet sockets +✓ CapabilityBoundingSet=~CAP_MAC_* Service cannot adjust SMACK MAC +✓ RestrictSUIDSGID= SUID/SGID file creation by service is restricted +✓ UMask= Files created by service are accessible only by service's own user by default +``` + +
+ +``` +→ Overall exposure level for lcd-off.service: 0.8 SAFE 😀 +``` diff --git a/linux/lcd-off.service b/linux/lcd-off.service new file mode 100644 index 0000000..d0778f1 --- /dev/null +++ b/linux/lcd-off.service @@ -0,0 +1,46 @@ +[Unit] +Description=Switch off embedded LCD on boot +After=local-fs.target + +[Service] +Type=oneshot +RemainAfterExit=no +DynamicUser=true +# tailored to Debian: adapt for other Linux flavours! RW access to /dev/ttyACM0 is required +Group=dialout + +ExecStart=/usr/bin/asterctl --off + +# lock down service +CapabilityBoundingSet= +LockPersonality=true +RestrictNamespaces=true +ProtectHome=true +ProtectSystem=strict +NoNewPrivileges=true +ProtectKernelTunables=true +ProtectKernelModules=true +ProtectKernelLogs=true +ProtectControlGroups=true +MemoryDenyWriteExecute=true +RestrictSUIDSGID=true +KeyringMode=private +ProtectClock=true +ProtectProc=invisible +ProcSubset=pid +RestrictRealtime=true +PrivateNetwork=true +PrivateTmp=true +PrivateUsers=true +ProtectHostname=true +RestrictAddressFamilies=none +SystemCallFilter=@system-service +SystemCallFilter=~@privileged @resources +SystemCallErrorNumber=EPERM +UMask=0177 + +# that's all we need access to +DeviceAllow=/dev/ttyACM0 rw + +[Install] +WantedBy=multi-user.target