fix: AIUI /aiui/ base path, nginx alias cycle, VPN auth, container boot

- AIUI: rebuild with /aiui/ base path (router, chunk loader, SW scope)
- nginx: remove alias from /aiui/ location (caused try_files redirect cycle)
- VPN: WireGuard standalone setup, auth improvements
- ISO: build script hardening, service file updates
- first-boot-containers: networking stack fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-09 20:42:09 +02:00
parent a8c6a36cd1
commit b8a09b448b
94 changed files with 382 additions and 233 deletions

View File

@@ -126,67 +126,96 @@ else
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)
NOSTR_PUBKEY=$(cat /var/lib/archipelago/identity/nostr_pubkey 2>/dev/null)
if [ -n "$NOSTR_SECRET" ]; then
# Initialize nvpn config if not already done
NVPN_CONFIG_DIR="/home/archipelago/.config/nvpn"
mkdir -p "$NVPN_CONFIG_DIR"
# The nvpn binary may have GLIBC mismatch (built for newer glibc than Debian 12).
# Write config.toml directly as fallback — the Rust backend reads it for vpn.invite/status.
NOSTR_SECRET=$(cat /var/lib/archipelago/identity/nostr_secret 2>/dev/null)
NOSTR_PUBKEY=$(cat /var/lib/archipelago/identity/nostr_pubkey 2>/dev/null)
if [ -n "$NOSTR_SECRET" ]; then
NVPN_CONFIG_DIR="/home/archipelago/.config/nvpn"
DAEMON_CONFIG_DIR="/var/lib/archipelago/nostr-vpn/.config/nvpn"
mkdir -p "$NVPN_CONFIG_DIR" "$DAEMON_CONFIG_DIR"
# Try nvpn CLI first (may fail with GLIBC mismatch)
NVPN_CLI_OK=false
if command -v nvpn >/dev/null 2>&1; then
if [ ! -f "$NVPN_CONFIG_DIR/config.toml" ]; then
# Run nvpn init as archipelago user to generate default config
su -l archipelago -c "nvpn init" 2>/dev/null || true
if su -l archipelago -c "nvpn init" 2>/dev/null; then
NVPN_CLI_OK=true
su -l archipelago -c "nvpn set --config '$NVPN_CONFIG_DIR/config.toml'" 2>/dev/null || true
else
log "NostrVPN: nvpn init failed (likely GLIBC mismatch) — using direct config"
fi
else
NVPN_CLI_OK=true
fi
# Set the node's Nostr identity from onboarding seed phrase
su -l archipelago -c "nvpn set --config '$NVPN_CONFIG_DIR/config.toml'" 2>/dev/null || true
fi
# Get server's public IP for WireGuard endpoint
HOST_IP=$(cat /var/lib/archipelago/host-ip.env 2>/dev/null | grep ARCHIPELAGO_HOST_IP | cut -d= -f2)
[ -z "$HOST_IP" ] && HOST_IP=$(curl -s --connect-timeout 5 https://api.ipify.org 2>/dev/null || hostname -I | awk '{print $1}')
# Get server's public IP for WireGuard endpoint
HOST_IP=$(cat /var/lib/archipelago/host-ip.env 2>/dev/null | grep ARCHIPELAGO_HOST_IP | cut -d= -f2)
[ -z "$HOST_IP" ] && HOST_IP=$(curl -s --connect-timeout 5 https://api.ipify.org 2>/dev/null || hostname -I | awk '{print $1}')
# Configure nvpn with node identity and endpoint
if [ -f "$NVPN_CONFIG_DIR/config.toml" ]; then
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
if $NVPN_CLI_OK && [ -f "$NVPN_CONFIG_DIR/config.toml" ]; then
# nvpn CLI works — use it to configure
su -l archipelago -c "nvpn set --endpoint '${HOST_IP}:51821'" 2>/dev/null || true
# 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
fi
# Sync config to daemon HOME so the service finds it
# (service runs with HOME=/var/lib/archipelago/nostr-vpn)
# Owned by archipelago so the backend can update participants without sudo
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"
# Fallback: write config.toml directly if it doesn't exist yet.
# Uses hex keys — the Rust backend converts hex to npub1/nsec1 at read time.
if [ ! -f "$DAEMON_CONFIG_DIR/config.toml" ] && [ ! -f "$NVPN_CONFIG_DIR/config.toml" ]; then
# Build relay list
RELAYS=""
RELAY_ONION=$(cat /var/lib/archipelago/tor-hostnames/relay 2>/dev/null)
if [ -n "$RELAY_ONION" ]; then
RELAYS="\"ws://${RELAY_ONION}:7777\""
fi
chown -R archipelago:archipelago /var/lib/archipelago/nostr-vpn
if [ -n "$HOST_IP" ] && ! echo "$HOST_IP" | grep -qE '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)'; then
[ -n "$RELAYS" ] && RELAYS="$RELAYS, "
RELAYS="${RELAYS}\"ws://${HOST_IP}:7777\""
fi
[ -z "$RELAYS" ] && RELAYS='"wss://relay.damus.io", "wss://relay.primal.net"'
# Ensure env file exists for the service
mkdir -p /var/lib/archipelago/nostr-vpn
cat > /var/lib/archipelago/nostr-vpn/env <<NVPNENV
cat > "$DAEMON_CONFIG_DIR/config.toml" <<NVPNCONF
[nostr]
public_key = "${NOSTR_PUBKEY}"
secret_key = "${NOSTR_SECRET}"
relays = [${RELAYS}]
[[networks]]
network_id = "archipelago"
participants = []
NVPNCONF
chmod 600 "$DAEMON_CONFIG_DIR/config.toml"
log "NostrVPN: wrote config.toml directly (hex keys, backend converts)"
fi
# Sync user config to daemon dir if nvpn CLI created it
if [ -f "$NVPN_CONFIG_DIR/config.toml" ] && [ ! -f "$DAEMON_CONFIG_DIR/config.toml" ]; then
cp "$NVPN_CONFIG_DIR/config.toml" "$DAEMON_CONFIG_DIR/config.toml"
fi
chown -R archipelago:archipelago /var/lib/archipelago/nostr-vpn
# Ensure env file exists for the service
mkdir -p /var/lib/archipelago/nostr-vpn
cat > /var/lib/archipelago/nostr-vpn/env <<NVPNENV
NOSTR_SECRET=${NOSTR_SECRET}
NOSTR_PUBKEY=${NOSTR_PUBKEY}
NVPNENV
chmod 600 /var/lib/archipelago/nostr-vpn/env
chmod 600 /var/lib/archipelago/nostr-vpn/env
# Start NostrVPN mesh service (standalone WG already started above)
systemctl reset-failed nostr-vpn 2>/dev/null || true
systemctl enable --now nostr-vpn 2>/dev/null || true
log "NostrVPN configured with node identity and started"
else
log "NostrVPN: no Nostr identity yet — will configure after onboarding"
fi
# Start NostrVPN mesh service (standalone WG already started above)
systemctl reset-failed nostr-vpn 2>/dev/null || true
systemctl enable --now nostr-vpn 2>/dev/null || true
log "NostrVPN configured with node identity and started"
else
log "NostrVPN binary not found — skipping VPN setup"
log "NostrVPN: no Nostr identity yet — will configure after onboarding"
fi
# Wait for a container to be healthy (accepting connections)