177 lines
5.8 KiB
Bash
177 lines
5.8 KiB
Bash
|
|
#!/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: "<ip-last-octet> <nic-name> <fips-npub>"
|
||
|
|
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" <<YAML
|
||
|
|
# FIPS Node Configuration — managed by scripts/fleet-fips-pair.sh
|
||
|
|
# DO NOT hand-edit: re-run the script to regenerate.
|
||
|
|
|
||
|
|
node:
|
||
|
|
identity:
|
||
|
|
# Persistent identity so the npub stays stable across restarts.
|
||
|
|
# Without this, every restart rolls a new keypair and federation
|
||
|
|
# peer lists go stale.
|
||
|
|
persistent: true
|
||
|
|
|
||
|
|
tun:
|
||
|
|
enabled: true
|
||
|
|
name: fips0
|
||
|
|
mtu: 1280
|
||
|
|
|
||
|
|
dns:
|
||
|
|
enabled: true
|
||
|
|
bind_addr: "127.0.0.1"
|
||
|
|
port: 5354
|
||
|
|
|
||
|
|
transports:
|
||
|
|
udp:
|
||
|
|
bind_addr: "0.0.0.0:$UDP_PORT"
|
||
|
|
tcp:
|
||
|
|
bind_addr: "0.0.0.0:$TCP_PORT"
|
||
|
|
|
||
|
|
ethernet:
|
||
|
|
interface: "$self_nic"
|
||
|
|
discovery: true
|
||
|
|
announce: true
|
||
|
|
auto_connect: true
|
||
|
|
accept_connections: true
|
||
|
|
|
||
|
|
peers:
|
||
|
|
# Public anchor — bootstraps DHT routing for any npub heard via
|
||
|
|
# federation invites. Every archipelago install ships this peer.
|
||
|
|
- npub: "npub1zv58cn7v83mxvttl70w5fwjwuclfmntv9cnmv5wmz2nzz88u5urqvdx96n"
|
||
|
|
alias: "fips.v0l.io"
|
||
|
|
addresses:
|
||
|
|
- transport: tcp
|
||
|
|
addr: "fips.v0l.io:8443"
|
||
|
|
- transport: udp
|
||
|
|
addr: "fips.v0l.io:2121"
|
||
|
|
connect_policy: auto_connect
|
||
|
|
|
||
|
|
# Fleet LAN fast-path — other archipelago nodes on this subnet.
|
||
|
|
YAML
|
||
|
|
|
||
|
|
for other_row in "${NODES[@]}"; do
|
||
|
|
read -r o_node _o_nic o_npub <<< "$other_row"
|
||
|
|
[ "$o_node" = "$self_node" ] && continue
|
||
|
|
cat >> "$out" <<YAML
|
||
|
|
- npub: "$o_npub"
|
||
|
|
alias: "archi-$o_node"
|
||
|
|
addresses:
|
||
|
|
- transport: udp
|
||
|
|
addr: "$LAN_PREFIX.$o_node:$UDP_PORT"
|
||
|
|
- transport: tcp
|
||
|
|
addr: "$LAN_PREFIX.$o_node:$TCP_PORT"
|
||
|
|
connect_policy: auto_connect
|
||
|
|
YAML
|
||
|
|
done
|
||
|
|
echo "$out"
|
||
|
|
}
|
||
|
|
|
||
|
|
deploy_to() {
|
||
|
|
local node="$1"
|
||
|
|
local nic="$2"
|
||
|
|
local ip="$LAN_PREFIX.$node"
|
||
|
|
local yaml
|
||
|
|
yaml=$(generate_yaml "$node" "$nic")
|
||
|
|
|
||
|
|
log_info "[.${node}] uploading fips.yaml"
|
||
|
|
scp_cmd "$yaml" "archipelago@${ip}:/tmp/fips.yaml.new"
|
||
|
|
|
||
|
|
log_info "[.${node}] installing + restarting fips.service"
|
||
|
|
ssh_cmd "$ip" '
|
||
|
|
set -e
|
||
|
|
sudo install -o root -g root -m 0600 /tmp/fips.yaml.new /etc/fips/fips.yaml
|
||
|
|
rm -f /tmp/fips.yaml.new
|
||
|
|
sudo systemctl restart fips.service
|
||
|
|
# Give the daemon a beat to come up before we ask about peers
|
||
|
|
for i in $(seq 1 10); do
|
||
|
|
if sudo systemctl is-active fips.service >/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
|