/ Documentation / Getting started / Install on Linux

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.

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:

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.

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:

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:

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

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.).