From a0a7aadcb3770a4efa97c35f8b899547da3b5983 Mon Sep 17 00:00:00 2001 From: Dorian Date: Thu, 9 Apr 2026 21:32:08 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20Debian=2012=20=E2=86=92=2013=20(Trixie?= =?UTF-8?q?)=20migration,=20service=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update all references from Debian 12 (Bookworm) to Debian 13 (Trixie) - Enable SystemCallArchitectures, RestrictAddressFamilies, RestrictRealtime in archipelago.service (safe on systemd 256+ which respects NoNewPrivileges=no) - Update GLIBC compatibility checks from 2.36 to 2.40 - ISO filename, build container, and docs updated throughout Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/build-iso-dev.yml | 4 +-- BUILD-GUIDE.md | 2 +- CLAUDE.md | 4 +-- CONTRIBUTING.md | 2 +- README.md | 6 ++--- RELEASE-NOTES-v1.0.0.md | 2 +- .../src/api/rpc/package/install.rs | 4 +-- docs/BETA-RELEASE-CHECKLIST.md | 2 +- docs/architecture.md | 2 +- docs/developer-guide.md | 2 +- image-recipe/BUILD-ISO-STATUS.md | 2 +- image-recipe/README.md | 4 +-- image-recipe/build-auto-installer-iso.sh | 27 +++++++++---------- image-recipe/configs/archipelago.service | 11 ++++---- image-recipe/create-fat32-usb.sh | 2 +- image-recipe/scripts/build-backend.sh | 2 +- image-recipe/write-usb-dd.sh | 2 +- scripts/first-boot-containers.sh | 2 +- scripts/install-tui-demo.sh | 2 +- 19 files changed, 41 insertions(+), 43 deletions(-) diff --git a/.gitea/workflows/build-iso-dev.yml b/.gitea/workflows/build-iso-dev.yml index d3be48f0..c82101f0 100644 --- a/.gitea/workflows/build-iso-dev.yml +++ b/.gitea/workflows/build-iso-dev.yml @@ -50,8 +50,8 @@ jobs: # Build in persistent repo dir to reuse target/ cache cd "$HOME/archy" export GIT_HASH=$(git rev-parse --short HEAD) - # Static musl build — runner is Debian 13 (glibc 2.41) but ISO rootfs - # is Debian 12/bookworm (glibc 2.36). Dynamic binary won't run. + # Static musl build for portability — ensures binary runs regardless + # of glibc version differences between build host and ISO rootfs. cargo build --release --target x86_64-unknown-linux-musl --manifest-path core/Cargo.toml # Copy binary to workspace for downstream steps mkdir -p "$GITHUB_WORKSPACE/core/target/release" diff --git a/BUILD-GUIDE.md b/BUILD-GUIDE.md index f29c3a54..dfd91a17 100644 --- a/BUILD-GUIDE.md +++ b/BUILD-GUIDE.md @@ -43,7 +43,7 @@ DEV_SERVER=archipelago@192.168.1.228 ./build-auto-installer-iso.sh ## What the ISO Includes -✅ Complete Debian 12 root filesystem +✅ Complete Debian 13 root filesystem ✅ Pre-built Archipelago backend ✅ Pre-built frontend (web UI) ✅ **Prepackaged container images** (Bitcoin Knots, LND, UIs, and other bundled apps), loaded on first boot diff --git a/CLAUDE.md b/CLAUDE.md index 4aa53e77..6efe57b1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,7 +2,7 @@ Archipelago is a **Bitcoin Node OS** — bootable, self-sovereign personal server. Flash to USB, install on hardware, manage via web UI. -**Stack**: Rust backend + Vue 3 + TypeScript (strict) + Vite 7 + Tailwind + Pinia + Podman on Debian 12 +**Stack**: Rust backend + Vue 3 + TypeScript (strict) + Vite 7 + Tailwind + Pinia + Podman on Debian 13 **Version**: 1.3.0 | **Target**: x86_64 and ARM64 ## Beta Freeze (2026-03-18) @@ -22,7 +22,7 @@ cd neode-ui && npm run build # Build (outputs to web/dist/neode-ui/) ## Architecture ``` -Debian 12 +Debian 13 ├── Podman (rootless, user archipelago) ├── Nginx (80/443 → backend, app proxies) ├── Rust Backend (core/) on 127.0.0.1:5678 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29ce3f26..a2fd83b8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ npm test # Run tests ### Backend (Rust) -Build on a Linux server (Debian 12), **not** macOS: +Build on a Linux server (Debian 13), **not** macOS: ```bash cargo clippy --all-targets --all-features diff --git a/README.md b/README.md index ad2a1284..f746386a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **Archipelago** is a bootable personal server OS. Flash it to a USB drive, install on any x86_64 or ARM64 machine, and manage Bitcoin infrastructure, self-hosted apps, and decentralized identity through a glassmorphism web UI. -[![Debian 12](https://img.shields.io/badge/Debian-12%20Bookworm-a80030)](https://www.debian.org/) +[![Debian 13](https://img.shields.io/badge/Debian-13%20Trixie-a80030)](https://www.debian.org/) [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE) [![Rust](https://img.shields.io/badge/rust-stable-orange)](https://www.rust-lang.org/) [![Vue.js](https://img.shields.io/badge/vue.js-3.5-brightgreen)](https://vuejs.org/) @@ -81,7 +81,7 @@ Bitcoin (ThunderHub), Storage (FileBrowser, Immich, Nextcloud), Productivity (Pe ### Prerequisites - macOS or Linux for frontend development -- Linux dev server (Debian 12) for backend builds — **never build Rust on macOS for Linux** +- Linux dev server (Debian 13) for backend builds — **never build Rust on macOS for Linux** - Node.js 20+, Rust stable toolchain ### Frontend Development @@ -112,7 +112,7 @@ sudo ./build-auto-installer-iso.sh ## Architecture ``` -Debian 12 (Bookworm) +Debian 13 (Trixie) ├── Rootless Podman (30 containers, archy-net DNS) ├── Nginx (reverse proxy, security headers, rate limiting) ├── Rust Backend (JSON-RPC API on 127.0.0.1:5678) diff --git a/RELEASE-NOTES-v1.0.0.md b/RELEASE-NOTES-v1.0.0.md index c43f03ee..a2f9a1b2 100644 --- a/RELEASE-NOTES-v1.0.0.md +++ b/RELEASE-NOTES-v1.0.0.md @@ -1,7 +1,7 @@ # Archipelago v1.0.0 Release Notes **Release Date**: March 2026 -**Target Platform**: Debian 12 (Bookworm) — x86_64 and ARM64 +**Target Platform**: Debian 13 (Trixie) — x86_64 and ARM64 ## What is Archipelago? diff --git a/core/archipelago/src/api/rpc/package/install.rs b/core/archipelago/src/api/rpc/package/install.rs index 7198d056..bbe5617c 100644 --- a/core/archipelago/src/api/rpc/package/install.rs +++ b/core/archipelago/src/api/rpc/package/install.rs @@ -1058,8 +1058,8 @@ autopilot.active=false\n", } /// Resolve the host gateway IP for --add-host flag. -/// Podman 4.3.x (Debian 12) doesn't support "host-gateway" in rootless mode, -/// so we resolve the default gateway IP from the routing table. +/// Resolve the default gateway IP from the routing table for --add-host flag. +/// Explicit IP avoids issues with "host-gateway" in rootless Podman. async fn resolve_host_gateway() -> String { // Try `ip route` to get the default gateway if let Ok(output) = tokio::process::Command::new("ip") diff --git a/docs/BETA-RELEASE-CHECKLIST.md b/docs/BETA-RELEASE-CHECKLIST.md index 24b04c49..a2562aa7 100644 --- a/docs/BETA-RELEASE-CHECKLIST.md +++ b/docs/BETA-RELEASE-CHECKLIST.md @@ -156,7 +156,7 @@ These must be tested in order on a fresh install: - [ ] Boot from USB on x86_64 hardware - [ ] Auto-installer partitions disk correctly -- [ ] Debian 12 installs without errors +- [ ] Debian 13 installs without errors - [ ] Archipelago services start on first boot - [ ] Web UI accessible at server IP within 3 minutes of first boot diff --git a/docs/architecture.md b/docs/architecture.md index 1e78b051..32e352f1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -3,7 +3,7 @@ > **Bitcoin Node OS** — Flash to USB, install on hardware, manage via web UI. **Stack**: Rust backend + Vue 3 + TypeScript (strict) + Vite 7 + Tailwind CSS + Pinia + rootless Podman -**Target OS**: Debian 12 (Bookworm) — x86_64 and ARM64 +**Target OS**: Debian 13 (Trixie) — x86_64 and ARM64 **Status**: Beta freeze (Phase 1: Feature Testing) For the full interactive architecture review with diagrams and learning guide, see [`architecture-review.html`](architecture-review.html). diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 6629806c..63b40bf7 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -75,7 +75,7 @@ archy/ ### Prerequisites - **macOS** (development machine): Node.js 20+, npm -- **Linux server** (`192.168.1.228`): Rust toolchain, Podman, Nginx, Debian 12 +- **Linux server** (`192.168.1.228`): Rust toolchain, Podman, Nginx, Debian 13 - SSH key: `~/.ssh/archipelago-deploy` ### Local Frontend Development diff --git a/image-recipe/BUILD-ISO-STATUS.md b/image-recipe/BUILD-ISO-STATUS.md index 7aea458b..d90b3007 100644 --- a/image-recipe/BUILD-ISO-STATUS.md +++ b/image-recipe/BUILD-ISO-STATUS.md @@ -74,7 +74,7 @@ From your dev server (192.168.1.228): ## Current Status -**Latest Working ISO**: `archipelago-debian-12-x86_64.iso` (469M, built 18:28) +**Latest Working ISO**: `archipelago-debian-13-x86_64.iso` (469M, built 18:28) - This ISO was built earlier today - Contains the auto-installer - **Should be tested** - might already have your live server state diff --git a/image-recipe/README.md b/image-recipe/README.md index 8a1c7ae5..1038c072 100644 --- a/image-recipe/README.md +++ b/image-recipe/README.md @@ -35,7 +35,7 @@ See the Architecture documentation for detailed system information. ## What's Included -- **Debian Linux Base**: Stable Debian 12 (Bookworm) distribution +- **Debian Linux Base**: Stable Debian 13 (Trixie) distribution - **Podman**: Container runtime for apps (rootless by default) - **Archipelago Backend**: Rust-based API server - **Archipelago Frontend**: Vue.js web interface @@ -44,7 +44,7 @@ See the Architecture documentation for detailed system information. ## Build Output -- `results/archipelago-debian-12-x86_64.iso` - Bootable hybrid ISO image +- `results/archipelago-debian-13-x86_64.iso` - Bootable hybrid ISO image ## Supported Platforms diff --git a/image-recipe/build-auto-installer-iso.sh b/image-recipe/build-auto-installer-iso.sh index 3e8d0fa2..4a38891d 100755 --- a/image-recipe/build-auto-installer-iso.sh +++ b/image-recipe/build-auto-installer-iso.sh @@ -905,10 +905,9 @@ mkdir -p "$ARCH_DIR" mkdir -p "$ARCH_DIR/bin" mkdir -p "$ARCH_DIR/scripts" -# netavark + aardvark-dns are installed in the rootfs via Dockerfile.rootfs (Debian 12 packages). -# Do NOT copy from the build host — the host may run a newer glibc (e.g. Debian 13) -# and the resulting binary will fail on the Debian 12 target with GLIBC_2.39 not found. -echo " netavark + aardvark-dns: included in rootfs (Debian 12 packages)" +# netavark + aardvark-dns are installed in the rootfs via Dockerfile.rootfs (Debian 13 packages). +# Do NOT copy from the build host — the host may run a different glibc version. +echo " netavark + aardvark-dns: included in rootfs (Debian 13 packages)" # Copy the pre-built rootfs echo " Including root filesystem..." @@ -967,9 +966,9 @@ 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 +# NOTE: The container image must be built against Debian 13's GLIBC (2.40). +# If built against a newer GLIBC, the binary will fail at runtime. +# Rebuild with: FROM debian:13 AS builder echo " Extracting NostrVPN binary..." _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)" @@ -982,17 +981,17 @@ if [ -n "$NVPN_CONTAINER" ]; then 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 + # Check GLIBC compatibility — Debian 13 (Trixie) has GLIBC 2.40 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." + # Compare: if required GLIBC > 2.40, warn + if printf '%s\n' "2.40" "$NVPN_GLIBC" | sort -V | tail -1 | grep -qv "^2\.40$"; then + echo " ⚠ WARNING: nvpn binary requires GLIBC $NVPN_GLIBC but Debian 13 has 2.40" + echo " ⚠ The nvpn daemon will fail at runtime. Rebuild the container against Debian 13." 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)" + echo " ✅ nvpn GLIBC compatibility OK (requires $NVPN_GLIBC, target has 2.40)" fi fi fi @@ -2048,7 +2047,7 @@ REGCONF chown -R 1000:1000 /mnt/target/home/archipelago/.config # Configure podman to use netavark backend (enables container DNS on archy-net). -# netavark + aardvark-dns binaries come from the rootfs (Debian 12 apt packages). +# netavark + aardvark-dns binaries come from the rootfs (Debian 13 apt packages). if [ -f /mnt/target/usr/lib/podman/netavark ]; then mkdir -p /mnt/target/home/archipelago/.config/containers cat > /mnt/target/home/archipelago/.config/containers/containers.conf <<'CONTAINERSCONF' diff --git a/image-recipe/configs/archipelago.service b/image-recipe/configs/archipelago.service index dcebe306..93a18fc0 100644 --- a/image-recipe/configs/archipelago.service +++ b/image-recipe/configs/archipelago.service @@ -34,12 +34,11 @@ NoNewPrivileges=no PrivateDevices=no SupplementaryGroups=dialout debian-tor -# 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. +# Syscall and network restrictions — safe on Debian 13 (systemd 256+) +# which respects NoNewPrivileges=no as an explicit override for seccomp filters +SystemCallArchitectures=native +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictRealtime=yes # MemoryDenyWriteExecute removed: ring (rustls) and secp256k1 (bitcoin/nostr) # use assembly code that requires executable memory mappings on some platforms diff --git a/image-recipe/create-fat32-usb.sh b/image-recipe/create-fat32-usb.sh index c4181475..8c90fb5a 100755 --- a/image-recipe/create-fat32-usb.sh +++ b/image-recipe/create-fat32-usb.sh @@ -20,7 +20,7 @@ if [ -z "$1" ]; then fi USB_DISK="$1" -ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-12-x86_64.iso" +ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-13-x86_64.iso" WORK_DIR="$SCRIPT_DIR/build/usb-extract" if [ ! -f "$ISO_FILE" ]; then diff --git a/image-recipe/scripts/build-backend.sh b/image-recipe/scripts/build-backend.sh index a93f6bda..b608f07c 100755 --- a/image-recipe/scripts/build-backend.sh +++ b/image-recipe/scripts/build-backend.sh @@ -32,7 +32,7 @@ if [ "$USE_DOCKER" = true ]; then -v "$PROJECT_ROOT:/workspace" \ -v "$OUTPUT_DIR:/output" \ -w /workspace/core/archipelago \ - rust:bookworm \ + rust:trixie \ sh -c ' echo "📦 Installing build dependencies..." apt-get update && apt-get install -y pkg-config libssl-dev diff --git a/image-recipe/write-usb-dd.sh b/image-recipe/write-usb-dd.sh index f14b0aec..675b704c 100755 --- a/image-recipe/write-usb-dd.sh +++ b/image-recipe/write-usb-dd.sh @@ -17,7 +17,7 @@ fi USB_DISK="$1" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-12-x86_64.iso" +ISO_FILE="$SCRIPT_DIR/results/archipelago-debian-13-x86_64.iso" if [ ! -f "$ISO_FILE" ]; then echo "❌ ISO not found: $ISO_FILE" diff --git a/scripts/first-boot-containers.sh b/scripts/first-boot-containers.sh index e727360f..c6a38d1a 100644 --- a/scripts/first-boot-containers.sh +++ b/scripts/first-boot-containers.sh @@ -126,7 +126,7 @@ else fi # ── NostrVPN: configure native system service with node identity ────── -# The nvpn binary may have GLIBC mismatch (built for newer glibc than Debian 12). +# The nvpn binary may have GLIBC mismatch (built for newer glibc than target OS). # 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) diff --git a/scripts/install-tui-demo.sh b/scripts/install-tui-demo.sh index 2f133f67..d3e2cf19 100755 --- a/scripts/install-tui-demo.sh +++ b/scripts/install-tui-demo.sh @@ -273,7 +273,7 @@ PHASE_DETAILS=( "/dev/sda (465.8G) — TOSHIBA MQ01ACF0" "BIOS boot + EFI + root + data" "FAT32, ext4, LUKS2" - "debootstrap → Debian 12 minimal" + "debootstrap → Debian 13 minimal" "AES-256-XTS (AES-NI detected)" "GRUB: BIOS + UEFI hybrid" )