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
co-authored by Claude Opus 4.6
parent 56e04a9df8
commit fe3c844fe6
94 changed files with 382 additions and 233 deletions
@@ -108,11 +108,11 @@ echo "📋 Installing base system..."
# Install base system using debootstrap
if command -v debootstrap >/dev/null 2>&1; then
debootstrap --arch=amd64 bookworm /mnt/archipelago http://deb.debian.org/debian
debootstrap --arch=amd64 trixie /mnt/archipelago http://deb.debian.org/debian
else
echo "❌ debootstrap not found. Installing..."
apt-get update && apt-get install -y debootstrap
debootstrap --arch=amd64 bookworm /mnt/archipelago http://deb.debian.org/debian
debootstrap --arch=amd64 trixie /mnt/archipelago http://deb.debian.org/debian
fi
echo "⚙️ Configuring system..."
@@ -149,9 +149,9 @@ echo "📦 Configuring package sources..."
# Create sources.list
cat > /mnt/archipelago/etc/apt/sources.list <<EOF
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
EOF
echo "📥 Updating package lists..."
+32 -14
View File
@@ -205,7 +205,7 @@ check_tools() {
# Fix root podman D-Bus issue (sd-bus: Transport endpoint is not connected)
# When running as sudo, systemd cgroup manager can't reach the user D-Bus session.
if [ "$CONTAINER_CMD" = "podman" ] && [ "$(id -u)" = "0" ]; then
if ! $CONTAINER_CMD run --rm debian:bookworm true 2>/dev/null; then
if ! $CONTAINER_CMD run --rm debian:trixie true 2>/dev/null; then
echo " Root podman D-Bus issue detected, using cgroupfs manager"
CONTAINER_CMD="podman --cgroup-manager=cgroupfs"
fi
@@ -239,7 +239,7 @@ if [ ! -f "$ROOTFS_TAR" ] || [ "$1" == "--rebuild" ]; then
# Create a Dockerfile for building the rootfs
cat > "$WORK_DIR/Dockerfile.rootfs" <<DOCKERFILE
FROM debian:bookworm
FROM debian:trixie
ENV DEBIAN_FRONTEND=noninteractive
@@ -253,9 +253,9 @@ RUN echo "keyboard-configuration keyboard-configuration/layoutcode string us" |
# Enable non-free-firmware repo — replace DEB822 sources with traditional format
# (DEB822 sed was silently failing, so just overwrite with known-good sources.list)
RUN echo "deb http://deb.debian.org/debian bookworm main non-free-firmware" > /etc/apt/sources.list && \
echo "deb http://deb.debian.org/debian bookworm-updates main non-free-firmware" >> /etc/apt/sources.list && \
echo "deb http://deb.debian.org/debian-security bookworm-security main non-free-firmware" >> /etc/apt/sources.list && \
RUN echo "deb http://deb.debian.org/debian trixie main non-free-firmware" > /etc/apt/sources.list && \
echo "deb http://deb.debian.org/debian trixie-updates main non-free-firmware" >> /etc/apt/sources.list && \
echo "deb http://deb.debian.org/debian-security trixie-security main non-free-firmware" >> /etc/apt/sources.list && \
rm -f /etc/apt/sources.list.d/debian.sources
# Install all packages we need including nginx, podman, tor, and openssl (for self-signed certs)
@@ -318,8 +318,8 @@ RUN find /usr/share/doc -depth -type f ! -name copyright -delete 2>/dev/null ||
find /usr/share/locale -maxdepth 1 -mindepth 1 ! -name 'en_US' ! -name 'locale.alias' -exec rm -rf {} + 2>/dev/null || true
# Install Tailscale from official repo
RUN curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null && \
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list && \
RUN curl -fsSL https://pkgs.tailscale.com/stable/debian/trixie.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null && \
curl -fsSL https://pkgs.tailscale.com/stable/debian/trixie.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list && \
apt-get update && apt-get install -y --no-install-recommends tailscale && \
apt-get clean && rm -rf /var/lib/apt/lists/*
@@ -582,7 +582,7 @@ $CONTAINER_CMD run --rm --privileged --platform $CONTAINER_PLATFORM \
-v "$WORK_DIR:/output" \
-e DEB_ARCH="$DEB_ARCH" \
-e LIB_DIR="$LIB_DIR" \
debian:bookworm bash -c '
debian:trixie bash -c '
set -e
apt-get update -qq
@@ -596,7 +596,7 @@ kmod,procps,iproute2,ca-certificates,gdisk,\
cryptsetup,cryptsetup-initramfs,parted,dosfstools,e2fsprogs,\
linux-image-${DEB_ARCH},grub-efi-${DEB_ARCH},grub-pc-bin,\
pciutils,usbutils,less,nano \
bookworm /installer http://deb.debian.org/debian
trixie /installer http://deb.debian.org/debian
# Install live-boot via chroot — debootstrap minbase resolver cannot handle it.
# The chroot approach works (confirmed in CI run 90) — just needs proc/sys/dev mounts.
@@ -948,7 +948,7 @@ if [ "$BACKEND_CAPTURED" = "0" ]; then
fi
BACKEND_DOCKERFILE="$WORK_DIR/Dockerfile.backend"
cat > "$BACKEND_DOCKERFILE" <<'BACKENDFILE'
FROM rust:1.93-bookworm as builder
FROM rust:1.93-trixie as builder
WORKDIR /build
COPY core ./core
RUN cd core && cargo build --release --bin archipelago
@@ -967,17 +967,35 @@ BACKENDFILE
fi
# Extract NostrVPN binary from container image (native system service, not a container app)
# NOTE: The container image must be built against Debian 12's GLIBC (2.36).
# If built against a newer GLIBC (e.g. 2.39 from Ubuntu 24.10), the binary will fail
# at runtime with "GLIBC_2.39 not found". Rebuild with: FROM debian:12 AS builder
echo " Extracting NostrVPN binary..."
NVPN_IMAGE="$($CONTAINER_CMD images -q 80.71.235.15:3000/archipelago/nostr-vpn:v0.3.7 2>/dev/null)"
if [ -z "$NVPN_IMAGE" ]; then
$CONTAINER_CMD pull 80.71.235.15:3000/archipelago/nostr-vpn:v0.3.7 2>/dev/null || true
_NVPN_IMG="${NOSTR_VPN_IMAGE:-80.71.235.15:3000/archipelago/nostr-vpn:v0.3.7}"
NVPN_IMAGE_ID="$($CONTAINER_CMD images -q "$_NVPN_IMG" 2>/dev/null)"
if [ -z "$NVPN_IMAGE_ID" ]; then
$CONTAINER_CMD pull "$_NVPN_IMG" 2>/dev/null || true
fi
NVPN_CONTAINER=$($CONTAINER_CMD create 80.71.235.15:3000/archipelago/nostr-vpn:v0.3.7 2>/dev/null) || true
NVPN_CONTAINER=$($CONTAINER_CMD create "$_NVPN_IMG" 2>/dev/null) || true
if [ -n "$NVPN_CONTAINER" ]; then
$CONTAINER_CMD cp "$NVPN_CONTAINER:/usr/local/bin/nvpn" "$ARCH_DIR/bin/nvpn" 2>/dev/null && \
chmod +x "$ARCH_DIR/bin/nvpn" && \
echo " ✅ NostrVPN binary extracted ($(du -h "$ARCH_DIR/bin/nvpn" | cut -f1))"
$CONTAINER_CMD rm "$NVPN_CONTAINER" 2>/dev/null || true
# Check GLIBC compatibility — Debian 12 has GLIBC 2.36
if [ -f "$ARCH_DIR/bin/nvpn" ]; then
NVPN_GLIBC=$(objdump -T "$ARCH_DIR/bin/nvpn" 2>/dev/null | grep -oP 'GLIBC_\K[0-9.]+' | sort -V | tail -1)
if [ -n "$NVPN_GLIBC" ]; then
# Compare: if required GLIBC > 2.36, warn
if printf '%s\n' "2.36" "$NVPN_GLIBC" | sort -V | tail -1 | grep -qv "^2\.36$"; then
echo " ⚠ WARNING: nvpn binary requires GLIBC $NVPN_GLIBC but Debian 12 has 2.36"
echo " ⚠ The nvpn daemon will fail at runtime. Rebuild the container against Debian 12."
echo " ⚠ VPN invite/status will still work via Rust backend config.toml fallback."
else
echo " ✅ nvpn GLIBC compatibility OK (requires $NVPN_GLIBC, target has 2.36)"
fi
fi
fi
else
echo " ⚠ NostrVPN image not available — nvpn binary will be missing"
fi
+6 -9
View File
@@ -34,15 +34,12 @@ NoNewPrivileges=no
PrivateDevices=no
SupplementaryGroups=dialout debian-tor
# Network restriction (allow IPv4/IPv6 + Unix sockets + netlink for WireGuard/VPN management)
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
# Restrict what the process can do
# RestrictNamespaces disabled: rootless podman creates user namespaces
RestrictRealtime=yes
# SystemCallFilter disabled: rootless podman needs clone/unshare for user namespaces
SystemCallArchitectures=native
# Network, syscall, and realtime restrictions DISABLED on Debian 12:
# RestrictAddressFamilies, SystemCallArchitectures, and RestrictRealtime all use
# seccomp filters that force no_new_privs=1 in the kernel (systemd 252).
# This blocks sudo, which is required for archipelago-wg (WireGuard peer management).
# Debian 13+ (systemd 256) respects NoNewPrivileges=no as an override, but Debian 12 does not.
# Re-enable these when dropping Debian 12 support.
# MemoryDenyWriteExecute removed: ring (rustls) and secp256k1 (bitcoin/nostr)
# use assembly code that requires executable memory mappings on some platforms
@@ -21,8 +21,6 @@ server {
# AIUI SPA (Chat mode iframe) — SPA fallback for client-side routing
location /aiui/ {
alias /opt/archipelago/web-ui/aiui/;
index index.html;
try_files $uri $uri/ /aiui/index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
@@ -794,8 +792,6 @@ server {
# AIUI SPA (Chat mode iframe) — SPA fallback for client-side routing
location /aiui/ {
alias /opt/archipelago/web-ui/aiui/;
index index.html;
try_files $uri $uri/ /aiui/index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
+2 -2
View File
@@ -2,6 +2,8 @@
Description=Nostr VPN - Mesh VPN with Nostr identity
After=network-online.target tor.service archipelago.service
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=10
[Service]
Type=simple
@@ -13,8 +15,6 @@ ExecStartPre=/bin/bash -c 'test -f /var/lib/archipelago/nostr-vpn/env || { echo
ExecStart=/usr/local/bin/nvpn daemon
Restart=on-failure
RestartSec=30
StartLimitIntervalSec=300
StartLimitBurst=10
TimeoutStartSec=30
TimeoutStopSec=10