Lesson 13

Try It

Twelve lessons of diagrams and byte layouts are enough. The rest of the protocol makes a lot more sense once you watch a real node boot, run a handshake, and show up in a spanning tree you can poke at. This page has everything you need to get there.

The plan:

  1. Build or install the fips daemon.
  2. Point it at the public test node. The Debian and macOS packages ship this peer in the default config, so most of you can skip the config step.
  3. Start the service and confirm you joined the mesh.
  4. Send a packet across it. Ping a peer by .fips name or SSH into a mesh-reachable host.

The public test node

alias fips-test-node
npub npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98
udp 217.77.8.91:2121

It is a plain FIPS node with auto_connect open to inbound UDP. When your node starts, it runs a Noise IK handshake with the test node, builds a link, and joins whatever tree the test node is part of. No other configuration is required.

Prerequisites

  • Rust 1.85 or newer (edition 2024). The project pins the toolchain in its lockfile.
  • Admin privileges on the host. The daemon creates a TUN device (fips0 on Linux, utunN on macOS), which the kernel will not give you as an unprivileged user.
  • Outbound UDP on port 2121. If the test-node handshake never completes, a firewall or CGNAT is the first thing to check.

Install and connect

Pick a platform. Every code block has a copy button. The commands come straight from the project README, so when the upstream install changes, this page is the first thing we update.

1. Install

Build and install the .deb
git clone https://github.com/jmcorgan/fips.git
cd fips
cargo install cargo-deb
cargo deb
sudo dpkg -i target/debian/fips_*.deb

Requires Rust 1.85+. The package ships systemd units and the default peer config.

Let your user talk to the daemon
sudo usermod -aG fips $USER
# log out and back in for the group change to take effect

2. Point at the test mesh

The package already ships fips-test-node in /etc/fips/fips.yaml. Skip to step 3.

3. Start the node

Start the service
sudo systemctl start fips
sudo journalctl -u fips -f

4. Verify you are on the mesh

Within a few seconds of starting, fipsctl show peers should list fips-test-node with an active link, and the tree should have more than one node in it.

fipsctl show status
fipsctl show peers
fipsctl show tree
ping6 npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips

Your first packet

Once fipsctl show peers lists the test node with state Authenticated and the spanning tree has at least two nodes in it, the mesh is usable. Try any of these:

Reach the test node by name
ping6 npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98.fips

On macOS use ping6, not ping. macOS ships them as two separate binaries and the IPv4 one will not resolve AAAA records.

Watch the mesh in real time
fipstop

A TUI dashboard for status, peers, links, sessions, tree, transports, and routing. Press q to quit.

Run something over it
ssh -6 npub1...xxx.fips
curl -6 http://npub1...yyy.fips/

Anything that takes an IPv6 address works. The flag forces the tool to use IPv6 and pick up the AAAA record from the FIPS resolver.

When it does not work

Handshake never completes

Outbound UDP 2121 is blocked, you are behind a symmetric NAT, or IPv4 connectivity to 217.77.8.91:2121 is dropped. Try a different network or add a TCP fallback under transports.tcp.

.fips names do not resolve

On tarball installs you have to point your system resolver at 127.0.0.1:5354 for the fips domain. The Debian and macOS packages do this for you. Check with dig @127.0.0.1 -p 5354 npub1...xxx.fips AAAA.

Tree stays at one node (just yourself)

The link is up but no spanning-tree announcements have arrived yet. Give it a few seconds. If it persists, fipsctl show links will tell you whether the link is authenticated and which metrics MMP has collected so far.

Where to go from here

  • Add a persistent identity. Set node.identity.persistent: true in your config so your npub survives restarts and your peers can pin it.
  • Bring a service online. The strfry sidecar example runs a Nostr relay that is only reachable through the mesh. About twenty lines of docker-compose.
  • Expose a second device. Run fips-gateway on a home server and reach mesh peers from a laptop that does not have FIPS installed. Lesson 12 covers how the NAT plumbing works.
  • Read the specs that generated this site: docs/design. Everything in these lessons is grounded in those documents.

Break something useful, open an issue, or put up a second test node. The mesh gets more interesting with every peer that joins it.