feat: ISO networking stack — relay + nvpn v0.3.7 + WireGuard

Add nostr-rs-relay as native system service (port 7777) for VPN
signaling. Every node runs its own private relay from first boot.
Update nvpn binary from v0.3.4 to v0.3.7 (fixes mesh event
processing). Add WireGuard helper and address service for peer VPN.
First-boot script configures relay, nvpn identity, relay URLs
(direct + Tor onion), and syncs daemon config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-08 15:06:27 +02:00
parent b0907c48b2
commit 42c29b99e2
6 changed files with 180 additions and 2 deletions

58
scripts/archipelago-wg Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
# archipelago-wg — Privileged WireGuard helper for the Archipelago backend.
# Installed to /usr/local/bin/archipelago-wg with a sudoers rule so the
# unprivileged archipelago/debian service user can manage wg0 without
# full root or disabling NoNewPrivileges.
#
# Usage:
# archipelago-wg setup <privkey-file> — Create wg0 interface
# archipelago-wg add-peer <pubkey> <ip> — Add peer to wg0
# archipelago-wg remove-peer <pubkey> — Remove peer from wg0
set -euo pipefail
case "${1:-}" in
setup)
KEY_FILE="${2:?Usage: archipelago-wg setup <privkey-file>}"
[ -f "$KEY_FILE" ] || { echo "Key file not found: $KEY_FILE" >&2; exit 1; }
# Ensure kernel module is loaded
modprobe wireguard 2>/dev/null || true
# Create interface
ip link add dev wg0 type wireguard 2>/dev/null || true
wg set wg0 listen-port 51820 private-key "$KEY_FILE"
# Assign server address if not already set
ip address show dev wg0 | grep -q "10.44.0.1" || ip address add 10.44.0.1/16 dev wg0
ip link set up dev wg0
# NAT masquerade for VPN clients
iptables -t nat -C POSTROUTING -s 10.44.0.0/16 ! -o wg0 -j MASQUERADE 2>/dev/null ||
iptables -t nat -A POSTROUTING -s 10.44.0.0/16 ! -o wg0 -j MASQUERADE
# Open firewall port
if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then
ufw allow 51820/udp >/dev/null 2>&1 || true
fi
echo "wg0 configured"
;;
add-peer)
PUBKEY="${2:?Usage: archipelago-wg add-peer <pubkey> <allowed-ip>}"
ALLOWED_IP="${3:?Usage: archipelago-wg add-peer <pubkey> <allowed-ip>}"
wg set wg0 peer "$PUBKEY" allowed-ips "$ALLOWED_IP"
echo "peer added"
;;
remove-peer)
PUBKEY="${2:?Usage: archipelago-wg remove-peer <pubkey>}"
wg set wg0 peer "$PUBKEY" remove
echo "peer removed"
;;
*)
echo "Usage: archipelago-wg {setup|add-peer|remove-peer}" >&2
exit 1
;;
esac

View File

@@ -86,6 +86,20 @@ done
chown -R archipelago:archipelago "$TOR_HOSTNAMES" 2>/dev/null
log "Tor hostnames populated: $(ls $TOR_HOSTNAMES 2>/dev/null | tr '\n' ' ')"
# ── Private Nostr Relay: start for VPN signaling and general use ──────
if command -v nostr-rs-relay >/dev/null 2>&1; then
# Relay config is pre-installed by ISO at /var/lib/archipelago/nostr-relay/config.toml
mkdir -p /var/lib/archipelago/nostr-relay
if [ ! -f /var/lib/archipelago/nostr-relay/config.toml ] && [ -f /etc/archipelago/nostr-relay-config.toml ]; then
cp /etc/archipelago/nostr-relay-config.toml /var/lib/archipelago/nostr-relay/config.toml
fi
chown -R archipelago:archipelago /var/lib/archipelago/nostr-relay
systemctl enable --now nostr-relay 2>/dev/null || true
log "Private Nostr relay started on port 7777"
else
log "nostr-rs-relay binary not found — skipping relay setup"
fi
# ── NostrVPN: configure native system service with node identity ──────
if command -v nvpn >/dev/null 2>&1; then
NOSTR_SECRET=$(cat /var/lib/archipelago/identity/nostr_secret 2>/dev/null)
@@ -107,7 +121,26 @@ if command -v nvpn >/dev/null 2>&1; then
# Configure nvpn with node identity and endpoint
if [ -f "$NVPN_CONFIG_DIR/config.toml" ]; then
su -l archipelago -c "nvpn set --endpoint '${HOST_IP}:51820'" 2>/dev/null || true
su -l archipelago -c "nvpn set --endpoint '${HOST_IP}:51821'" 2>/dev/null || true
fi
# Add this node's own relay as a signaling relay
# Direct relay (public IP) — only if not behind NAT
if [ -n "$HOST_IP" ] && ! echo "$HOST_IP" | grep -qE '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)'; then
su -l archipelago -c "nvpn relay add 'ws://${HOST_IP}:7777'" 2>/dev/null || true
fi
# Tor relay (works behind NAT)
RELAY_ONION=$(cat /var/lib/archipelago/tor-hostnames/relay 2>/dev/null)
if [ -n "$RELAY_ONION" ]; then
su -l archipelago -c "nvpn relay add 'ws://${RELAY_ONION}:7777'" 2>/dev/null || true
fi
# Sync config to daemon HOME so the service finds it
# (service runs with HOME=/var/lib/archipelago/nostr-vpn)
DAEMON_CONFIG_DIR="/var/lib/archipelago/nostr-vpn/.config/nvpn"
mkdir -p "$DAEMON_CONFIG_DIR"
if [ -f "$NVPN_CONFIG_DIR/config.toml" ]; then
cp "$NVPN_CONFIG_DIR/config.toml" "$DAEMON_CONFIG_DIR/config.toml"
fi
# Ensure env file exists for the service