Hardened Device Images
LineInterpreter provides hardened Ubuntu Core 24 images that you deploy to your own hardware. The security controls are applied automatically at first boot via cloud-init. This page documents what those controls provide and why each one exists.
Bootstrap Access
Section titled “Bootstrap Access”The image includes a single account — li-bootstrap — that exists only to run the provisioning script. The account is designed so that whoever is standing at the machine can complete provisioning without any involvement from LineInterpreter, while preventing any other use.
| Control | Detail |
|---|---|
| No credentials in the image | The account ships locked. A unique random password is generated at first boot and displayed above the login prompt. |
| Single allowed command | li-bootstrap has no general sudo rights. Its entire sudo permission is one path: sudo provision-once. Any other command is denied. |
| Root-owned wrapper | provision-once is owned by root and not writable by li-bootstrap, so the script cannot be replaced to escalate permissions. |
| Run-once enforcement | A sentinel file (/var/lib/lineinterpreter/provisioned) prevents provision-once from running twice. A re-provision requires an admin to explicitly remove it. |
| Self-destructing account | On successful provisioning, provision-once deletes the li-bootstrap account with userdel -r. The account ceases to exist. |
| No pre-provisioning SSH | openssh-server is not installed in the base image. SSH access is only configured by provision.sh during provisioning. |
OS Immutability and Integrity
Section titled “OS Immutability and Integrity”Ubuntu Core 24 uses a read-only squashfs root filesystem. This means:
- Core OS files cannot be modified at runtime — even by root.
- Only cryptographically signed snaps can be installed, as defined by the model assertion. An attacker with full shell access cannot install arbitrary software.
- Secure Boot is enabled — only the trusted bootchain can start the system.
- AppArmor confines each snap application, restricting its access to the host system.
Kernel Network Hardening (CIS Level 2)
Section titled “Kernel Network Hardening (CIS Level 2)”The following sysctl parameters are applied at boot and persist across reboots:
IP Forwarding & Redirects
- IP forwarding disabled (IPv4 and IPv6) — the device cannot be used as a router
- Packet redirect sending disabled
- Source routing, ICMP redirects, and secure ICMP redirects rejected
Suspicious Traffic
- Martian (impossible source) packets are logged
- Broadcast ICMP requests ignored
- Bogus ICMP error responses ignored
- TCP SYN cookies enabled — mitigates SYN flood DoS attacks
- Reverse Path Filtering enabled — rejects packets that don’t have a valid return route
IPv6
- IPv6 is completely disabled. Edge devices have no IPv6 requirement, so eliminating it removes the entire IPv6 attack surface.
Memory Safety
- ASLR (
randomize_va_space = 2) — full address space layout randomisation, making memory-based exploits significantly harder.
Kernel Module Restrictions
Section titled “Kernel Module Restrictions”Kernel modules that are unused on a kiosk device are blacklisted so they cannot be loaded:
| Category | Modules |
|---|---|
| Unused filesystems | cramfs, freevxfs, jffs2, hfs, hfsplus, squashfs, udf |
| Physical data exfiltration | usb-storage — disabled by provision.sh at the end of provisioning. Left enabled in the image so the dashboard snap bundle can be transferred via USB stick before SSH exists. Pass --keep-usb to skip disabling it. |
| Uncommon network protocols | dccp, sctp, rds, tipc |
USB storage is left enabled in the base image because it is needed to transfer the provisioning bundle before SSH exists. provision.sh blocks usb access the end of provisioning (unless —keep-usb passed), so it takes effect on the next boot.
Core Dump Suppression
Section titled “Core Dump Suppression”Core dumps can expose sensitive data (memory contents, credentials, keys) if an attacker triggers a crash and retrieves the resulting file.
- Hard limit of 0 for all users — core dumps are forbidden
fs.suid_dumpable = 0— SUID processes cannot produce core dumpskernel.core_pattern = |/bin/false— any dump attempt is silently discarded
Filesystem Permissions
Section titled “Filesystem Permissions”/rootis restricted to700— no world or group access/tmphas the sticky bit set (1777) — users cannot delete each other’s temporary files
Blast Radius
Section titled “Blast Radius”li-bootstrap (pre-provisioning)
Section titled “li-bootstrap (pre-provisioning)”If an attacker were to compromise li-bootstrap credentials before provisioning:
- They can run exactly one command as root:
provision-once - That command only executes a specific script at a specific path — it does not provide a shell
- The immutable OS means they cannot install software, modify system files, or persist a backdoor
- The model assertion means no unauthorised snaps can be installed
- Post-provisioning, the account no longer exists
li-updater (post-provisioning)
Section titled “li-updater (post-provisioning)”After provisioning, li-bootstrap is gone. The only remote access path is the li-updater account, used to deliver snap updates over SSH. If those credentials were compromised:
- No interactive shell — every SSH connection is routed through a restricted
ForceCommandwrapper (li-updater-shell). The user cannot run arbitrary commands. - Allow-listed commands only — the wrapper permits a small, explicit set: upload files to
~/, install a signed snap update, verify checksums, check snap version/logs, and basic diagnostics (top,df,ip addr, etc.). All other commands are denied. - Single sudo command —
li-updatercan only runsudo update-dashboard, which itself only accepts a path-validated.snapfile from the home directory, requires a matching Snap Store–signed assertion file, and callssnap install. There is no path to a root shell. - AppArmor enforcement — the
update-dashboardwrapper runs under an AppArmor enforce profile that grants read-only access to~/li-updater/*.snap, and hard-denies access to/etc/shadow, sudoers files, SSH keys, and/root. - Snap Store signatures —
snap ackvalidates the cryptographic assertion before installation. An attacker cannot install an arbitrary or modified snap package even with fullli-updateraccess. - Password authentication disabled —
li-updaterships with a locked password; SSH access requires the authorised key configured during provisioning.