Repository navigation
v0.1.9 — LustLess (hardening: local tamper, fail-open DNS, poisoned queues)
Linux accountability client (Covenant Eyes-compatible, clean-room reimplementation).
Install
curl -fsSL https://github.com/HenryGetz/LustLess/releases/latest/download/install.sh | sudo bashDetects your distro, downloads the matching package, installs it with the
native tool, starts the agent — and the sign-in window opens. Log in there.
Other ways:
| Distro | File | Command |
|---|---|---|
| Debian / Ubuntu / Zorin / Mint | lustless_0.1.9_amd64.deb |
sudo apt install ./lustless_0.1.9_amd64.deb |
| Fedora | lustless-0.1.9-1.x86_64.rpm |
sudo dnf install ./lustless-0.1.9-1.x86_64.rpm |
| Bazzite / immutable Fedora | lustless-0.1.9-1.x86_64.rpm |
sudo rpm-ostree install ./lustless-0.1.9-1.x86_64.rpm && reboot |
| Arch / EndeavourOS / SteamOS | lustless-0.1.9-1-x86_64.pkg.tar.zst |
sudo pacman -U ./lustless-0.1.9-1-x86_64.pkg.tar.zst |
| Alpine | lustless-0.1.9-r0.apk |
sudo apk add --allow-untrusted ./lustless-0.1.9-r0.apk |
Uninstall: sudo apt purge lustless (or the dnf/rpm-ostree/pacman/apk
equivalent) — restores the DNS, browser-policy and polkit state exactly as
found.
What's new — hardening
Two focused reviews (local attack surface; error paths) were run against the
shipped code and everything they found is fixed here. In an accountability
client the person at the keyboard is the adversary, so the tamper findings are
as important as crashes.
Local tamper, previously possible for any unprivileged user:
- Dashboard tokens were validated and then discarded, so any local user could
fetch a token over the 0666 IPC socket and drive the signed-in session: sign
it out, set the weakest filter level, or allow-list*. Mutations now require
the token to own the session. 0x4c USER_LOGOUThad no ownership check — any uid could force a sign-out
(and withfail_closed_when_signed_out = false, stop the filter).0x61/0x43/0x4d/0x54/0x67leaked the signed-in username, filter
state and outbox path to any uid, minted a dashboard token for them, and let
them trigger diagnostics, outbox flushes and a feed fetch.- The break-glass audit line now carries the promised
org.lustless.break-glass uid=… reason=…tag; denials are distinguishable. - The agent's session-token file no longer falls back to world-writable
/tmp
(symlink capture) and refuses a symlinked directory.
Fail-open and queue defects:
- Filtering could silently be off while the daemon looked healthy: a DNS
forwarder that failed to build or bind only logged. It is now markedOutage
and reported,dns.listen/ports are validated at startup, and an unparsable
config refuses to start instead of quietly using defaults. - Block pages never loaded: the synthesized CNAME was owned by the block
host instead of the queried name, so a stub resolver returned NODATA. Now
RFC 1034-shaped. - A fail-closed classifier exit counted as clean (it prints
byeand
returns 1), bypassing the crash budget, metric and escalation and respawning
every 5 s forever with screen accountability off. - Rejected (4xx) batches poisoned the upload queue forever (
drop_invalid
matched only locally-invalid rows, so nothing was deleted and the batch was
re-claimed oldest-first). Deterministic rejections now delete exactly the
claimed rows. - A second daemon could run, sharing the outbox/spool/crash ledger and
reporting a false crash:lustlessdnow holds an exclusiveflock. - Spool orphans are swept by the daemon (previously only at classifier
startup), shutdown aborts overrunning tasks, and the staged update payload is
removed after install.
Workspace suite: 313 passed, 0 failed. Everything from 0.1.8 (crash
pipeline), 0.1.7 (parity audit, real-model proof), 0.1.6 (Zorin Lite branding),
0.1.5 (DNS that stays alive) and 0.1.4 (agent main loop) is unchanged.