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,231 @@
|
||||
# IPv6 Adapter Walkthrough
|
||||
|
||||
You have completed [join-the-test-mesh](join-the-test-mesh.md).
|
||||
Your daemon is peered with `test-us01` and you can ping mesh
|
||||
nodes by `.fips` name. This tutorial walks the plumbing that
|
||||
makes that possible: what happens between the moment your shell
|
||||
types `ssh user@<peer>.fips` and the moment a TCP SYN arrives at
|
||||
sshd on the far side. Each step is something you can observe
|
||||
with the running daemon from the previous tutorial.
|
||||
|
||||
By the end you will be comfortable reading `fipstop` output and
|
||||
you will know which design doc to consult when something looks
|
||||
off.
|
||||
|
||||
> **Prerequisites.** The daemon from
|
||||
> [join-the-test-mesh.md](join-the-test-mesh.md) is running and
|
||||
> peered with at least one test-mesh node, and your host's local
|
||||
> resolver is forwarding `.fips` queries to the daemon's DNS
|
||||
> responder (the system fips-dns.service drop-in does this
|
||||
> automatically on systemd hosts).
|
||||
|
||||
## The path we're tracing
|
||||
|
||||
```text
|
||||
shell ──ssh──> libc resolver ──.fips──> fips DNS ──AAAA──> fd97:...:test-us01
|
||||
│
|
||||
▼
|
||||
kernel IPv6 stack
|
||||
│
|
||||
▼
|
||||
fips0 (TUN)
|
||||
│
|
||||
▼
|
||||
your fips daemon
|
||||
(FSP session setup,
|
||||
FMP forwarding)
|
||||
│
|
||||
UDP / internet
|
||||
▼
|
||||
test-us01's fips daemon
|
||||
│
|
||||
▼
|
||||
fips0 (TUN)
|
||||
│
|
||||
▼
|
||||
kernel IPv6 stack
|
||||
│
|
||||
▼
|
||||
sshd
|
||||
```
|
||||
|
||||
In a multi-hop mesh the middle would have additional FMP
|
||||
forwarders between your daemon and the destination. For this
|
||||
walkthrough you have a single direct link to `test-us01`, which
|
||||
keeps the trace simple.
|
||||
|
||||
## Step 1: Watch the DNS resolution
|
||||
|
||||
Ask the system resolver to translate `test-us01`'s npub into its
|
||||
mesh address:
|
||||
|
||||
```sh
|
||||
dig npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips AAAA +short
|
||||
```
|
||||
|
||||
You should see one AAAA record returning a `fd97:...` address.
|
||||
The prefix is the FIPS ULA range (`fd00::/8`, with `fd97:...`
|
||||
covering the address space derived from npubs).
|
||||
|
||||
The query went through `systemd-resolved` (or your platform
|
||||
equivalent), which routed `.fips` queries to the daemon's local
|
||||
responder via the drop-in installed by `fips-dns.service`. To
|
||||
confirm, query the daemon directly:
|
||||
|
||||
```sh
|
||||
dig @::1 -p 5354 npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips AAAA +short
|
||||
```
|
||||
|
||||
Same answer, same fast turnaround — no external DNS traffic in
|
||||
either case.
|
||||
|
||||
The mapping `npub → fd00::/8 address` is deterministic. The
|
||||
responder hashes the public key into 16 bytes, prepends the
|
||||
prefix, and returns the result. There is no shared registry; the
|
||||
address space is self-allocating from the public-key namespace.
|
||||
|
||||
If you ask for any non-`.fips` suffix, the responder returns
|
||||
`REFUSED` — it is intentionally a stub for this single zone, not a
|
||||
recursive resolver. An unknown `.fips` name returns `NXDOMAIN`.
|
||||
|
||||
The full DNS integration is documented in
|
||||
[../design/fips-ipv6-adapter.md](../design/fips-ipv6-adapter.md).
|
||||
|
||||
## Step 2: Watch the session being created
|
||||
|
||||
Open `fipstop` against your daemon's control socket:
|
||||
|
||||
```sh
|
||||
sudo fipstop
|
||||
```
|
||||
|
||||
Press `Tab` until you reach the **Sessions** tab. Before any
|
||||
TCP traffic to `test-us01`, the table is empty (or has rows from
|
||||
earlier exchanges).
|
||||
|
||||
In another terminal, kick off a TCP connection from your host
|
||||
toward `test-us01`:
|
||||
|
||||
```sh
|
||||
ssh -o ConnectTimeout=5 user@test-us01.fips
|
||||
```
|
||||
|
||||
(`test-us01.fips` resolves to the same address as the npub
|
||||
form via the installer's `/etc/fips/hosts` entry.)
|
||||
|
||||
(It is fine if the SSH attempt fails authentication or if no
|
||||
sshd is exposed on the far side — what we want to observe is the
|
||||
session machinery firing, not a successful login.)
|
||||
|
||||
In `fipstop`'s Sessions tab you should see a new row appear with:
|
||||
|
||||
- `state` cycling from `initiating` to `awaiting_msg3` to
|
||||
`established` (the three FSP handshake states).
|
||||
- `display_name` showing `test-us01` (the `alias` you set in your
|
||||
`peers:` block in the previous tutorial).
|
||||
- A non-zero `last_activity_ms`.
|
||||
|
||||
Once `established`, the session row stays put until idle-timeout
|
||||
expires. The traffic counters and MMP metrics tick as data flows.
|
||||
|
||||
> **Watch for.** Some intermediate states may be too fast to
|
||||
> see at the default `fipstop` refresh rate of 2 s. Run
|
||||
> `sudo fipstop -r 1` for a faster refresh during the exercise.
|
||||
|
||||
## Step 3: Watch the per-session metrics
|
||||
|
||||
Switch to the **Performance** tab. Each established session has
|
||||
a session-layer MMP entry showing:
|
||||
|
||||
- `srtt_ms` — smoothed end-to-end round-trip time. Over a
|
||||
public-internet path this typically lands in the tens of
|
||||
milliseconds; for a US-coast destination from a US client you
|
||||
might see 30–80 ms steady-state.
|
||||
- `loss_rate` — fraction of in-flight payloads inferred lost from
|
||||
counter gaps. Stays at 0 on a healthy link; small bursts during
|
||||
congestion or path changes.
|
||||
- `path_mtu` — the end-to-end MTU the session-layer MMP currently
|
||||
believes is in force. Starts at the IPv6 floor and climbs as
|
||||
PathMtuNotification echoes arrive.
|
||||
- `etx` and `goodput_bps` — derived metrics, useful as
|
||||
steady-state indicators.
|
||||
|
||||
The same metrics are available without the TUI:
|
||||
|
||||
```sh
|
||||
sudo fipsctl show sessions | jq '.sessions[] | {display_name, state, mmp}'
|
||||
```
|
||||
|
||||
What these numbers mean is documented in
|
||||
[../design/fips-mmp.md](../design/fips-mmp.md). Briefly: SRTT is
|
||||
RFC 6298-style with α = 1/8; loss is bidirectional, inferred from
|
||||
counter gaps in MMP reports; path MTU is end-to-end-echoed with
|
||||
hysteresis on increase.
|
||||
|
||||
## Step 4: Watch the link below the session
|
||||
|
||||
Switch to the **Peers** tab. Each authenticated peer has its own
|
||||
link-layer MMP block, distinct from the session-layer one above.
|
||||
The link-layer metrics measure a single hop (here, your daemon
|
||||
↔ `test-us01` over UDP), independent of any session that
|
||||
traverses it.
|
||||
|
||||
Compare the link-layer SRTT for `test-us01` to the session-layer
|
||||
SRTT of the session you just created. Because your reach to
|
||||
`test-us01` is one direct hop, the two should be very close —
|
||||
the session has no transit forwarders to add latency.
|
||||
|
||||
If you reach a node that `test-us01` forwards to (try the
|
||||
`test-us02` ping from the previous tutorial), the session-layer
|
||||
SRTT for that destination will be measurably larger than the
|
||||
link-layer SRTT to `test-us01`. The difference is the time
|
||||
`test-us01` spent forwarding plus the hop from `test-us01` to
|
||||
`test-us02`.
|
||||
|
||||
In a deeper mesh this divergence grows: link-layer SRTT measures
|
||||
the direct neighbour, session-layer SRTT measures the full
|
||||
end-to-end path.
|
||||
|
||||
## Step 5: Read the relevant design docs
|
||||
|
||||
You have now seen the moving parts. To go from "I can read these
|
||||
metrics" to "I understand why each one moves the way it does":
|
||||
|
||||
- [../design/fips-ipv6-adapter.md](../design/fips-ipv6-adapter.md)
|
||||
— DNS responder, identity cache, TUN reader/writer, IPv6 header
|
||||
compression, MTU enforcement at the TUN boundary.
|
||||
- [../design/fips-session-layer.md](../design/fips-session-layer.md)
|
||||
— FSP session lifecycle: msg1 / msg2 / msg3, the rekey state
|
||||
machine, the drain window for old sessions during cutover.
|
||||
- [../design/fips-mmp.md](../design/fips-mmp.md) — both link-layer
|
||||
and session-layer MMP: report format, SRTT estimation,
|
||||
loss/jitter/ETX computation, the trend indicators.
|
||||
- [../design/fips-mtu.md](../design/fips-mtu.md) — what `path_mtu`
|
||||
in `show sessions` means: the proactive forward-path field, the
|
||||
reactive `MtuExceeded` mechanism, the hysteresis on increase.
|
||||
- [../design/fips-architecture.md](../design/fips-architecture.md)
|
||||
— the two-layer encryption model: link-layer Noise IK over
|
||||
each hop, end-to-end Noise XK over the session.
|
||||
|
||||
## What you've learned
|
||||
|
||||
- A `.fips` name resolves through a daemon-local stub responder.
|
||||
The mapping from npub to `fd00::/8` address is deterministic
|
||||
and needs no registry.
|
||||
- The kernel IPv6 stack treats the TUN adapter as an ordinary
|
||||
interface; packets to `fd00::/8` go out via that route. The
|
||||
daemon reads them off the TUN, looks up an FSP session for the
|
||||
destination (creating one if needed), and forwards them onward
|
||||
through its peers.
|
||||
- The session layer (FSP) and the link layer (FMP) each maintain
|
||||
their own MMP metrics. Session-layer metrics measure the path
|
||||
end-to-end; link-layer metrics measure a single hop. The two
|
||||
align when the destination is your direct peer; they diverge
|
||||
when traffic traverses additional hops.
|
||||
- `fipstop` exposes both views in real time. `fipsctl show sessions`,
|
||||
`fipsctl show peers`, and `fipsctl show transports` cover the
|
||||
same ground programmatically.
|
||||
|
||||
When something looks off in production, the `fipsctl show *`
|
||||
queries are usually the first stop; the relevant design doc tells
|
||||
you what the numbers mean and what they should do.
|
||||
Reference in New Issue
Block a user