mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
docs: four-section /docs/ restructure with new-user content, accuracy pass, and gateway feature-set rewrite
Restructures /docs/ by reader purpose (tutorials, how-to, reference, design), adds the new-user-progression and operator-recipe content the prior layout lacked, runs an accuracy pass against current source across the pre-existing design docs, and rewrites the gateway feature-set documentation end-to-end around its actual operational profile (a niche feature designed for systems already serving DHCP/DNS to a LAN, with two independent halves — outbound LAN→mesh, inbound mesh→LAN — sharing one nftables table, one binary, and one control socket). Top-level README and getting-started rewritten around two equally-weighted deployment modes (overlay on existing IP networks; ground-up over non-IP transports). ## Additions - 11 new tutorials in docs/tutorials/: an 8-step new-user progression from single-daemon test-mesh peering through to a ground-up two-device mesh, an IPv6-adapter side-trip walkthrough, an Advanced Tutorials index, and a hand-held OpenWrt walk-through for fips-gateway deployment that exercises both halves of the feature. - 12 new how-tos in docs/how-to/: firewall activation, Nostr discovery (resolve / advertise / open across five scenarios), Tor onion (directory + control_port modes), UDP buffer tuning, unprivileged-user setup, persistent identity, host aliases, Bluetooth LE peering, MTU diagnostics, manual Linux-host gateway deployment (covers both halves), gateway troubleshooting (organised by half), and a section index. - 9 new reference docs in docs/reference/: configuration, wire formats, control-socket protocol, four CLI references (fips, fipsctl, fipstop, fips-gateway), security posture matrix, and Nostr events catalog. Configuration and wire-formats are renamed-and-extended from prior design/ versions; the other seven are net-new. - 6 new design docs: fips-concepts, fips-architecture, and fips-prior-work split out of the deleted fips-intro.md; consolidated fips-mmp and fips-mtu aggregations; and a new generic port-advertisement-and-nat-traversal doc (Nostr-signaled port advertisement plus UDP NAT-traversal protocol, FIPS as an example implementation, suitable for eventual NIP submission). - Top-level docs/getting-started.md walking through the binary-installer-only Install story. - packaging/common/hosts pre-populated with the eight public test-mesh nodes so shortnames resolve out of the box on every fresh install. ## Changes - 23 wire-format diagrams relocated to reference/diagrams/ alongside the wire-formats move. - 4 design diagrams corrected against source code (fips-protocol-stack, fips-identity-derivation, fips-coordinate-discovery, fips-routing-decision). - 10 pre-existing design docs reconciled with current source. Numeric corrections: stale link-MMP report bounds (now [1s, 5s] with 200 ms cold-start floor); UDP default MTU (now 1280, IPv6 minimum); node_addr formula (SHA-256(pubkey)[..16]); Noise patterns (IK at link, XK at session); peer-ACL semantics (strict allowlist requires ALL in peers.deny); daemon DNS upstream ([::1]:5354); on-the-wire bloom-filter size (1,071 bytes); obsolete Cargo-feature references (PR #79 dropped them) removed. - Transport framing tightened across the docs: TCP is for UDP-filtered networks (not NAT traversal); Tor is a deployment mode (not failover); WebSocket dropped (not a shipped FIPS transport); WiFi promoted to Implemented via Ethernet in infrastructure mode; classic-Bluetooth row removed (BLE is the only Bluetooth-mode transport). - docs/design/fips-gateway.md rewritten end-to-end to lead with the niche-feature framing and the two-halves structure. Title moved from "FIPS Outbound LAN Gateway" to "FIPS Gateway"; architecture section describes the common machinery (the fips-gateway service, the nftables table, the control socket) before splitting into separate "Outbound Half" and "Inbound Half" sections of equal weight; security considerations split per-half; no Future Work section (speculative directions live in the project tracker, not in protocol design docs). Inbound port forwarding is a first-class half rather than a buried "Implemented Extensions" subsection. - Gateway terminology unified across all gateway docs as a separate Linux service running alongside the fips daemon (its own systemd unit / OpenWrt init script). Container- pattern terms (sidecar) are reserved for the Docker/Kubernetes sidecar deployment examples — the testing/sidecar/ tree, examples/k8s-sidecar/, examples/sidecar-nostr-relay/, examples/wireguard-sidecar-macos/, and the related CHANGELOG / top-level README entries — where the term carries its standard container meaning. - Net-new design body content: rekey section in fips-mesh-layer (Noise IK msg1/msg2 over the established link, K-bit cutover, drain window, smaller-NodeAddr-wins tie-breaker on dual-init); Mesh Size Estimation and Antipoison FPR Cap sections in fips-bloom-filters; Mesh-Interface Query Filter subsection in fips-ipv6-adapter; failure-suppression knobs and clock- skew tolerance in fips-nostr-discovery; loop-rejection and mid-chain ancestor swap added to spanning-tree propagation / stability rules; Priority Chain in fips-mesh-operation renumbered to match the routing-decision diagram. - Top-level README: dropped the stale nostr-discovery cargo-feature parenthetical. docs/README.md and the four section READMEs (tutorials, how-to, reference, design) refreshed for the new structure; index rows reflect both halves of the gateway feature and the new fips-gateway CLI reference. - Cargo.toml [package.metadata.deb] assets path updated for the fips-security.md move; .gitignore /reference/ rule anchored to repo root so docs/reference/ is trackable. - packaging/openwrt-ipk/files/etc/fips/fips.yaml configuration-doc URL updated to the new docs/reference/configuration.md location. ## Deletions - docs/design/fips-intro.md (split into the three new intro design docs). - docs/design/document-relationships.svg (orphan, no longer referenced). - docs/proposals/ tree removed; the only proposal it contained (the Nostr UDP hole-punch protocol) was rewritten as the new generic design/port-advertisement-and-nat-traversal.md.
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
# FIPS Architecture
|
||||
|
||||
The protocol architecture, identity system, and two-layer encryption
|
||||
model. For the higher-level "what is FIPS and why" framing, see
|
||||
[fips-concepts.md](fips-concepts.md). For prior art and academic
|
||||
citations, see [fips-prior-work.md](fips-prior-work.md).
|
||||
|
||||
## Protocol Architecture
|
||||
|
||||
FIPS is organized in three protocol layers, each with distinct
|
||||
responsibilities and clean service boundaries. No layer depends on
|
||||
the specifics of the layers above or below it — transport plugins
|
||||
know nothing about sessions, the routing layer knows nothing about
|
||||
application addressing, and applications know nothing about which
|
||||
physical media carry their traffic. This separation means new
|
||||
transports, protocol features, and application interfaces can be
|
||||
added independently.
|
||||
|
||||

