Release notes
What changed in each release, newest first. A behaviour change that can stop something that worked before comes first in its release. nfltr version prints the version you run; nfltr update updates it.
v2.1.56
Fixes
- A session opened as a drain's deadline cuts the connection is refused, not lost. A session whose opening crossed the drain's cut used to get no answer, and its opener saw the connection end. It is now refused, so the opener knows nothing ran there and can retry on another connection. Sessions opened earlier in a drain run to their end, as before.
nfltr node joinrefuses another machine's agent-to-agent key at start. A node whose key file belongs to a different machine than the one it signs in as now stops at once, and the message names both machines and the command that makes the right key (nfltr orch hub machines add <name> --out <file>). Before, it started and then every call to it was refused. If you hit this, follow the re-key steps under v2.1.55's behaviour changes.- A session closed from both sides frees its place at once. When both ends of a session had closed their write side, the session's place under the connection's session limit was freed a moment late. A new session opened in that moment could be refused as over the limit, and that refusal closed the connection with every session on it.
v2.1.55
Who can read your traffic, said plainly
Every CLI banner, the dashboard and the proof page now say one of two things:
- "end to end: the relay can't read this": sessions pinned to the agent's certificate (
nfltr dial,tcp-connect,ssh-proxyor aconnect:mapping with--pin), andnfltr wg. - "the relay can read this":
/browse/, share links and unpinned sessions.
The old "Verified" and "Blind relay" labels on share links are gone. A share link is always decrypted by the relay, even when the agent has its own certificate: only a client that checks the agent's key gets end to end. An agent whose ACME certificate isn't issued yet shows no fingerprint and no badge, instead of ACME:pending.
Behaviour changes
- A root key file reaches only the machine you name (
nfltr wg,nfltr p2p). A bare service name now reaches only an exit under the root key. Reach an exit under a machine key as<machine>.<service>or by itsm-<id>-<service>ref. - A node on another machine needs that machine's A2A key. A key made with
nfltr orch hub machines add --out <file>and no name (as v2.1.54'snfltr startprinted it) is the key of the hub's machine. A node on another machine with that key now gets every call refused, andnfltr node joinrefuses the key at start, naming both machines. Keys made by name (machines add <name> --out, as the v2.1.54 notes said), and nodes on the hub's own machine or using its API key, keep working. To re-key such a node:- Where the hub runs:
nfltr machineslists the node machine's name, the one it signed in with (nfltr config login --machine <name>). - There:
nfltr orch hub machines add <name> --out a2a-machine.key. - Copy the file to the node's machine yourself, never through nfltr, as
~/.config/nfltr/a2a-machine.key(mode 0600), replacing the old one (or pass it with--e2ee-key-file), then startnfltr node joinagain.
- Where the hub runs:
--share-loginworks on a default share, and is refused with--e2ee-cert,--acme-domainor--mode passthrough, where the relay can't sign visitors in.nfltr shellprints its SSH host key's fingerprint, to compare with the one your SSH client shows the first time.
Security fixes
We reviewed every claim in Proving nfltr's end-to-end encryption against a hostile relay against the code. The post's update note lists what we found:
- Root key files and WireGuard or peer-to-peer: a client holding the root key file used whatever machine the relay named, so the relay could send it to an exit of the same service name on another of your machines. It now checks the machine against your own list of machines.
- Agent-to-agent calls: a call's machine label keys it only when it names the machine its agent belongs to.
nfltr node joinrefuses a machine id your hub already issued, andmachines addrewrites an issued machine's key only for the id you type. - Peer-to-peer data records: a write that failed partway could reuse an encryption nonce. It now ends the connection, as signalling writes did from v2.1.54.
- Share labels: a share served with the relay's certificate was labelled verified end to end. It is now labelled as the relay reading it (above).
- Revoked machines: a machine's dashboard-cookie connection stayed open after the machine was revoked. It now ends.
Fixes
- During a relay drain, a session could end as "connection lost" instead of
drain_deadline. A session that had ended just before the drain's deadline could also lose its end. - Relays name themselves to the agents that connect, and refuse an agent that is already attached to them through another address: the relay side of agents with several relays.
- Relays you run yourself: the machine CA key may be group-readable (0440) when systemd passes it as a credential.
v2.1.54
Every machine has its own identity
Until now one API key stood for a whole account. From v2.1.54 each machine has its own identity, key and certificate. A lost key affects only that machine: revoke it, and your other machines keep working. You also decide which machines can reach which.
This is a hard cut. Keys from before v2.1.54 are refused with machine_not_enrolled. On each machine:
nfltr update --apply(add--with orchwherenfltr orchornfltr noderuns).nfltr config login --machine <name>. On a machine without a browser, choose Add machine in the dashboard's Fleet view and use the code or key it shows.- Restart what runs there (
nfltr up,nfltr http,nfltr node join, ...).
Behaviour changes
- New addresses. Agents are reached as
<machine>.<service>;nfltr dialprints the exact address when the agent starts. Update scripts,connect:mappings and bookmarks that name an old address. Share links made before this release have ended: make them again. - End-to-end encrypted TCP services list their clients. An agent with an
e2ee: trueservice, or one reached with--pin, refuses to start until it lists each client's key: runnfltr config client-keyon the client, and put the key inallow_client: [...](or--allow-client). Clients keep using--pin. - An agent never dials a target the relay names. An end-to-end encrypted
nfltr tcpneeds its own target (--forward), and the raw sessions ofnfltr http --e2eeneed--tcp-forward. Before, a relay could choose where the agent sent the decrypted bytes. - Agent-to-agent calls are always end-to-end encrypted, with a key per machine. Your hub makes its root key the first time it starts;
nfltr node joinon the hub's machine gets its machine key by itself. For a node on another machine, runnfltr orch hub machines add <machine> --out <file>where the hub runs, copy the file there yourself, and pass it tonfltr node join --e2ee-key-file <file>. - Fleet tokens are replaced by Add machine in the dashboard (enrol codes and tokens).
- Relays you run yourself: key files from v2.1.53 or earlier are refused; re-add each machine with
nfltr-relay keys add. --retries 0is one connection attempt, with no retry.
Machines and groups
nfltr machineslists your machines, andnfltr machine statusshows this one's identity. Each machine renews its certificate by itself.- By default your machines are in one group and can all reach each other. Split them, and allow only the paths you want with
nfltr groups allow, or in the dashboard's Groups view. Groups decide which machines reach which agents; the account's mailboxes, webhooks and stored files stay shared by all its machines. - A workload can enrol with a token from its platform's OIDC issuer:
nfltr machine enrol --oidc-token <file>, with the workload rules in Groups.
Security fixes
These came from the new machine-checked proofs of every end-to-end encrypted path, written with the relay as the attacker (Proving nfltr's end-to-end encryption against a hostile relay):
- An end-to-end encrypted
nfltr tcpwithout--forwardsent the decrypted bytes to the target the relay named. Now refused (see above). - An end-to-end encrypted TCP service accepted any client, so a relay could open a pinned session of its own. Clients are now listed (see above).
- Agent-to-agent calls could be rerouted to another of the owner's machines, reflected back to their sender, or replayed. Each call is now bound to the machine it was meant for, and each direction has its own keys.
- WireGuard and peer-to-peer sessions could be sent to another exit holding the same key. Each session is now bound to the exit's name.
- In peer-to-peer transfers, a signalling write that failed partway could reuse an encryption nonce. A failed signalling write now ends the connection. (The data records had the same gap; their fix follows in the next release.)
- The hub page of a paired phone could show an approval the hub had accepted as refused.
Additions and fixes
- WireGuard (
nfltr wg) and peer-to-peer (nfltr p2p) accept a machine key file as their pairing key. tcp-connectkeeps opening sessions past 1,024 on one connection.- A share link can ask its visitors to sign in; the dashboard's Share card sets it up.
Dashboard
- New Fleet and Groups views for machines and reach rules.
- The agent's Proof panel is now Encryption: what is encrypted to the agent, what the relay decrypts, and one command to check it.
- Browse is offered only for agents that serve it.
- The Custom domains form says that a domain's agent and service are fixed once added.
v2.1.53
Custom domains
- Custom domains are available on nfltr.xyz: an agent's site can answer on a domain you own (
www.example.com, or the apexexample.com). You prove the domain with a TXT record, point it at nfltr with a CNAME (or A/AAAA records where a CNAME is not allowed), and nfltr gets and renews its certificate. Dashboard, Account, Custom domains; Serve Your Site on Your Own Domain.
Behaviour changes
- Account settings the relay never enforced are gone from the dashboard and its API: per-user settings, the IP allowlist, the rate limit, max agents and the share link lifetime. Max keys and the share reservation lifetime stay, and are enforced.
- Signing out is a POST.
GET /logoutno longer signs you out; the dashboard's sign-out button sends a POST. An open dashboard stream ends within 30 seconds of signing out. - A connected agent cannot be deleted. Its row has no Delete, and the API answers 409 while it is connected.
- Uploaded files are kept 7 days after the last upload, and each account has a storage limit; over it, an upload is refused with 413
LIMIT_EXCEEDED.
Fixes
- HTTP proxies.
connect:mappings,nfltr dialandtcp-connectnow go throughHTTPS_PROXYwith HTTP CONNECT; before, they dialed the relay directly and never connected from a site whose only way out is a proxy. The agent's own data connections followHTTPS_PROXYtoo. --exit-with-parentin containers. Since the end of October a parent with PID 1 counted as gone, so a sidecar or dial child of an app running as a container's main process exited at once (parent_gone). It now stays while its parent runs.- Share revocation drops every cached copy of a share by its id on every replica, also when the revocation arrives while that share's lookup is still running.
trust_loopbackno longer trusts a request that a same-host reverse proxy forwarded with a forwarding header.- WebSocket frames with an invalid 64-bit length are a protocol error instead of closing the connection abruptly.
Dashboard
- Simpler Home: your agents, shares and sites, live WireGuard tunnels and connect clients, and usage first; orchestration one link away. Each agent is listed once, with details one click away.
- Fleet tokens are under Account for every user.
- Custom domain problems read as sentences, not codes.
Docs and site
- Pricing: how billing will work, with no prices yet. nfltr.xyz stays free until further notice.
- Your software in your customers' networks, for vendors whose agents run at customer sites.
- New posts: What TLA+ found in nfltr and nfltr against jprq, portal, sish and the October four.
v2.1.52
Behaviour change: nfltr tcp refuses a session without a pin
nfltr tcp offers end-to-end encryption by default (--e2ee), and it now takes only sessions that pin its certificate. A session without a pin was plain text inside the relay's own TLS, so the relay could read it while the agent's banner said "e2ee: enabled". Such a session is now refused: nfltr tcp-connect and nfltr dial exit 4 with the reason ERROR_REASON_E2EE_REQUIRED, and the message says how to pin.
- To keep end-to-end encryption, pin the fingerprint
nfltr tcpprints:nfltr tcp-connect <agent> <port> --pin <fingerprint>,nfltr dial <agent> <port> --pin <fingerprint>, orpin:on annfltr upconnect:mapping. Take the fingerprint from the agent's own output, not from the relay. - To keep unpinned sessions, run the agent with
--e2ee=false. SSH encrypts end to end itself, sonfltr tcp 22usually wants--e2ee=false. - A tcp service of
nfltr upwithoutagent:is now plain (--e2ee=false); end-to-end encryption of a tcp service needsagent:ande2ee: true, as before.nfltr shelland the HTTP commands are unchanged.
The post What "end to end" means for nfltr tcp explains the change, what the relay sees on each path and how it was tested.
Fixes
- Pinned sessions to
nfltr tcpcarry data again. Since v2.1.6, a session pinned to annfltr tcp --e2eeagent finished its TLS handshake and then closed without data: the agent took it for an encrypted share's HTTP. It failed closed (no bytes, nothing readable by the relay). Such a session now carries the port's bytes; a conformance test checks a 64 MiB transfer by SHA-256. - Rolling relay restarts. A request, a site visit or an agent-to-agent call that reaches a replica just as the agent moves onto it now waits for the agent's registration there instead of answering offline, and a forward that reaches the replica the agent just left goes on to the replica it moved to. A two-replica test drains one replica under steady visits and expects no failed visit.
- Site cookies. A site's or a mailbox route's response drops the agent's
Set-Cookieheaders also when its handler writes no status line first; that path let them through before. - The hub no longer launches one agent too many when several spawns race for the last free slots on a node.
Relay
- Per-source limits. The relay limits connections per source address at accept, gives a gRPC connection 10 s to finish its handshake, and limits datagrams and QUIC handshake datagrams per source address on the QUIC agent link. A share visitor's flood spends that visitor's rate budget, not the agent's, and a refused visit closes its connection (HTTP/2 included).
- Abuse reports. The contact page has an abuse report form (
/contact?topic=abuse), linked from every page's footer as "Report abuse". A share, site, agent or account taken down stops being served on every replica.
Dashboard
- Home shows a status strip and the agents online now, updated live.
- Problems lists the recent problems the relay recorded for your account, such as a visit refused after a takedown; Home shows how many there are.
- Usage splits what your account used by agent and by share.
Running your own relay
- Every Redis client of the relay and of the mailbox service speaks TLS and mutual TLS (
REDIS_TLS_CA_FILE,REDIS_TLS_CERT_FILEwithREDIS_TLS_KEY_FILE,REDIS_TLS_SERVER_NAME); half a configuration fails the start. The directory client now sendsREDIS_PASSWORDtoo, so a password-protected Redis works for relays with several replicas without a TLS proxy in front.
Not in this release
- Custom domains (your own name for a site) are not switched on for nfltr.xyz yet; they come in a later release.