Install on Linux
Distro packages, prebuilt tarball, runtime requirements.
Runtime requirements
LUKSbox dynamically links against three system libraries:
| Library | Used for | Distro package |
|---|---|---|
libfido2 >= 1.10 |
FIDO2 hardware-key support | libfido2-1 (Debian/Ubuntu), libfido2 (Fedora/Arch) |
libfuse3 >= 3.10 |
The mount subcommand |
libfuse3-3 (Debian/Ubuntu), fuse3 (Fedora/Arch) |
libudev |
USB device enumeration | libudev1 / systemd-libs (already present on systemd distros) |
A passphrase-only vault doesn't need libfido2; a software-only build
without mount doesn't need libfuse3. The published binaries link
both because the typical user wants both.
Debian / Ubuntu / Mint (.deb, recommended)
curl -LO https://github.com/penthertz/LUKSbox/releases/latest/download/luksbox_amd64.deb
sudo apt install ./luksbox_amd64.deb
luksbox --version
apt resolves the runtime deps (libfido2-1, libfuse3-3) for
you, registers the luksbox-gui desktop launcher in your app menu,
and installs the MIME type so double-clicking a .lbx file in
Nautilus / Dolphin / Thunar opens it directly in LUKSbox. Uninstall
with sudo apt remove luksbox.
Since v0.2.0 the .deb also Recommends tpm-udev and
tpm2-tools. These are not strict dependencies (a passphrase-only
or FIDO2-only user does not need them), so a stripped-down system
or a deliberate --no-install-recommends install will skip them.
With the defaults, apt install ./luksbox_*.deb brings them in
automatically, which gets you:
/etc/udev/rules.d/60-tpm.rulesshipped bytpm-udev, grants/dev/tpm0and/dev/tpmrm0to members of thetssgroup.- The
tsssystem group created by the same package. - The
tpm2_*CLI binaries (tpm2_getcap,tpm2_pcrread, etc.) fromtpm2-tools, useful for one-off TPM operations and for debugging whether your chip is reachable at all.
After install you still need to add yourself to the tss group
and log back in, the package will not do this silently, by
Debian convention. See Permissions below.
Direct dpkg -i: use sudo, not bare su root
If you bypass apt and run dpkg -i luksbox_*.deb directly,
use sudo or su -, never plain su root. On Debian 13
(Trixie) a plain su root shell inherits the original user's
PATH, which typically lacks /sbin. Dpkg's own pre-flight
check then aborts with:
dpkg: warning: 'ldconfig' not found in PATH or not executable
dpkg: warning: 'start-stop-daemon' not found in PATH or not executable
dpkg: error: 2 expected programs not found in PATH or not executable
Dpkg fails BEFORE any maintainer script runs, so this cannot be fixed inside the package. Workarounds:
# Recommended: sudo honors `secure_path` which includes /sbin.
sudo dpkg -i luksbox_*.deb
# Or: use `su -` (login shell, loads root's PATH).
su -
dpkg -i luksbox_*.deb
# Or: extend PATH explicitly before the dpkg call.
export PATH="$PATH:/sbin:/usr/sbin"
dpkg -i luksbox_*.deb
The apt install ./luksbox_*.deb flow earlier in this section
already uses sudo and is not affected.
dpkg -i does not install dependencies (QubesOS AppVMs, minimal templates)
dpkg -i installs only the .deb you hand it; it never pulls the
packages LUKSbox depends on. On a full desktop Debian those runtime
libraries are usually already present from other software, so
dpkg -i appears to "just work". On a minimal template (a QubesOS
AppVM, a container, a fresh debootstrap) they are not, and the
install stops with unmet dependencies:
dpkg: dependency problems prevent configuration of luksbox:
luksbox depends on libtss2-esys-3.0.2-0t64 (>= 2.3.1); however: ...
luksbox depends on libtss2-mu-4.0.1-0t64 (>= 3.0.1); however: ...
luksbox depends on libtss2-tctildr0t64 (>= 3.0.1); however: ...
The libtss2-* libraries back the optional TPM 2.0 keyslots and are a
hard runtime dependency because the binary links them. A QubesOS AppVM
usually has no TPM at all, but the libraries must still be present for
the binary to load; passphrase and FIDO2 keyslots then work without a
TPM. Two fixes:
# Best: let apt resolve and install the dependencies for you.
sudo apt install ./luksbox_*.deb
# Or, if you already ran `dpkg -i` and it left the package
# unconfigured, pull the missing dependencies and finish the install:
sudo apt --fix-broken install
You do NOT need libtss2-dev (the development headers): the runtime
libtss2-* packages that apt selects on its own are enough.
Fedora / RHEL / Rocky / Alma / openSUSE (.rpm, recommended)
curl -LO https://github.com/penthertz/LUKSbox/releases/latest/download/luksbox.x86_64.rpm
sudo dnf install ./luksbox.x86_64.rpm
luksbox --version
Pulls in libfido2 and fuse3-libs automatically. Same desktop
integration as the .deb. Uninstall with sudo dnf remove luksbox.
Since v0.2.0 the .rpm also Recommends tpm2-tss (the
higher-level package on Fedora / RHEL / openSUSE that ships the
udev rules at /usr/lib/udev/rules.d/60-tpm-udev.rules and
creates the tss group) plus tpm2-tools for the CLI. dnf
installs both by default; pass --setopt=install_weak_deps=False
to opt out. Same post-install usermod -aG tss "$USER" step
applies, see Permissions.
Arch / NixOS / Alpine / generic Linux (tarball + install.sh)
For distros without a dedicated package, use the generic tarball.
The bundled install.sh handles per-user (~/.local) or system-wide
(/usr/local) install with desktop integration:
# Install runtime deps for your distro first.
sudo pacman -S libfido2 fuse3 # Arch
# (or)
sudo apk add libfido2 fuse3 # Alpine
# (NixOS: use the `nix-shell -p libfido2 fuse3` ephemeral env, or
# add to your configuration.nix.)
curl -LO https://github.com/penthertz/LUKSbox/releases/latest/download/luksbox-x86_64-unknown-linux-gnu.tar.gz
tar -xzf luksbox-x86_64-unknown-linux-gnu.tar.gz
cd luksbox-*-x86_64-linux
./install.sh # per-user, ~/.local
# (or)
./install.sh --system # system-wide, /usr/local + sudo
luksbox --version
Uninstall with ./install.sh --uninstall (or --uninstall --system).
The installer drops a manifest in ~/.local/share/luksbox/ so it
knows exactly which files to remove.
Verifying the download
Every release ships with a SHA-256 manifest:
curl -LO https://github.com/penthertz/LUKSbox/releases/latest/download/SHA256SUMS.txt
curl -LO https://github.com/penthertz/LUKSbox/releases/latest/download/SHA256SUMS.txt.asc
sha256sum -c SHA256SUMS.txt # checks luksbox-*.tar.gz
Using TPM 2.0 keyslots
LUKSbox supports two TPM-bound keyslot kinds on Linux:
tpm2- TPM-only. Wrap key lives inside the local TPM chip; no passphrase is involved. Vault becomes uncrackable if its file is stolen separately from this machine, but loses portability (won't unlock on any other machine).tpm2-fido2- Fused. Unlock requires BOTH the local TPM AND a connected FIDO2 authenticator. Strongest single-slot mode; loss of either factor permanently kills the slot, so pair with a passphrase or FIDO2-only slot for recovery.
Prerequisites
Most modern PCs ship a TPM 2.0 - either a discrete chip or a firmware TPM (Intel PTT / AMD fTPM) integrated into the CPU. Check whether yours is enabled and exposed:
ls /dev/tpm*
# Expected output: /dev/tpm0 /dev/tpmrm0
If the device files are missing:
- Reboot into the BIOS / UEFI setup, look for an option like "Trusted Platform Module", "Intel PTT", or "AMD fTPM", enable it, save, reboot.
- If the chip exists but the kernel driver isn't loaded:
sudo modprobe tpm_crb(most modern chips) orsudo modprobe tpm_tis(older).
Userspace runtime libraries are pulled in automatically by the
.deb / .rpm packages; for the generic tarball install:
sudo apt install libtss2-esys-3.0.2-0 # Debian/Ubuntu (runtime)
sudo dnf install tpm2-tss # Fedora/RHEL
sudo pacman -S tpm2-tss # Arch
Permissions
If you installed via the .deb or .rpm (v0.2.0+), the Recommends
listed above already created the tss system group and installed
the udev rules. You only need the one-time group-membership step:
sudo usermod -aG tss "$USER"
# log out + log back in (or `newgrp tss`) for the new group to apply
id | tr , '\n' | grep tss # confirm `tss` appears
ls -l /dev/tpmrm0
# expected: crw-rw---- 1 root tss ... /dev/tpmrm0
If you installed via the tarball, or you used
--no-install-recommends / --setopt=install_weak_deps=False,
neither the group nor the udev rule exists yet. Either install
the udev-providing package manually:
sudo apt install tpm-udev tpm2-tools # Debian / Ubuntu / Mint
sudo dnf install tpm2-tss tpm2-tools # Fedora / RHEL / Rocky
sudo pacman -S tpm2-tools # Arch (creates the group + rule)
...then re-run the usermod line above, or use the tarball
installer's TPM-setup shortcut:
./install.sh --tpm-setup
which creates the group + udev rule + adds you in one step (prompts
for sudo once). Either way you still need to log out + back in
before the new group takes effect in your shell session.
Enroll and unlock
# Enroll a TPM-only keyslot on an existing vault (the vault must
# already have a passphrase or FIDO2 slot to bootstrap from).
luksbox enroll vault.lbx --kind tpm2
# Unlock via TPM, no passphrase prompt.
luksbox open vault.lbx --tpm2
luksbox ls vault.lbx --tpm2 /
# Or the fused mode requiring BOTH the TPM AND a YubiKey.
luksbox enroll vault.lbx --kind tpm2-fido2
luksbox open vault.lbx --tpm2-fido2
The GUI exposes the same surfaces under Manage Keyslots -> Add TPM 2.0 keyslot / Add fused TPM 2.0 + FIDO2 keyslot, and adds two new radios in the unlock view.
Caveats and limitations
- Linux only for now. macOS Secure Enclave and Windows TPM
are on the roadmap but not shipped yet - see
SECURITY.mdTier 3 item 10. macOS and Windows users get passphrase / FIDO2 / hybrid-PQ for now. - No PCR sealing yet. Current TPM slots use an empty policy, so any caller on this TPM can unseal. Adding PCR sealing (refuse to unwrap if the boot chain has been tampered with) is a planned follow-up. Until it ships, a rootkit that loaded BEFORE the kernel could in principle replay the unseal.
- No PIN auth on the sealed object. Possession of the chip is sufficient for TPM-only slots; the fused TPM+FIDO2 mode adds the FIDO2 authenticator as the second factor. Adding optional PIN auth on TPM-only is also a planned follow-up.
- TPM dictionary-attack lockout. After ~32 wrong unseal
attempts the chip refuses for a cooldown period (vendor-
specific, typically 1-24 hours, configurable). Recover with
tpm2_dictionarylockout --clear-lockoutif you have the TPM owner password (most users don't have one set). - TPM-bound keyslots are non-portable. A vault enrolled
with
--kind tpm2will not unlock on a different machine, even with the same.lbxfile copied over. Always pair with a passphrase or FIDO2 recovery slot.
Server / cloud VMs
Most cloud VM providers don't expose a TPM to guests. If
/dev/tpm* is missing on a server, either install swtpm
(software TPM emulator) for testing, or use passphrase / FIDO2
keyslots which work everywhere.
udev rule for FIDO2 devices (non-root use)
If luksbox enroll --fido2 reports "permission denied" reading a
hidraw device, your distro doesn't have a udev rule giving the user
session access to the FIDO HID class. Most distros ship one in 2026,
but if yours doesn't:
sudo tee /etc/udev/rules.d/70-fido2.rules > /dev/null << 'EOF'
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
ATTRS{idVendor}=="1050", TAG+="uaccess" # YubiKey
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
ATTRS{idVendor}=="18d1", TAG+="uaccess" # Google Titan
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
ATTRS{idVendor}=="20a0", TAG+="uaccess" # Nitrokey
EOF
sudo udevadm control --reload && sudo udevadm trigger
Then unplug + replug the device.
QubesOS and other hardened / memory-locked VMs
LUKSbox runs fine inside a QubesOS AppVM (tested on a debian-trixie
template), but two AppVM defaults bite the first time you create or
unlock a vault. Both are environment limits, not bugs in the vault
format, and both have one-line fixes.
"memory allocation of 268435456 bytes failed / Aborted" during Argon2id
You'll see this right after the "Stretching ... with Argon2id" line when creating a vault or adding a passphrase / FIDO2 keyslot:
Stretching passphrase with Argon2id (about 500 ms)...
memory allocation of 268435456 bytes failed
Aborted
It is not about total RAM. 268435456 bytes is exactly 256 MiB,
the memory cost of Argon2id's default Interactive preset. LUKSbox
calls mlockall(MCL_CURRENT | MCL_FUTURE) at startup so derived keys
can never be paged to swap or captured in a hibernate image. With
MCL_FUTURE set, every later allocation must be lockable, bounded by
RLIMIT_MEMLOCK (ulimit -l) - not by free memory. A QubesOS AppVM
ships with ulimit -l at 128 MiB, below the 256 MiB Argon2id
buffer, so the kernel refuses the allocation even on a VM with several
free GiB.
Confirm the diagnosis:
ulimit -l # locked-memory limit, in KB. 131072 == 128 MiB
free -h # shows plenty of free RAM; total RAM was never the cap
If ulimit -l prints something under 262144, that's the cause.
Fix (recommended, persistent). Raise the locked-memory ceiling in
the TemplateVM, not the AppVM - an AppVM's /etc is reset from its
template on every boot, and in Qubes the terminal is usually launched
outside pam_limits, so the systemd default is the reliable knob.
Inside the debian-trixie (or whatever) template:
sudo mkdir -p /etc/systemd/system.conf.d
printf '[Manager]\nDefaultLimitMEMLOCK=infinity\n' | \
sudo tee /etc/systemd/system.conf.d/99-luksbox-memlock.conf
Shut down the template, then restart the AppVM. ulimit -l now comes
up unlimited and luksbox runs with full-strength 256 MiB Argon2id,
no further ceremony.
Why sudo ... one-liners don't help. Raising ulimit -l only
affects the shell you run it in and its children, and sudo / su /
runuser open a fresh PAM session that re-applies the 128 MiB cap
right before luksbox starts. So ulimit -l unlimited in one shell
followed by launching luksbox in another (or after dropping back to
your user) silently reverts. If you need a one-off without touching the
template, raise the limit and run luksbox as root in the same
shell, then fix ownership afterward:
sudo -i
ulimit -l unlimited && ulimit -l # must print: unlimited
luksbox wizard # vault is created root-owned
exit
sudo chown "$USER:$USER" vault.lbx
No-config alternative. A smaller Argon2id memory cost fits under
the 128 MiB ceiling with zero system changes. In the wizard's
Argon2id strength prompt choose Custom and set the memory cost
to e.g. 65536 KiB (64 MiB). FIDO2-wrapped keyslots tolerate this
well since their entropy comes from the authenticator, not the
passphrase; a passphrase-only slot at low memory is more brute-forcible
offline, so prefer raising ulimit -l when the slot is passphrase-only.
GUI fails to start: Error: NoGlutinConfigs(...)
A QubesOS AppVM has no GPU passed through, so the GUI's OpenGL backend can't find a hardware config and aborts before the window opens:
$ luksbox-gui
Error: NoGlutinConfigs(ConfigTemplate { ... }, ...)
Render in software with Mesa's llvmpipe rasteriser instead:
sudo apt install libgl1-mesa-dri # Debian / Ubuntu / Qubes template
LIBGL_ALWAYS_SOFTWARE=1 luksbox-gui
Recent builds detect this exact failure and re-launch themselves with
software rendering automatically, so on those you only need the
libgl1-mesa-dri package present. The luksbox CLI needs no GPU and
works regardless.
Build from source
See Build from source for the cargo-based path (useful for development, Raspberry Pi, MUSL static binaries, etc.).