M5: documentation, packaging, and verified nix build
Rewrite README with tested examples, config reference table, unlock method matrix, NixOS-specific notes on LD_LIBRARY_PATH for cryptsetup token plugins, FIDO2 enrollment instructions, and troubleshooting section. Verify nix build produces working binary with version injection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
112
README.md
112
README.md
@@ -3,47 +3,74 @@
|
|||||||
A CLI tool for mounting and unmounting LUKS-encrypted volumes. Latin for
|
A CLI tool for mounting and unmounting LUKS-encrypted volumes. Latin for
|
||||||
"strongbox."
|
"strongbox."
|
||||||
|
|
||||||
arca talks to udisks2 over D-Bus, so no root privileges are required. It
|
arca talks to udisks2 over D-Bus for passphrase/keyfile unlock (no root
|
||||||
handles the unlock-then-mount and unmount-then-lock sequences as single
|
needed) and falls back to cryptsetup for FIDO2/TPM2 token-based unlock
|
||||||
commands.
|
(requires doas/sudo). It handles the unlock-then-mount and
|
||||||
|
unmount-then-lock sequences as single commands.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
arca mount /dev/sda1 # unlock + mount by device path
|
|
||||||
arca mount backup # unlock + mount by config alias
|
arca mount backup # unlock + mount by config alias
|
||||||
|
arca mount /dev/sda1 # unlock + mount by device path
|
||||||
|
arca mount backup -m /mnt/usb # mount at a specific mountpoint
|
||||||
arca unmount backup # unmount + lock
|
arca unmount backup # unmount + lock
|
||||||
arca status # show unlocked LUKS volumes
|
arca status # show all LUKS volumes and their state
|
||||||
|
arca init # generate config from detected devices
|
||||||
|
arca --version # print version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Mount and unmount are idempotent: mounting an already-mounted device
|
||||||
|
prints the existing mount point; unmounting an already-locked device is
|
||||||
|
a no-op.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Optional. Without a config file, arca works with device paths directly.
|
Optional. Without a config file, arca works with device paths directly
|
||||||
|
using passphrase unlock.
|
||||||
|
|
||||||
`~/.config/arca/config.yaml`:
|
Run `arca init` to auto-generate a config from detected LUKS devices
|
||||||
|
(excludes the root filesystem). Edit the generated file to set aliases,
|
||||||
|
methods, and mount points.
|
||||||
|
|
||||||
|
`~/.config/arca/config.yaml` (respects `$XDG_CONFIG_HOME`):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
devices:
|
devices:
|
||||||
backup:
|
backup:
|
||||||
uuid: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
uuid: "b8b2f8e3-4cde-4aca-a96e-df9274019f9f"
|
||||||
mountpoint: "/mnt/backup" # optional — udisks2 picks if omitted
|
mountpoint: "/mnt/backup" # optional — udisks2 picks if omitted
|
||||||
methods: # optional — default: [passphrase]
|
methods: # optional — default: [passphrase]
|
||||||
- fido2
|
- fido2
|
||||||
- passphrase
|
- passphrase
|
||||||
media:
|
media:
|
||||||
uuid: "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
|
uuid: "a1b2c3d4-5678-9abc-def0-1234567890ab"
|
||||||
methods:
|
methods:
|
||||||
- keyfile
|
- keyfile
|
||||||
- passphrase
|
- passphrase
|
||||||
keyfile: "/path/to/media.key"
|
keyfile: "/path/to/media.key"
|
||||||
```
|
```
|
||||||
|
|
||||||
Aliases let you refer to devices by name and ensure stable identification
|
### Config fields
|
||||||
via UUID regardless of device path changes.
|
|
||||||
|
|
||||||
The `methods` list defines the unlock strategies to try in order. If the
|
| Field | Required | Description |
|
||||||
first method fails (e.g., FIDO2 key not present), arca tries the next.
|
|--------------|----------|--------------------------------------------------------|
|
||||||
Supported methods: `passphrase`, `keyfile`, `fido2`, `tpm2`.
|
| `uuid` | yes | LUKS partition UUID (stable across device path changes) |
|
||||||
|
| `mountpoint` | no | Where to mount; udisks2 picks if omitted |
|
||||||
|
| `methods` | no | Ordered unlock strategies; default: `[passphrase]` |
|
||||||
|
| `keyfile` | no | Path to keyfile (required if `keyfile` is in methods) |
|
||||||
|
|
||||||
|
### Unlock methods
|
||||||
|
|
||||||
|
| Method | Backend | Root required | Notes |
|
||||||
|
|--------------|------------|---------------|----------------------------------------|
|
||||||
|
| `passphrase` | udisks2 | no | Prompts on terminal |
|
||||||
|
| `keyfile` | udisks2 | no | Reads file from `keyfile` config field |
|
||||||
|
| `fido2` | cryptsetup | yes (doas) | Requires enrolled FIDO2 token |
|
||||||
|
| `tpm2` | cryptsetup | yes (doas) | Requires enrolled TPM2 key |
|
||||||
|
|
||||||
|
Methods are tried in order. If the first fails (e.g., FIDO2 key not
|
||||||
|
plugged in), arca tries the next.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -53,7 +80,7 @@ Supported methods: `passphrase`, `keyfile`, `fido2`, `tpm2`.
|
|||||||
# flake.nix
|
# flake.nix
|
||||||
inputs.arca.url = "git+https://git.wntrmute.dev/kyle/arca";
|
inputs.arca.url = "git+https://git.wntrmute.dev/kyle/arca";
|
||||||
|
|
||||||
# in your NixOS config or home packages
|
# in your NixOS config
|
||||||
environment.systemPackages = [ inputs.arca.packages.${system}.default ];
|
environment.systemPackages = [ inputs.arca.packages.${system}.default ];
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -66,4 +93,57 @@ go install git.wntrmute.dev/kyle/arca@latest
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Linux with udisks2 running (standard on most desktop distributions)
|
- Linux with udisks2 running (standard on most desktop distributions)
|
||||||
- D-Bus session or system bus access
|
- D-Bus system bus access
|
||||||
|
- For FIDO2/TPM2: `cryptsetup`, `doas` or `sudo`
|
||||||
|
- For FIDO2/TPM2: token must be enrolled via `systemd-cryptenroll`
|
||||||
|
|
||||||
|
## NixOS Notes
|
||||||
|
|
||||||
|
cryptsetup loads token handler plugins (FIDO2, TPM2) via `dlopen`, but
|
||||||
|
NixOS's glibc only searches the binary's baked-in RUNPATH, which doesn't
|
||||||
|
include systemd's plugin directory. arca works around this by setting
|
||||||
|
`LD_LIBRARY_PATH` to the systemd cryptsetup plugin directory when
|
||||||
|
invoking cryptsetup.
|
||||||
|
|
||||||
|
The plugin directory is discovered automatically from
|
||||||
|
`/run/current-system/sw/lib/cryptsetup` or by resolving the
|
||||||
|
`systemd-cryptenroll` binary path.
|
||||||
|
|
||||||
|
Note: cryptsetup's `--external-tokens-path` flag does not work on NixOS
|
||||||
|
due to the same RUNPATH limitation — the flag is accepted but the
|
||||||
|
dlopen call still uses the default search path.
|
||||||
|
|
||||||
|
### Enrolling a FIDO2 key
|
||||||
|
|
||||||
|
```
|
||||||
|
doas systemd-cryptenroll --fido2-device=auto /dev/sda1
|
||||||
|
```
|
||||||
|
|
||||||
|
This prompts for the existing passphrase, then enrolls the FIDO2 key.
|
||||||
|
Verify with:
|
||||||
|
|
||||||
|
```
|
||||||
|
doas cryptsetup luksDump /dev/sda1 | grep -A3 Token
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**"cannot connect to udisks2"**: The udisks2 service isn't running.
|
||||||
|
Check `systemctl status udisks2`.
|
||||||
|
|
||||||
|
**"device not found"**: The device path or alias doesn't match anything
|
||||||
|
udisks2 knows about. Run `arca status` to list detected devices, or
|
||||||
|
`arca init` to regenerate the config.
|
||||||
|
|
||||||
|
**"No usable token is available"**: The FIDO2/TPM2 token isn't enrolled
|
||||||
|
on this LUKS device. Enroll with `systemd-cryptenroll`. Also check that
|
||||||
|
the token plugin is discoverable (see NixOS Notes above).
|
||||||
|
|
||||||
|
**"Not authorized to perform operation"**: udisks2 polkit authorization
|
||||||
|
failed. This happens when mounting a device unlocked via cryptsetup
|
||||||
|
(root-owned mapping). Use `--mountpoint` or set `mountpoint` in config
|
||||||
|
to use privileged mount instead.
|
||||||
|
|
||||||
|
**FIDO2 key not detected**: Ensure the key is plugged in and
|
||||||
|
`/dev/hidraw*` devices are accessible. Check `doas systemd-cryptenroll
|
||||||
|
--fido2-device=list`.
|
||||||
|
|||||||
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1774244481,
|
||||||
|
"narHash": "sha256-4XfMXU0DjN83o6HWZoKG9PegCvKvIhNUnRUI19vzTcQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "4590696c8693fea477850fe379a01544293ca4e2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-25.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user