Repository navigation
NexaPipe v0.6.0
Every device now holds a credential of its own, so revoking one no longer rotates
the rest. A config.toml written before this release loads unchanged: a client
carrying only secret keeps authenticating exactly as it did.
One thing breaks. /metrics renders request latency as a histogram:
nexapipe_request_duration_ms_bucket{le="…"} beside _sum and _count replaces
nexapipe_request_duration_ms_total. A scrape or dashboard looking for the old
counter will not find it; a mean that used to divide it by
nexapipe_requests_total reads _sum the same way.
Added
-
Per-device credentials.
[auth.clients.<id>]gains adevicestable — one
TOTP secret per device, issued at enrollment and revoked on its own:[auth.clients.client-001.devices.laptop] secret = "LAPTOPSECRET"
Nothing there is written by hand: enrollment files the device, and so does
nexapipe client add client-001 --device laptop. -
Revocation closes what the device already holds, not only what it dials
next. The reload that notices a device left[auth]closes its connections,
with a new close codeREVOKED = 6that the client reports as "this credential
is gone" rather than as a code typed wrong. -
Each install says which device it is. The desktop answers after its
hostname, Android after the device model. The name is claimed at enrollment and
nowhere else, so nothing re-enrolls on its own, and a credential that was never
issued to a device keeps answering as it does today. -
An access line says whose request it was. Every line ends
client=… device=…, and/v1/connectionsanswers who is connected rather than
only how many. -
nexapipe client list|add|revoke, each taking--device, writing
config.tomlthrough the same lock the server reads it with — a running
instance picks the change up on its next reload./v1/*stays read-only on
purpose: its token has no scope and no rotation. -
[auth.clients.<id>].unnamed_device_allowed(defaulttrue): set to
false, a peer that names no device is refused rather than answered under the
client's shared secret. -
A systemd unit for the server in both READMEs. The relay has had one in
docs/self-hosted-relay.mdsince earlier in this release. -
Desktop: session totals, and a page listing the connections a running proxy
holds. A running proxy says what quitting should do.
Changed
- Request latency on
/metricsis a histogram (see above). - The desktop TUN shares DNS and address space with other TUN apps, instead of
taking both over. - The workspace declares the Rust version it needs:
1.89.
Fixed
- A name outside the hijack is answered through the host's own resolver, instead
of the TUN swallowing it. - Desktop: no empty window while the app starts; a launch with no frame still
sends its start-up timings; the macOS bundle keeps the content security policy;
the build gets the vendoredsmoltcppatch; a tunnel whose DNS was never
hijacked no longer runs as though it had been. - Server: an enrollment can no longer take over a device that is already in the
table; a peer is no longer connected before it is revocable;client add
fails instead of reporting a secret it did not write. - Android: no native crash on the stop path, no stop on the main thread, no
credential stored unencrypted without asking. config.tomland the--qr-outfile are created private, and neither follows
a symlink to reach the file;[peers]refuses a key it does not recognise; a
TOTP period that does not fit is refused at enrollment; each TUN flow and every
preconnect runs under a budget.
Not in this release
Per-device key pairs (the credential stays TOTP), a write API (client add|revoke are subcommands, not POST /v1/clients), and package managers.
Full detail in
CHANGELOG.md;
what comes next in
docs/ROADMAP.md.