Files
fips/docs/how-to/README.md
Johnathan Corgan 8560408135 Prepare the node for the rekey state machine
Groundwork the rekey state machine needs from the node, each part
standing on its own.

Measure an active peer's rekey timers on the host monotonic clock type.

An active peer's rekey timers (the session and link ages, the dampening after
a peer's rekey msg1, the responder's pending hold, the drain and the last
cutover) are now held as instants of a PeerClock, an alias of the host's
monotonic clock, beside the session table's SessionClock, instead of bare
std::time::Instant values. Ages are read as the distance from that clock's
now.

Schedule link rekey msg1 resends on the monotonic clock.

A link rekey's msg1 resend schedule was stamped and read on the wall clock,
while every other link and session rekey timer was already monotonic. A
forward step of the system clock (an NTP correction, a manual set, a resume
from suspend) therefore made a resend due at once, and a backward step held
every resend back by the size of the step, so the rekey stalled until its
handshake timed out.

Read unauthenticated handshake messages on a fork of the handshake.

A Noise read mixes the sender's ephemeral and the DH results into the
handshake, and advances its nonce, before the AEAD that authenticates the
message runs, so a forged or corrupt msg2 or msg3 that fails partway
would leave a handshake the genuine message can no longer complete. Until
now each caller took the handshake out of its slot and called a
try_read_* method that put back the fields its read writes, a list kept
by hand for each message, and then put the handshake back.

Count the silent drops, split the msg1 refusals, and gate ignored tests.

An encrypted frame naming an unknown session index, or one left pointing at
a removed peer, was dropped before any peer was looked up, so nothing
counted it: the side of a diverged link whose index the peer still addresses
was silent. Both drops are now counted in a dataplane family that
show_metrics serves. The handshake and FSP session reject counters were kept
but served by no query; show_metrics now serves them too, as of the last
tick. The msg1 refusals the classification decides each get their own
handshake counter (max_peers, rekey_pending, rekey_tiebreak,
answered_before, off_link) instead of all landing in bad_state.

Make ActivePeer's session-slot and rekey methods private to the crate.

The methods of ActivePeer that read or change its Noise sessions and
their indices, the K-bit, the session time base, the stored link-setup
msg2, the peer's startup epoch and the rekey cycle were public, so the
library published them although only the node's own handlers can call
them safely: a call from outside could leave a peer's sessions out of
step with the node's index tables. They are now pub(crate), so the rekey
work that follows can change them without another break in the library's
interface. Four of them, set_their_index, clear_handshake_msg2,
set_rekey_in_progress and set_msg1_next_resend, had no caller and are
removed, and pending_their_index, called only by tests, is built for
tests only.
2026-10-20 02:39:06 +00:00

36 lines
3.5 KiB
Markdown

# How-To Guides
Task-oriented, step-by-step recipes for operators with a specific
goal in mind. Each guide assumes the reader already knows what FIPS
is and wants to get a particular thing done — enable a feature,
deploy a component, troubleshoot a class of problem.
How-to guides do not teach concepts (that is the role of design/)
and do not enumerate options (that is the role of reference/). They
take the reader along the shortest correct path from "I want to do
X" to "X is done".
## Available Guides
| Guide | Goal |
| ----- | ---- |
| [enable-mesh-firewall.md](enable-mesh-firewall.md) | Activate the default-deny nftables baseline on `fips0` |
| [enable-nostr-discovery.md](enable-nostr-discovery.md) | Turn on Nostr-mediated discovery (3 capabilities — resolve, advertise, open — across 5 scenarios) |
| [deploy-tor-onion.md](deploy-tor-onion.md) | Run a Tor onion service for inbound FIPS connections |
| [tune-udp-buffers.md](tune-udp-buffers.md) | Set host sysctls so FIPS UDP sockets don't get clamped |
| [tune-file-descriptors.md](tune-file-descriptors.md) | Raise `RLIMIT_NOFILE` so a busy node doesn't exhaust file descriptors (`EMFILE`) as peer count grows |
| [run-as-unprivileged-user.md](run-as-unprivileged-user.md) | Run the daemon under a dedicated unprivileged service account (drops the default-root posture) |
| [deploy-gateway.md](deploy-gateway.md) | Manually deploy `fips-gateway` on a non-OpenWrt Linux host (LAN-to-mesh outbound + mesh-to-LAN inbound port-forwards). For the OpenWrt path, see the gateway tutorial. |
| [troubleshoot-gateway.md](troubleshoot-gateway.md) | Diagnostic recipes for the gateway, organised by half (outbound, inbound, common) |
| [persistent-identity.md](persistent-identity.md) | Provision a stable Nostr keypair so the node keeps the same npub across restarts |
| [host-aliases.md](host-aliases.md) | Use shortnames (`test-us01.fips`, `my-laptop.fips`) instead of full npubs by editing `/etc/fips/hosts` or setting peer aliases |
| [set-up-bluetooth-peer.md](set-up-bluetooth-peer.md) | Configure a Bluetooth Low Energy peer link |
| [set-up-80211s-mesh-backhaul.md](set-up-80211s-mesh-backhaul.md) | Link OpenWrt FIPS routers over an open 802.11s radio backhaul (FIPS provides encryption, authentication, and routing) |
| [set-up-open-access-ssid.md](set-up-open-access-ssid.md) | Broadcast the open `!FIPS` access SSID so phones and laptops roam onto the mesh (one ESS: save once, roam every FIPS router) |
| [diagnose-reachability.md](diagnose-reachability.md) | Find out whether one node can reach another, by what route, and why not: `fipsctl probe`, peers versus sessions, rerolled identities, relay ACLs and `.fips` name resolution |
| [diagnose-mtu-issues.md](diagnose-mtu-issues.md) | Triage MTU-shaped failures and rule out their imposters (bufferbloat, transport saturation) |
| [use-the-native-datagram-api.md](use-the-native-datagram-api.md) | Enable the experimental native datagram API and write a program that sends and receives datagrams by pubkey and port (no IPv6 emulation, no TUN). Read the `fips` group warning first |
| [write-a-native-api-client.md](write-a-native-api-client.md) | Speak the native datagram API's line protocol directly from C, Python or Go, where there is no client library |
| [serve-many-peers-on-one-thread.md](serve-many-peers-on-one-thread.md) | Handle every native API flow from one `poll` loop instead of a thread per peer |
| [migrate-an-embedder-to-v0.6.md](migrate-an-embedder-to-v0.6.md) | Move code that uses the `fips` library crate to v0.6.0: each change that can stop it building, and what to do |