mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Fix documentation drift from recent feature additions
Update 9 documentation files to match current implementation: - Add missing rekey config section (node.rekey.*) and host mapping section to fips-configuration.md - Update Ethernet frame format from [type:1][payload] to [type:1][length:2 LE][payload] in wire-formats and transport docs - Fix Ethernet effective MTU from interface-1 to interface-3 - Mark rekey as Implemented in mesh-layer and session-layer status tables - Change TCP default port examples from 443 to 8443 - Add rekey, persistent identity, host mapping, mesh size estimation to README features and status sections - Update chaos scenario count from 16 to 20, add rekey topology to static test docs
This commit is contained in:
@@ -14,15 +14,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Docker sidecar deployment for containerized services
|
||||
- Comprehensive node and transport statistics via control socket
|
||||
- fipstop TUI monitoring tool with smoothed metrics and quality indices
|
||||
- fipstop peers display: transport type, direction, and tree roles
|
||||
- Estimated mesh size from bloom filter cardinality
|
||||
- ECN congestion signaling and transport congestion detection
|
||||
- Persistent identity with key file management (`fipsctl keygen`)
|
||||
- Periodic Noise rekey with fresh DH for forward secrecy (FMP + FSP)
|
||||
- Host-to-npub static mapping: resolve `hostname.fips` via host map
|
||||
populated from peer config aliases and `/etc/fips/hosts` file
|
||||
- DNS responder auto-reloads hosts file on modification (no restart needed)
|
||||
- Debian/Ubuntu `.deb` packaging via cargo-deb
|
||||
- Systemd service packaging with tarball installer
|
||||
- Build version metadata: git commit hash, dirty flag, and target triple
|
||||
embedded in all binaries via `--version`
|
||||
- Local CI runner script (`testing/ci-local.sh`)
|
||||
- TCP transport node-level integration tests
|
||||
- CI: expanded integration matrix, nextest JUnit reporting, workflow_dispatch
|
||||
- CHANGELOG.md following Keep a Changelog format
|
||||
|
||||
### Fixed
|
||||
@@ -32,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Ethernet AEAD decryption failures caused by minimum-frame padding
|
||||
- Link-dead detection skipping peers that never send data
|
||||
- FMP version check added to TCP stream reader
|
||||
- Control socket path mismatch between daemon and clients
|
||||
- fips-dns.service pulling in systemd-resolved and hanging on missing fips0
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ endpoints.
|
||||
- **Multi-transport** — UDP, TCP, and Ethernet today; designed for
|
||||
Bluetooth, serial, radio, and Tor
|
||||
- **Noise encryption** — hop-by-hop link encryption plus independent
|
||||
end-to-end session encryption
|
||||
end-to-end session encryption, with periodic rekey for forward secrecy
|
||||
- **Nostr-native identity** — secp256k1 keypairs as node addresses, no
|
||||
registration or central authority
|
||||
- **IPv6 adaptation** — TUN interface maps npubs to fd00::/8 addresses for
|
||||
unmodified IP applications
|
||||
unmodified IP applications; static hostname mapping (`/etc/fips/hosts`)
|
||||
- **Metrics Measurement Protocol** — per-link RTT, loss, jitter, and goodput
|
||||
measurement
|
||||
- **ECN congestion signaling** — hop-by-hop CE flag relay with RFC 3168 IPv6
|
||||
@@ -248,8 +248,11 @@ UDP, TCP, and Ethernet but has not been tested beyond small meshes.
|
||||
- Spanning tree construction with greedy coordinate routing
|
||||
- Bloom filter discovery for finding nodes without global state
|
||||
- Noise IK (link layer) and Noise XK (session layer) encryption
|
||||
- Periodic Noise rekey with forward secrecy (FMP + FSP)
|
||||
- Persistent node identity with key file management
|
||||
- IPv6 TUN adapter with DNS resolution of `.fips` names
|
||||
- Per-link metrics (RTT, loss, jitter, goodput)
|
||||
- Static hostname mapping (`/etc/fips/hosts`) with auto-reload
|
||||
- Per-link metrics (RTT, loss, jitter, goodput) and mesh size estimation
|
||||
- ECN congestion signaling (hop-by-hop CE relay, IPv6 CE marking, kernel drop detection)
|
||||
- UDP, TCP, and Ethernet transports
|
||||
- Runtime inspection via `fipsctl` and `fipstop`
|
||||
|
||||
@@ -194,6 +194,20 @@ outgoing link ETX ≥ `etx_threshold`, or kernel receive buffer drops detected o
|
||||
any local transport. CE is relayed hop-by-hop: once set on any hop, the flag
|
||||
stays set for all subsequent hops to the destination.
|
||||
|
||||
### Rekey (`node.rekey.*`)
|
||||
|
||||
Controls periodic Noise rekey for forward secrecy. When enabled, both FMP
|
||||
(link-layer IK) and FSP (session-layer XK) sessions perform fresh Diffie-Hellman
|
||||
key exchanges after a time or message count threshold, whichever comes first.
|
||||
A 10-second drain window keeps the old session active for decryption during
|
||||
cutover.
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `node.rekey.enabled` | bool | `true` | Enable periodic Noise rekey on all links and sessions |
|
||||
| `node.rekey.after_secs` | u64 | `120` | Initiate rekey after this many seconds on a session |
|
||||
| `node.rekey.after_messages` | u64 | `65536` | Initiate rekey after this many messages sent on a session |
|
||||
|
||||
### Session / Data Plane (`node.session.*`)
|
||||
|
||||
Controls end-to-end session behavior and packet queuing.
|
||||
@@ -268,6 +282,19 @@ with the node for routing.
|
||||
The `dns.ttl` value should not exceed `node.cache.coord_ttl_secs` to avoid
|
||||
stale address mappings.
|
||||
|
||||
### Host Mapping
|
||||
|
||||
The DNS resolver checks a host map before falling back to direct npub
|
||||
resolution, enabling names like `gateway.fips` instead of `npub1...fips`.
|
||||
The host map is populated from two sources:
|
||||
|
||||
1. **Peer aliases** — the `alias` field on configured peers in `peers:`.
|
||||
2. **Hosts file** — `/etc/fips/hosts`, one `hostname npub1...` per line.
|
||||
Blank lines and `#` comments are allowed.
|
||||
|
||||
The hosts file is auto-reloaded on modification (mtime change) without
|
||||
restarting the daemon. Hostnames are case-insensitive.
|
||||
|
||||
## Transports (`transports.*`)
|
||||
|
||||
### UDP (`transports.udp.*`)
|
||||
@@ -288,7 +315,7 @@ Requires `CAP_NET_RAW` or running as root. Linux only.
|
||||
|-----------|------|---------|-------------|
|
||||
| `interface` | string | *(required)* | Network interface name (e.g., `"eth0"`, `"enp3s0"`) |
|
||||
| `ethertype` | u16 | `0x2121` | EtherType |
|
||||
| `mtu` | u16 | *(auto)* | Override MTU. Default: interface MTU minus 1 (for frame type prefix) |
|
||||
| `mtu` | u16 | *(auto)* | Override MTU. Default: interface MTU minus 3 (for frame type + length prefix) |
|
||||
| `recv_buf_size` | usize | `2097152` | Socket receive buffer size in bytes (2 MB) |
|
||||
| `send_buf_size` | usize | `2097152` | Socket send buffer size in bytes (2 MB) |
|
||||
| `discovery` | bool | `true` | Listen for discovery beacons from other nodes |
|
||||
@@ -324,7 +351,7 @@ overhead.
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `transports.tcp.bind_addr` | string | *(none)* | Listen address (e.g., `"0.0.0.0:443"`). If omitted, outbound-only mode. |
|
||||
| `transports.tcp.bind_addr` | string | *(none)* | Listen address (e.g., `"0.0.0.0:8443"`). If omitted, outbound-only mode. |
|
||||
| `transports.tcp.mtu` | u16 | `1400` | Default MTU. Per-connection MTU derived from `TCP_MAXSEG` when available. |
|
||||
| `transports.tcp.connect_timeout_ms` | u64 | `5000` | Outbound connect timeout in milliseconds |
|
||||
| `transports.tcp.nodelay` | bool | `true` | `TCP_NODELAY` (disable Nagle for low latency) |
|
||||
@@ -514,6 +541,10 @@ node:
|
||||
enabled: true # ECN congestion signaling (CE flag relay)
|
||||
loss_threshold: 0.05 # MMP loss rate threshold for CE marking (5%)
|
||||
etx_threshold: 3.0 # MMP ETX threshold for CE marking
|
||||
rekey:
|
||||
enabled: true # periodic Noise rekey for forward secrecy
|
||||
after_secs: 120 # rekey interval (seconds)
|
||||
after_messages: 65536 # rekey after N messages sent
|
||||
control:
|
||||
enabled: true
|
||||
socket_path: null # null = auto ($XDG_RUNTIME_DIR → /run/fips → /tmp fallback)
|
||||
@@ -542,7 +573,7 @@ transports:
|
||||
# ethernet: # uncomment to enable (requires CAP_NET_RAW)
|
||||
# interface: "eth0" # required: network interface name
|
||||
# ethertype: 0x2121 # default EtherType
|
||||
# mtu: null # null = interface MTU - 1 (typically 1499)
|
||||
# mtu: null # null = interface MTU - 3 (typically 1497)
|
||||
# recv_buf_size: 2097152 # 2 MB
|
||||
# send_buf_size: 2097152 # 2 MB
|
||||
# discovery: true # listen for beacons
|
||||
@@ -551,7 +582,7 @@ transports:
|
||||
# accept_connections: false # accept inbound handshakes
|
||||
# beacon_interval_secs: 30 # beacon interval (min 10)
|
||||
# tcp: # uncomment to enable TCP transport
|
||||
# bind_addr: "0.0.0.0:443" # listen address (omit for outbound-only)
|
||||
# bind_addr: "0.0.0.0:8443" # listen address (omit for outbound-only)
|
||||
# mtu: 1400 # default MTU
|
||||
# connect_timeout_ms: 5000 # outbound connect timeout
|
||||
# nodelay: true # TCP_NODELAY
|
||||
|
||||
@@ -573,7 +573,7 @@ an attacker sends invalid packets to elicit responses.
|
||||
| Path MTU tracking (SessionDatagram) | **Implemented** |
|
||||
| Metrics Measurement Protocol (MMP) | **Implemented** |
|
||||
| ECN congestion signaling (CE relay, IPv6 marking) | **Implemented** |
|
||||
| Rekey with index rotation | Planned |
|
||||
| Rekey with index rotation | **Implemented** |
|
||||
| Allowlist/blocklist | Planned |
|
||||
|
||||
## References
|
||||
|
||||
@@ -538,7 +538,7 @@ MMP session metrics session=npub1tdwa...84le rtt=4.3ms loss=0.6% jitter=0.2ms go
|
||||
| PathBroken handling | **Implemented** |
|
||||
| Simultaneous initiation tie-breaker | **Implemented** |
|
||||
| Flush coord cache on parent change | **Implemented** |
|
||||
| Rekey | Planned |
|
||||
| Rekey | **Implemented** |
|
||||
| Path MTU tracking (FMP SessionDatagram field) | **Implemented** |
|
||||
| Path MTU notification (end-to-end echo) | **Implemented** |
|
||||
|
||||
|
||||
@@ -272,16 +272,20 @@ EtherType 0x2121. SOCK_DGRAM mode
|
||||
lets the kernel handle Ethernet header construction and parsing — the
|
||||
transport deals only with payloads and MAC addresses.
|
||||
|
||||
A 1-byte frame type prefix disambiguates data frames (0x00) from discovery
|
||||
beacons (0x01) on the receive path. This costs one byte of MTU but allows
|
||||
beacons and data to share the same EtherType and socket.
|
||||
Data frames use a 3-byte header: a 1-byte frame type (`0x00`) followed by
|
||||
a 2-byte little-endian payload length. The length field allows the receiver
|
||||
to trim Ethernet minimum-frame padding that would otherwise corrupt AEAD
|
||||
verification. Beacon frames (`0x01`) use only the 1-byte type prefix
|
||||
(fixed 34-byte payload). Beacons and data share the same EtherType and
|
||||
socket.
|
||||
|
||||
| Property | Value |
|
||||
| -------- | ----- |
|
||||
| EtherType | 0x2121 |
|
||||
| Socket type | AF_PACKET SOCK_DGRAM |
|
||||
| Frame type prefix | 0x00 = data, 0x01 = beacon |
|
||||
| Effective MTU | Interface MTU - 1 (typically 1499) |
|
||||
| Data frame header | `[type:1][length:2 LE][payload]` |
|
||||
| Beacon frame header | `[type:1][payload]` (fixed 34 bytes) |
|
||||
| Effective MTU | Interface MTU - 3 (typically 1497) |
|
||||
| Addressing | 6-byte MAC address |
|
||||
| Platform | Linux only (`CAP_NET_RAW` required) |
|
||||
|
||||
@@ -396,7 +400,7 @@ removes it from the pool and aborts its receive task.
|
||||
```yaml
|
||||
transports:
|
||||
tcp:
|
||||
bind_addr: "0.0.0.0:443" # Listen address (omit for outbound-only)
|
||||
bind_addr: "0.0.0.0:8443" # Listen address (omit for outbound-only)
|
||||
mtu: 1400 # Default MTU
|
||||
connect_timeout_ms: 5000 # Outbound connect timeout
|
||||
nodelay: true # TCP_NODELAY (disable Nagle)
|
||||
|
||||
@@ -23,11 +23,14 @@ transports (TCP, WebSocket, Tor) must delineate FIPS packets within the
|
||||
byte stream; the common prefix `payload_len` field provides this
|
||||
framing directly.
|
||||
|
||||
**Ethernet frame type prefix.** The Ethernet transport prepends a 1-byte
|
||||
frame type before the FMP payload: `0x00` for data frames and `0x01` for
|
||||
beacon (discovery) frames. This byte is consumed by the transport layer
|
||||
and is not visible to FMP. The effective MTU for FMP is the interface
|
||||
MTU minus one byte (typically 1499).
|
||||
**Ethernet data frame header.** The Ethernet transport prepends a 3-byte
|
||||
header before the FMP payload on data frames: a 1-byte frame type
|
||||
(`0x00`) followed by a 2-byte little-endian payload length. The length
|
||||
field allows the receiver to trim Ethernet minimum-frame padding that
|
||||
would otherwise corrupt AEAD verification. Beacon frames (`0x01`) have
|
||||
no length field (fixed 34-byte payload). These bytes are consumed by the
|
||||
transport layer and are not visible to FMP. The effective MTU for FMP is
|
||||
the interface MTU minus three bytes (typically 1497).
|
||||
|
||||
## Link-Layer Formats
|
||||
|
||||
|
||||
+6
-4
@@ -17,16 +17,18 @@ configurations.
|
||||
| mesh | 5 | UDP | Sparse mesh, 6 links, multi-hop |
|
||||
| chain | 5 | UDP | Linear chain, max 4-hop paths |
|
||||
| mesh-public | 5+1 | UDP | Mesh with external public node |
|
||||
| tcp-chain | 3 | TCP | Linear chain over TCP (port 443) |
|
||||
| tcp-chain | 3 | TCP | Linear chain over TCP (port 8443) |
|
||||
| rekey | 5 | UDP | Rekey integration test topology |
|
||||
|
||||
### [chaos/](chaos/) -- Stochastic Simulation
|
||||
|
||||
Automated network testing with configurable node counts, topology
|
||||
algorithms (random geometric, Erdos-Renyi, chain, explicit), and fault
|
||||
injection (netem mutation, link flaps, traffic generation, node
|
||||
churn). 16 scenarios covering general stress testing, cost-based parent
|
||||
selection, mixed link technologies (fiber/Bluetooth/WiFi), and
|
||||
transport-specific validation (UDP, TCP, Ethernet). Scenarios are
|
||||
churn). 20 scenarios covering general stress testing, cost-based parent
|
||||
selection, mixed link technologies (fiber/Bluetooth/WiFi),
|
||||
transport-specific validation (UDP, TCP, Ethernet), and ECN/congestion
|
||||
testing. Scenarios are
|
||||
defined in YAML and executed via a Python harness that manages the full
|
||||
lifecycle: topology generation, Docker orchestration, fault scheduling,
|
||||
log collection, and analysis.
|
||||
|
||||
@@ -96,7 +96,7 @@ Explicit topologies exercising non-UDP transports.
|
||||
via beacons, not static config. Minimal netem (1-5ms delay).
|
||||
- **ethernet-mesh**: Mirrors `tcp-mesh` topology but with Ethernet instead of
|
||||
TCP. UDP edges use static config; Ethernet edges use beacon discovery.
|
||||
- **tcp-only**: 4-node ring using TCP on port 443. Tests connect-on-send,
|
||||
- **tcp-only**: 4-node ring using TCP on port 8443. Tests connect-on-send,
|
||||
FMP framing over TCP, and reconnection. Netem enabled (1-10ms delay, 0-1%
|
||||
loss).
|
||||
- **tcp-chain**: 4-node linear chain, all TCP. Tests multi-hop routing over
|
||||
|
||||
@@ -90,14 +90,20 @@ appear in the topology file so that Docker nodes can peer with them.
|
||||
|
||||
### TCP Chain
|
||||
|
||||
Three nodes in a linear chain using TCP transport (port 443) instead of
|
||||
Three nodes in a linear chain using TCP transport (port 8443) instead of
|
||||
UDP: A -- B -- C. Each node peers only with its immediate neighbors.
|
||||
Tests basic TCP transport connectivity and multi-hop routing over TCP.
|
||||
|
||||
The topology file sets `default_transport: tcp`, which causes config
|
||||
generation to use TCP peer addresses (port 443), inject the TCP transport
|
||||
generation to use TCP peer addresses (port 8443), inject the TCP transport
|
||||
section, and remove the UDP transport section.
|
||||
|
||||
### Rekey
|
||||
|
||||
Same sparse mesh as the mesh topology (5 nodes, 6 links). Configs are
|
||||
post-processed to use aggressive rekey timers (35s) for CI testing. The
|
||||
`rekey-test.sh` script handles config injection and multi-phase verification.
|
||||
|
||||
## Configuration Management
|
||||
|
||||
### File Structure
|
||||
@@ -114,7 +120,8 @@ testing/static/
|
||||
│ ├── mesh.yaml # Mesh topology definition
|
||||
│ ├── chain.yaml # Chain topology definition
|
||||
│ ├── mesh-public.yaml # Mesh + external public node
|
||||
│ └── tcp-chain.yaml # TCP chain (3 nodes, port 443)
|
||||
│ ├── tcp-chain.yaml # TCP chain (3 nodes, port 8443)
|
||||
│ └── rekey.yaml # Rekey integration test (5 nodes)
|
||||
├── generated-configs/ # Auto-generated (gitignored)
|
||||
│ ├── npubs.env # NPUB_A=..., NPUB_B=..., etc.
|
||||
│ ├── mesh/
|
||||
@@ -319,7 +326,7 @@ removing rules first.
|
||||
- **Capabilities**: `CAP_NET_ADMIN` (for TUN device creation)
|
||||
- **Devices**: `/dev/net/tun` mapped into each container
|
||||
- **DNS**: FIPS built-in resolver on `127.0.0.1:53`
|
||||
- **Transport**: UDP on port 2121 (MTU 1472) or TCP on port 443
|
||||
- **Transport**: UDP on port 2121 (MTU 1472) or TCP on port 8443
|
||||
- **TUN**: `fips0` interface, MTU 1280
|
||||
|
||||
Each node resolves `<npub>.fips` DNS names to FIPS IPv6 addresses via its
|
||||
|
||||
Reference in New Issue
Block a user