|
||||
|
||||
### Mapping to Traditional Networking
|
||||
|
||||
Readers familiar with the OSI model or TCP/IP networking may find it
|
||||
helpful to see how FIPS concepts relate to traditional layers:
|
||||
|
||||

|
||||
|
||||
Note that FMP spans what would traditionally be separate link and
|
||||
network layers. This is intentional — in a self-organizing mesh, the
|
||||
same layer that authenticates peers also makes routing decisions,
|
||||
because routing depends on authenticated peer state (spanning tree
|
||||
positions, bloom filters).
|
||||
|
||||
### Layer Responsibilities
|
||||
|
||||
**Transport layer**: Delivers datagrams between endpoints over a
|
||||
specific medium. Each transport type (UDP socket, Ethernet interface,
|
||||
radio modem) implements the same abstract interface: send and receive
|
||||
datagrams, report MTU. The transport layer knows nothing about FIPS
|
||||
identities, routing, or encryption. It provides raw datagram delivery
|
||||
to FMP above.
|
||||
|
||||
See [fips-transport-layer.md](fips-transport-layer.md) for the
|
||||
transport layer specification.
|
||||
|
||||
**FIPS Mesh Protocol (FMP)**: Manages peer connections, authenticates
|
||||
peers via Noise IK handshakes, and encrypts all traffic on each link.
|
||||
FMP is where the mesh organizes itself — nodes exchange spanning tree
|
||||
announcements and bloom filters with their direct peers, and FMP
|
||||
makes forwarding decisions for transit traffic. FMP provides
|
||||
authenticated, encrypted forwarding to FSP above.
|
||||
|
||||
See [fips-mesh-layer.md](fips-mesh-layer.md) for the FMP specification
|
||||
and [fips-mesh-operation.md](fips-mesh-operation.md) for how FMP's
|
||||
routing and self-organization work in practice.
|
||||
|
||||
**FIPS Session Protocol (FSP)**: Provides end-to-end authenticated
|
||||
encryption between any two nodes, regardless of how many intermediate
|
||||
hops separate them. FSP manages session lifecycle (setup, data
|
||||
transfer, teardown), caches destination coordinates for efficient
|
||||
routing, and handles the warmup strategy that keeps transit node
|
||||
caches populated. Session dispatch uses index-based routing inspired
|
||||
by [WireGuard](https://www.wireguard.com/), enabling O(1) packet
|
||||
demultiplexing. FSP provides a datagram service to applications above.
|
||||
|
||||
See [fips-session-layer.md](fips-session-layer.md) for the FSP
|
||||
specification.
|
||||
|
||||
**IPv6 adaptation layer**: Sits above FSP as a service on port 256,
|
||||
adapting the FIPS datagram service for unmodified IPv6 applications.
|
||||
Provides DNS resolution (npub → fd00::/8 address), identity cache
|
||||
management, IPv6 header compression, MTU enforcement, and a TUN
|
||||
interface. This is the primary way existing applications use the FIPS
|
||||
mesh.
|
||||
|
||||
See [fips-ipv6-adapter.md](fips-ipv6-adapter.md) for the IPv6 adapter.
|
||||
|
||||
### Node Architecture
|
||||
|
||||
Application services sit at the top of the stack, dispatched by FSP
|
||||
port number: the IPv6 TUN adapter (port 256) maps npubs to `fd00::/8`
|
||||
addresses with header compression so unmodified IP applications can
|
||||
use the network transparently, while the native datagram API
|
||||
addresses destinations directly by npub.
|
||||
|
||||

|
||||
|
||||
The mesh routes application traffic across heterogeneous transports
|
||||
transparently. A packet may traverse WiFi, Ethernet, UDP/IP, and Tor
|
||||
links on its way from source to destination — the application never
|
||||
needs to know which transports are involved. Each hop is independently
|
||||
encrypted at the link layer, while a single end-to-end session
|
||||
protects the payload across the entire path.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Identity System
|
||||
|
||||
FIPS uses [Nostr](https://github.com/nostr-protocol/nips) keypairs
|
||||
(secp256k1) as node identities. The public key identifies the node;
|
||||
the private key signs protocol messages and establishes encrypted
|
||||
sessions.
|
||||
|
||||
The public key (or its bech32-encoded npub form) is the primary means
|
||||
for application-layer software to identify communication endpoints.
|
||||
Internally, the protocol derives a `node_addr` (a 16-byte SHA-256 hash
|
||||
of the pubkey) used as the routing identifier in packet headers, and
|
||||
an IPv6 address derived from the node_addr for the TUN adapter.
|
||||
Applications use the pubkey or npub; the routing layer uses node_addr;
|
||||
unmodified IPv6 applications use the derived `fd00::/8` address. All
|
||||
three are deterministically derived from the same keypair.
|
||||
|
||||
### FIPS Identity Handling
|
||||
|
||||

|
||||
|
||||
The pubkey is the node's cryptographic identity, used in Noise
|
||||
handshakes for both link encryption (IK) and session encryption (XK).
|
||||
It is never exposed beyond the endpoints of an encrypted channel. The node_addr, a one-way
|
||||
SHA-256 hash truncated to 16 bytes, serves as the routing identifier
|
||||
in packet headers and bloom filters. Intermediate routers see only
|
||||
node_addrs — they can forward traffic without learning the Nostr
|
||||
identities of the endpoints. An observer can verify "does this
|
||||
node_addr belong to pubkey X?" if they already know the pubkey, but
|
||||
cannot enumerate communicating identities by inspecting traffic. The
|
||||
IPv6 address prepends `fd` to the first 15 bytes of the node_addr,
|
||||
providing a ULA overlay address for unmodified IP applications via the
|
||||
TUN interface.
|
||||
|
||||
Below the FIPS identity layer, each transport uses its own native
|
||||
addressing — IP:port or hostname:port addresses, MAC addresses,
|
||||
.onion identifiers. These **link addresses** are opaque to everything
|
||||
above FMP and discarded once link authentication completes.
|
||||
|
||||
### Identity Verification
|
||||
|
||||
The Noise Protocol Framework mutually authenticates both peer-to-peer
|
||||
link connections (at FMP) and end-to-end session traffic (at FSP),
|
||||
proving each party controls the private key for their claimed
|
||||
identity.
|
||||
|
||||
See [fips-mesh-layer.md](fips-mesh-layer.md) for peer authentication
|
||||
and [fips-session-layer.md](fips-session-layer.md) for end-to-end
|
||||
session establishment.
|
||||
|
||||
Key rotation changes the node's identity — a new keypair produces a
|
||||
new node_addr and IPv6 address, requiring all sessions to be
|
||||
re-established. Migration mechanisms that allow a node to announce a
|
||||
successor key are a future consideration.
|
||||
|
||||
## Two-Layer Encryption
|
||||
|
||||
FIPS uses independent encryption at two protocol layers:
|
||||
|
||||
| Layer | Scope | Pattern | Purpose |
|
||||
| ----- | ----- | ------- | ------- |
|
||||
| **FMP (Mesh)** | Hop-by-hop | Noise IK | Encrypt all traffic on each peer link |
|
||||
| **FSP (Session)** | End-to-end | Noise XK | Encrypt application payload between endpoints |
|
||||
|
||||
### Link Layer (Hop-by-Hop)
|
||||
|
||||
When two nodes establish a direct connection, they perform a [Noise
|
||||
IK](https://noiseprotocol.org/) handshake. This authenticates both
|
||||
parties and establishes symmetric keys for encrypting all traffic on
|
||||
that link. Every packet between direct peers is encrypted — gossip
|
||||
messages, routing queries, and forwarded session datagrams alike.
|
||||
|
||||
The IK pattern is used because outbound connections know the peer's
|
||||
npub from configuration, while inbound connections learn the
|
||||
initiator's identity from the first handshake message.
|
||||
|
||||
### Session Layer (End-to-End)
|
||||
|
||||
FIPS establishes end-to-end encrypted sessions between any two
|
||||
communicating nodes using Noise XK, regardless of how many hops
|
||||
separate them. The initiator knows the destination's npub (required
|
||||
for XK's pre-message); the responder learns the initiator's identity
|
||||
from the third handshake message. Unlike the link-layer IK pattern
|
||||
where the initiator's identity is revealed in msg1, XK delays
|
||||
identity disclosure until msg3, providing stronger initiator identity
|
||||
protection for traffic traversing untrusted intermediate nodes.
|
||||
|
||||
A packet from A to D through intermediate nodes B and C:
|
||||
|
||||
1. A encrypts payload with A↔D session key (FSP)
|
||||
2. A wraps in SessionDatagram, encrypts with A↔B link key (FMP),
|
||||
sends to B
|
||||
3. B decrypts link layer, reads destination node_addr, re-encrypts
|
||||
with B↔C link key, forwards to C
|
||||
4. C decrypts link layer, re-encrypts with C↔D link key, forwards
|
||||
to D
|
||||
5. D decrypts link layer, then decrypts session layer to get payload
|
||||
|
||||
Intermediate nodes route based on destination node_addr but cannot
|
||||
read session-layer payloads. Each hop strips one link encryption and
|
||||
applies the next — the session-layer ciphertext passes through
|
||||
untouched.
|
||||
|
||||
Both layers always apply, even between adjacent peers — a packet to a
|
||||
direct neighbor is still encrypted twice. This uniform model means no
|
||||
special cases for local vs remote destinations, and topology changes
|
||||
(a direct peer becomes reachable only through intermediaries) don't
|
||||
affect existing sessions.
|
||||
|
||||
See [fips-mesh-layer.md](fips-mesh-layer.md) for link encryption and
|
||||
[fips-session-layer.md](fips-session-layer.md) for session encryption.
|
||||
|
||||
## Routing and Mesh Operation
|
||||
|
||||
Forwarding decisions are local. Each node combines spanning-tree
|
||||
coordinates with peer bloom filters to choose a next hop, falling back
|
||||
to greedy tree routing when bloom filters have not converged. Discovery
|
||||
warms transit node caches with destination coordinates, and three
|
||||
explicit error signals (CoordsRequired, PathBroken, MtuExceeded) drive
|
||||
recovery when forwarding fails. The full routing decision process,
|
||||
discovery protocol, and error-recovery integration view live in
|
||||
[fips-mesh-operation.md](fips-mesh-operation.md).
|
||||
|
||||
## Transport Abstraction
|
||||
|
||||
FIPS treats the communication medium as a pluggable component. UDP,
|
||||
TCP, raw Ethernet, Tor, and BLE all implement the same small datagram
|
||||
interface (send, receive, report MTU) and feed peers into a single FMP
|
||||
routing layer; radio and serial transports are in the planned set.
|
||||
Multi-transport nodes bridge between networks transparently. The
|
||||
transport-layer specification — including per-transport categories,
|
||||
the trait surface, the connection model, and implementation status —
|
||||
is in [fips-transport-layer.md](fips-transport-layer.md).
|
||||
|
||||
## Security
|
||||
|
||||
FIPS defends against four adversary classes (transport observers,
|
||||
active transport attackers, intermediate routers, and adversarial
|
||||
mesh nodes) through layered controls: hop-by-hop FMP link encryption,
|
||||
end-to-end FSP session encryption with stronger initiator identity
|
||||
protection, signed and replay-protected gossip, and rate-limited
|
||||
handshake processing. The threat-model details and per-layer
|
||||
mitigations are in [fips-mesh-layer.md](fips-mesh-layer.md), and the
|
||||
operator-facing controls (default-deny baseline, peer ACLs,
|
||||
filesystem permissions, cryptographic primitives) are consolidated in
|
||||
[fips-security.md](fips-security.md) and
|
||||
[../reference/security.md](../reference/security.md).
|
||||
|
||||
## MTU as a Cross-Cutting Concern
|
||||
|
||||
MTU is not owned by any single layer. The transport layer reports
|
||||
per-link MTU, FMP carries `path_mtu` in SessionDatagram and
|
||||
LookupResponse to track the minimum along a path, FSP echoes the
|
||||
observed forward-path MTU back to the source, and the IPv6 adapter
|
||||
enforces the resulting effective MTU at the TUN with ICMP Packet Too
|
||||
Big and TCP MSS clamping. The unified design — encapsulation overhead
|
||||
budget, proactive PMTUD, reactive MtuExceeded, and per-destination
|
||||
storage — is in [fips-mtu.md](fips-mtu.md).
|
||||
|
||||
## Approaches Considered but Rejected
|
||||
|
||||
One design alternative evaluated and ruled out during the architecture
|
||||
pass was onion routing, rejected because it requires the sender to
|
||||
know the full path upfront (incompatible with self-organizing
|
||||
routing) and prevents per-hop error feedback (incompatible with
|
||||
CoordsRequired/PathBroken recovery). The canonical mention lives in
|
||||
[fips-mesh-operation.md](fips-mesh-operation.md#privacy-considerations).
|
||||
Reference in New Issue
Block a user