#!/bin/bash # LAN fast-path pairing for our 4 dev fleet nodes. # # ── Is this needed for every archipelago install? No. ──────────────── # For nodes deployed anywhere in the world, FIPS-to-FIPS routing by # npub works via the anchor peer network (fips.v0l.io ships by default # in /etc/fips/fips.yaml on every install — that anchor bootstraps DHT # routing for any npub the node has ever heard about). The peer's # fips_npub is advertised in our federation invite codes (since v1.4), # so accepting an invite is enough for `dial::peer_base_url(npub)` to # reach the peer through the anchor mesh. # # ── Why this script exists ─────────────────────────────────────────── # Our 4 fleet nodes are all on 192.168.1.0/24. Hopping through the # fips.v0l.io anchor for intra-LAN traffic is wasteful when the peers # are on the same wire. This script writes per-node fips.yaml with: # 1. The public anchor (fips.v0l.io) so internet peers still route. # 2. The other 3 fleet nodes as static LAN peers (UDP 2121 / TCP # 8443) so LAN traffic stays on LAN. # 3. `persistent: true` so the npub is stable across restarts — # without this the daemon rolls a new keypair on every restart # and any federation invite we advertised goes stale. # # Idempotent: re-running picks up any newly-added or removed nodes. # # For a production install on an unknown LAN, this script isn't the # mechanism — the ISO install writes the anchor-only fips.yaml and # identity comes from the archipelago seed; peer discovery is purely # through the DHT + federation invites. # # Usage: # scripts/fleet-fips-pair.sh # apply to all nodes # scripts/fleet-fips-pair.sh --verify # just print the peer state set -eo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" . "$SCRIPT_DIR/lib/common.sh" # Fleet roster: " " NODES=( "116 enp0s25 npub1mxavs6scfgl056k6lm4mk73ddnrhjewg78zlyzfn2lmr0rfyrs5qhcr03g" "198 enp2s0 npub13cy4lml94cj4rdu8runrr945z2muszuvr5tql8mr9m063d7xzpqqu3k8se" "228 enp2s0 npub1a0xxcqce2tsv8ulwastep23jtf3h4wvvry8r8nklnl36jtrdnefqh5qn6h" "253 enx9cbf0d0129f9 npub1dl0m0yfzfw6467c3z6q63s7ggzd77yg97j90ptfrheprxeypt3msj0mq4g" ) LAN_PREFIX="192.168.1" UDP_PORT=2121 TCP_PORT=8443 if [ "${1:-}" = "--verify" ]; then for row in "${NODES[@]}"; do read -r node _nic _npub <<< "$row" echo "=== .$node ===" ssh_cmd "$LAN_PREFIX.$node" "sudo fipsctl show peers 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(f\"{len(d[\"peers\"])} authenticated peers\"); [print(\" npub=\", p.get(\"npub\",\"?\"), \"alias=\", p.get(\"alias\",\"?\")) for p in d[\"peers\"]]' || echo ' fipsctl show peers failed'" done exit 0 fi TMP_ROOT=$(mktemp -d) trap 'rm -rf "$TMP_ROOT"' EXIT generate_yaml() { # $1 = self node octet, $2 = self nic local self_node="$1" local self_nic="$2" local out="$TMP_ROOT/fips.yaml.$self_node" cat > "$out" <> "$out" </dev/null 2>&1; then break; fi sleep 0.5 done sudo systemctl is-active fips.service ' } for row in "${NODES[@]}"; do read -r node nic _npub <<< "$row" deploy_to "$node" "$nic" done echo log_info "Waiting 10s for peer handshakes to settle…" sleep 10 echo log_info "Post-pair peer state:" for row in "${NODES[@]}"; do read -r node _nic _npub <<< "$row" count=$(ssh_cmd "$LAN_PREFIX.$node" "sudo fipsctl show peers 2>/dev/null | grep -c '\"npub\"' || echo 0") log_info " .$node: $count authenticated peers" done