Files
fips_setup/plans/FIPS_ADDRESSING.md
2026-04-11 20:40:01 -04:00

178 lines
6.0 KiB
Markdown

# FIPS Addressing: How to Share Your Node Address
## Overview
There are **three ways** someone can reach your FIPS node, from most user-friendly to most raw:
| Method | Example | Config needed on visitor? |
|---|---|---|
| Friendly hostname | `http://mysite.fips` | Yes — host map entry or peer alias |
| Direct npub | `http://npub1qmc3...98.fips` | No — works on any FIPS node |
| Raw IPv6 | `http://[fdab:1234:...]:80` | Requires prior DNS lookup to prime cache |
---
## 1. Friendly Hostname: `mysite.fips`
This is the best option for sharing a web page address. You create a human-readable alias by adding an entry to `/etc/fips/hosts` on the visitor's node:
```
mysite npub1abc...xyz
```
Or, if the visitor has you as a configured peer with an `alias` in their `fips.yaml`, it works automatically:
```yaml
peers:
- npub: "npub1abc...xyz"
alias: "mysite"
addresses:
- transport: udp
addr: "1.2.3.4:2121"
```
Then they just browse to:
```
http://mysite.fips
```
### How it works
The FIPS DNS resolver on port 5354 sees `mysite.fips`, looks up `mysite` in the host map → gets the npub → derives the `fd00::/8` IPv6 address → primes the identity cache → returns the AAAA record. The browser connects transparently.
### The catch
This is a *local* mapping. There's no global DNS — each node maintains its own host map. So you'd share both the hostname convention and the npub, and visitors add the entry themselves. Think of it like a `/etc/hosts` entry but for the FIPS mesh.
Resolution priority:
1. `/etc/fips/hosts` entries (take precedence)
2. Peer `alias` fields from `fips.yaml`
3. Fall through to direct npub resolution
Changes to `/etc/fips/hosts` are picked up automatically on the next DNS query — no restart needed.
### Hosts file format
```
# /etc/fips/hosts
# hostname npub
mysite npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98
vps-tx npub10yffd020a4ag8zcy75f9pruq3rnghvvhd5hphl9s62zgp35s560qrksp9u
```
Rules:
- Lines starting with `#` are comments
- Empty lines are ignored
- Hostnames: a-z, 0-9, hyphens only; max 63 characters
- One hostname and one npub per line, separated by whitespace
---
## 2. Direct npub Address: `npub1abc...xyz.fips`
This is the **zero-configuration** option — no host map needed. You give someone your npub and they use it directly as a domain name:
```
http://npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips
```
### How it works
The FIPS DNS resolver extracts the npub from the label before `.fips`, derives the IPv6 address purely computationally (npub → public key → SHA-256 → node_addr → `fd00::/8` IPv6), and returns it as an AAAA record. No lookup table needed — the npub *is* the address.
This works on any FIPS node without any prior configuration. The downside is obvious: npubs are 63 characters of bech32, so the URL is long and ugly.
### Examples
```bash
# Web browsing
http://npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips
# SSH
ssh -6 npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips
# Ping
ping6 npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips
# Curl
curl -6 http://npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips
```
---
## 3. Raw IPv6 Address: `fd00:...`
Under the hood, every npub deterministically maps to an IPv6 address in the `fd00::/8` ULA range:
```
Public Key (32 bytes)
→ SHA-256 → node_addr (16 bytes)
→ fd + node_addr[0..15] → IPv6 address (16 bytes)
```
So you could share the raw IPv6:
```
http://[fdab:1234:5678:9abc:def0:1234:5678:9abc]:80
```
### Why this is the worst option
The derivation is **one-way** — the receiver's FIPS node can't recover the npub from the IPv6 address alone. The identity cache must be primed first (via a DNS lookup or inbound traffic from that node). If someone types the raw IPv6 without a prior DNS resolution, they get ICMPv6 "No route to destination."
Use raw IPv6 only for debugging or when you've already resolved the address via DNS.
---
## The Address Derivation Chain
```
Keypair (secp256k1)
├── npub1... (bech32-encoded public key)
│ ↓
│ npub1xxx.fips ← DNS name, resolvable on any FIPS node
├── node_addr (16 bytes = SHA-256 of pubkey, truncated)
│ ↓
│ Used internally for routing — intermediate nodes see only this
└── fd00::/8 IPv6 (fd + node_addr[0..15])
Used by TUN interface for unmodified IPv6 apps
```
All three representations are **deterministically derived** from the same keypair. No registration, no central authority.
---
## What You'd Actually Tell People
In practice, you'd share something like:
> **My FIPS address:** `npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98`
>
> Browse to: `http://npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips`
>
> Or add to your `/etc/fips/hosts`:
> ```
> coolsite npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98
> ```
> Then just visit `http://coolsite.fips`
The **npub is the canonical address** — it's self-authenticating (derived from your keypair), works without any central registry, and any FIPS node can resolve it to an IPv6 address purely through computation. The friendly hostname is a local convenience layer on top.
---
## Key Properties
| Property | Detail |
|---|---|
| **Self-sovereign** | You generate your own address from a keypair — no one assigns it to you |
| **Self-authenticating** | The address IS the public key — connecting to an npub cryptographically proves you reached the right node |
| **Deterministic** | npub → IPv6 is pure computation, same result everywhere, no lookup needed |
| **No global registry** | No DNS authority, no CA, no registrar |
| **Friendly names are local** | `/etc/fips/hosts` is per-node; there's no global `.fips` name registry |
| **Privacy-preserving** | Intermediate routers see only the node_addr hash, not the npub identity |