Move the staged changelog entries under a 0.5.3 heading dated 2026-10-16, marked provisional in the heading itself, and leave an empty Unreleased section above it. The topic groups follow the order the 0.5.2 section uses, and fixes that described one mechanism in several entries now read as one: the gateway's virtual IP handling, the macOS sending threads, the transport counters, the forged and unreadable SessionMsg3 and SessionSetup cases, and the same-epoch msg1 handling. No entry's detail was dropped. Add the release notes and mirror them byte for byte to RELEASE-NOTES.md, with every link absolute and each paragraph on one line. They lead with who should upgrade and what to do first: the SSH rule and gateway forwarding before an OpenWrt upgrade, the farthest-first order for routers reached over an 802.11s mesh, the Windows installer's stop on a key left in \etc\fips, the refusal of a config that configures nothing, the gateway's LAN-only translation and pool checks, and the changed fips.nft, including what the systemd tarball does with an edited copy. The upgrade steps say to restart fips after the network reload on an OpenWrt mesh or gateway router, since a running daemon does not form links over a recreated interface, and give the upgrade, reload and restart as one detached command for a router reached over SSH. The FreeBSD restart after the package upgrade is required, because pkg ends the daemon the package starts. On Windows, a key moved out of \etc\fips needs node.identity.persistent: true beside it and the old fips.yaml deleted, and a service registered by hand is checked with sc.exe qc first. On Debian, the steps cover each answer at the fips.nft prompt, an upgrade run without a terminal, and masking fips-dns on a host that renamed the TUN, which fips-dns does not support. A gateway on a VLAN device on a bridge is affected only when br_netfilter passes bridged IPv6 to the firewall, and only for clients whose traffic enters the bridge untagged; the notes say how to check and what the workaround costs, and that hosts off gateway.lan_interface lose .fips access. They state the wire-format comparison and what it does not cover, the limits that remain, the advisories accepted with the release including RUSTSEC-2024-0449, that no crate was added to the lockfile, the fips-mesh crate name and how a dependent names it, what was measured and what was not, and the contributors. The README's status badge, release-notes link and status paragraphs follow the release, without naming a branch. Correct documentation that no longer matches the release: - The fips and configuration references say the Windows \etc\fips config probe is deprecated, that the daemon warns when it loads a config from there, and that from v0.6.0 the search no longer looks there. - Getting started no longer says there is no cargo install path, since the crate is published; it says cargo install fips-mesh installs only the binaries and is not how to install the daemon. - The reachability how-to names its probe placeholder as a substitution, and the gateway port-forward recipe marks its example mesh address as the one to replace. - The mesh firewall how-to says the systemd tarball keeps an edited fips.nft and writes the new one as fips.nft.template. - The gateway design document and the configuration reference state the bridge netfilter condition under which a VLAN device on a bridge does not serve its clients. - The FreeBSD package README no longer says the package restarts the services on upgrade, and says to restart them by hand. - The OpenWrt package README's mesh upgrade order adds the fips restart after the reload, as a detached command.
FIPS FreeBSD packaging
Builds a native FreeBSD .pkg shipping fips, fipsctl, fipstop,
rc.d services, and .fips DNS integration. fips-gateway is excluded
(its NAT backend is nftables, Linux-only).
Platform notes: the Ethernet and BLE transports are not available on
FreeBSD (UDP, TCP, Tor, and Nym are). The UDP datapath deliberately
uses the portable single-packet receive loop — FreeBSD's recvmmsg(2)
is a libc loop over recvmsg, not a kernel batch, so the Linux/macOS
batched arm would gain nothing — and the connected-UDP fast path is
not compiled pending FreeBSD-specific SO_REUSEPORT validation.
Build
./packaging/freebsd/build-pkg.sh # cargo build --release + pkg create
./packaging/freebsd/build-pkg.sh --no-build # package existing release binaries
Output: deploy/fips-<version>-freebsd-<arch>.pkg. pkg versions cannot
contain - or +, so both are mapped to .: a Cargo version of
<x.y.z>-dev becomes fips-<x.y.z>.dev-freebsd-amd64.pkg.
Install
pkg add ./deploy/fips-<version>-freebsd-<arch>.pkg
# post-install seeds this from the sample if absent, at mode 0600
vi /usr/local/etc/fips/fips.yaml
sysrc fips_enable=YES fips_dns_enable=YES
service fips start
service fips_dns start
fipsctl show status
Config installs sample-style (@sample semantics via manifest
scripts), so an edited fips.yaml survives upgrade/removal.
fips.yaml is installed 0600 — it may hold the node's private key
(nsec:). The daemon runs under daemon(8) with pidfile
/var/run/fips/fips.pid and logs to /var/log/fips.log (rc.conf
knobs: fips_config, fips_flags, fips_logfile).
The log is rotated by /usr/local/etc/newsyslog.conf.d/fips.conf: five
bzip2-compressed generations of 1000 KB. daemon(8) runs with -H and
records its own pid in /var/run/fips/daemon.pid; newsyslog signals that
pid after the rename, and daemon(8) reopens the log. The entry covers
the default fips_logfile only, so a log moved elsewhere needs its own
newsyslog entry. The entry belongs to the package and is replaced on
upgrade.
The package creates a fips group; members can run fipsctl and
fipstop without root (pw groupmod fips -m <user>, then re-login).
On pkg upgrade the services are stopped before the binaries are
replaced, and the package starts them again afterwards if enabled, but
pkg 2.8.4 ends a daemon that a package script starts once pkg exits
(measured with pkg install of a package file), so that start does not
last. After an upgrade, run service fips restart
and, if you use it, service fips_dns restart. On pkg delete the
services are stopped and the .fips resolver drop-in is removed.
.fips DNS integration
The daemon answers .fips queries on [::1]:5354. fips_dns points
the system resolver's fips. zone there; backends tried in order:
base local_unbound (drop-in /var/unbound/conf.d/fips.conf), pkg
unbound, pkg dnsmasq. The unbound drop-in must (and does) set:
do-not-query-localhost: no— unbound's default silently refuses loopback forwarders, SERVFAILing every.fipsquery.do-ip6: yes— the daemon binds::1only.domain-insecure: "fips."— the zone is unsigned.
One-time host resolver setup (NOT automated)
The package configures the fips. zone only; making the local
resolver the system resolver is an operator decision. On a typical
box:
sysrc local_unbound_enable=YES
local-unbound-setup 1.1.1.1 9.9.9.9 # explicit upstreams — see below
service local_unbound restart
Field-tested caveats (fips-dns-setup detects and warns about each):
/etc/resolv.confmust list a loopback nameserver (ideally only127.0.0.1), or nothing ever queries unbound and.fipscannot resolve.- Do not use a home-router DNS proxy as unbound's upstream. Many CPE forwarders are EDNS-broken; unbound always sends EDNS, so every public query SERVFAILs. Forward to real resolvers (ISP or public).
- Remove
options edns0from/etc/resolv.confif present, and setresolv_conf_options=""in/etc/resolvconf.confso resolvconf(8) does not re-add it — against an EDNS-broken router it breaks libc resolution outright. - Never run
local-unbound-setupwith no arguments while resolv.conf already points at 127.0.0.1 — it snapshots that as upstream and forwards unbound to itself.
Debugging
drill -p 5354 <npub>.fips @::1 AAAA # daemon directly (bypasses unbound)
drill <npub>.fips AAAA # full chain; SERVER: must be 127.0.0.1
cat /var/run/fips/dns-backend # which backend fips_dns configured
The TUN interface gets a kernel-assigned name (tun0, tun1, ...),
like utun on macOS, and is destroyed automatically when the daemon
exits. ifconfig <name> prints Opened by PID <n> for the process
holding a tun device.