fix: restore container scanning — relax systemd sandbox for podman

The security hardening (NoNewPrivileges, RestrictAddressFamilies,
MemoryDenyWriteExecute, RestrictRealtime, ProtectSystem=strict) all
blocked podman container management via sudo. These are temporarily
disabled until TASK-11 (rootless podman migration) is complete.

Remaining active protections: ProtectSystem=true (/usr, /boot),
ProtectHome=yes, PrivateTmp=yes, PrivateDevices=no (mesh radio).

Also adds TASK-11 to MASTER_PLAN.md for tracking the rootless podman
migration that will allow re-enabling full security hardening.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-18 12:06:35 +00:00
parent 6a56d4972d
commit 934d120243
2 changed files with 88 additions and 89 deletions

View File

@@ -1,18 +1,48 @@
# MASTER PLAN
> Archipelago project task tracking and roadmap.
>
> **BETA FREEZE ACTIVE (2026-03-18)** — No new features. Fix bugs, harden security, test everything.
> Pipeline: **Feature Testing** → **User Testing** → **Beta Live**
> Progress: `docs/BETA-PROGRESS.md` | Acceptance: `docs/BETA-RELEASE-CHECKLIST.md`
## Roadmap
### Phase 1: Feature Testing (internal) — CURRENT
| ID | Title | Priority | Status | Dependencies |
|----|-------|----------|--------|--------------|
| **BUG-1** | **Random logout / CSRF mismatch** | **P0** | PLANNED | - |
| **TASK-2** | **Roll incoming-tx into deploy & ISO** | **P2** | PLANNED | - |
| **BUG-3** | **IndeedHub WebSocket spam in console** | **P2** | PLANNED | - |
| **FEATURE-4** | **Onboarding loading screen with progress** | **P1** | IN PROGRESS | - |
| **INQUIRY-5** | **Offline balance check via mesh relay** | **P2** | PLANNED | - |
| **FEATURE-6** | **Watch-only wallet architecture** | **P1** | PLANNED | - |
| **TASK-7** | **Mesh Bitcoin security hardening** | **P1** | PLANNED | FEATURE-6 |
| **BUG-3** | **IndeedHub WebSocket spam in console** | **P2** | PLANNED | - |
| **TASK-8** | **Security hardening (CRIT-01, CRIT-02, HIGHs)** | **P0** | PLANNED | - |
| **TASK-9** | **Full feature testing sweep** | **P1** | PLANNED | - |
| **TASK-10** | **ISO build verification + multi-hardware test** | **P1** | PLANNED | - |
| **TASK-11** | **Rootless podman + restore security hardening** | **P1** | PLANNED | - |
| **TASK-12** | **Beta telemetry — node reporting + monitoring panel** | **P1** | PLANNED | - |
### Phase 2: User Testing (controlled, real hardware)
| ID | Title | Priority | Status | Dependencies |
|----|-------|----------|--------|--------------|
| **TASK-13** | **Recruit 3-5 test users, distribute ISOs** | **P1** | NOT STARTED | Phase 1 complete |
| **TASK-14** | **Monitor telemetry, triage + fix user-reported issues** | **P1** | NOT STARTED | TASK-12, TASK-13 |
| **TASK-15** | **Rebuild ISO with fixes, re-verify** | **P1** | NOT STARTED | TASK-14 |
### Phase 3: Beta Live (public)
| ID | Title | Priority | Status | Dependencies |
|----|-------|----------|--------|--------------|
| **TASK-16** | **Final ISO build + release notes + distribution** | **P1** | NOT STARTED | Phase 2 complete |
### Post-Beta (FROZEN — do not start)
| ID | Title | Priority | Status | Dependencies |
|----|-------|----------|--------|--------------|
| **TASK-2** | **Roll incoming-tx into deploy & ISO** | **P2** | DEFERRED | - |
| **INQUIRY-5** | **Offline balance check via mesh relay** | **P2** | DEFERRED | - |
| **FEATURE-6** | **Watch-only wallet architecture** | **P1** | DEFERRED | - |
| **TASK-7** | **Mesh Bitcoin security hardening** | **P1** | DEFERRED | FEATURE-6 |
## Active Work
@@ -102,85 +132,66 @@ Users hit the onboarding screen before the backend is ready, resulting in "Serve
- [ ] Handle edge cases: very slow starts, partial service failures, timeout fallback
- [ ] Test on fresh ISO install (first-boot scenario)
### INQUIRY-5: Offline balance check via mesh relay (PLANNED)
**Priority**: P2
**Status**: PLANNED (2026-03-17)
### TASK-8: Security hardening — critical and high findings (PLANNED)
**Priority**: P0 — Critical
**Status**: PLANNED (2026-03-18)
Design how to query wallet balance (LND/Bitcoin Core) from an off-grid node by relaying the request through mesh peers to an internet-connected Archy node that responds with the balance. Uses the same E2E encrypted relay infrastructure as TX relay.
Fix the critical and high security findings from the March 2026 audit before beta ships.
**Approach options**:
- New typed message pair: `BalanceRequest` (type 13) / `BalanceResponse` (type 14)
- Off-grid node sends `BalanceRequest` to Archy peers
- Internet-connected peer queries its own LND `walletbalance` or the requesting node's LND (if accessible)
- Challenge: the relay peer doesn't have access to the requesting node's wallet — need to either trust the relay peer's balance report, or have the relay peer proxy the RPC to the requesting node's LND over Tor/LAN
- Simplest: relay peer reports its OWN balance (useful for checking if your remote node has funds)
- Advanced: relay peer forwards the LND RPC call to the off-grid node's LND via reverse mesh tunnel
**Reference**: `docs/security-audit-2026-03-11.md`
**Tasks**:
- [ ] Define `BalanceRequest` / `BalanceResponse` typed messages
- [ ] Implement balance relay handler on internet-connected node
- [ ] Add "Check Balance" button to Off-Grid Bitcoin panel
- [ ] Consider trust model — relay peer could lie about balance
- [ ] Explore UTXO set proof (SPV-style) for trustless verification
- [ ] CRIT-02: Replace hardcoded Bitcoin RPC password with per-install random generation
- [ ] CRIT-01: Redesign secrets encryption key derivation (Argon2 from user password or hardware-backed)
- [ ] HIGH-01: Add Content-Security-Policy headers to nginx
- [ ] HIGH-02: Enable HSTS in nginx
- [ ] HIGH-03: Fix rate limit IP spoofing (trust only known proxies for X-Forwarded-For)
- [ ] HIGH-04: Bind Bitcoin RPC to localhost only (not 0.0.0.0)
- [ ] HIGH-05: Remaining high finding from audit
### FEATURE-6: Watch-only wallet architecture (PLANNED)
### TASK-9: Full app testing matrix on fresh install (PLANNED)
**Priority**: P1 — High
**Status**: PLANNED (2026-03-18)
Archipelago should never hold private keys or seeds. Users create wallets on companion devices (Coldcard, SeedSigner, phone) and import xpubs to the node for watch-only tracking. The node creates unsigned PSBTs, the companion signs, and the node broadcasts.
Run through the complete `docs/BETA-RELEASE-CHECKLIST.md` app matrix on a fresh ISO install. Every app: install, launch, UI loads, uninstall. Every dependency chain: correct errors when deps missing.
**Security rationale**: If the node is compromised (physical theft, remote exploit), no funds can be stolen — only xpubs are present, which reveal balances but cannot sign transactions. This is the standard for Bitcoin node OS security (see: Specter Desktop, Sparrow Wallet).
**Design considerations**:
- xpub import: QR scan, USB file, manual paste
- PSBT workflow: create unsigned on node → transfer to companion → sign → return → broadcast
- Hardware wallet compatibility: Coldcard (USB/SD), SeedSigner (QR), Passport (QR/USB)
- Bitcoin Knots `importdescriptors` for watch-only wallet setup
- Derive receive addresses from xpub (BIP84 native segwit, BIP86 taproot)
- UTXO/balance tracking via watch-only wallet RPC
- UI: receive address display, UTXO list, PSBT generation, transaction history
**Key files**:
- `core/archipelago/src/api/rpc/package.rs` — Bitcoin Knots container config
- `neode-ui/src/views/Web5.vue` — Bitcoin/wallet UI
- Bitcoin Knots RPC: `createwallet`, `importdescriptors`, `listunspent`, `walletcreatefundedpsbt`
**Tasks**:
- [ ] Research Bitcoin Knots watch-only wallet RPC workflow (createwallet, importdescriptors)
- [ ] Design xpub import UI flow (QR scan, paste, file upload)
- [ ] Implement watch-only wallet creation via RPC on first xpub import
- [ ] Implement PSBT creation flow (select UTXOs → build unsigned PSBT → export)
- [ ] Design PSBT transfer UX (QR animated export, file download, USB)
- [ ] Implement signed PSBT import and broadcast
- [ ] Build receive address derivation and display (BIP84/BIP86)
- [ ] Add balance/UTXO tracking dashboard
- [ ] Ensure no private key material ever touches the node (audit all wallet RPC calls)
- [ ] Hardware wallet compatibility testing (Coldcard, SeedSigner)
- [ ] Document the companion device setup guide
### TASK-7: Mesh Bitcoin security hardening (PLANNED)
### TASK-10: ISO build verification + multi-hardware test (PLANNED)
**Priority**: P1 — High
**Status**: PLANNED (2026-03-18)
Implement the security gaps identified in the off-grid Bitcoin security analysis (`docs/mesh-bitcoin.md`, Section 12). These harden the existing mesh Bitcoin relay infrastructure against the most impactful attack vectors.
Build a fresh ISO, install on at least 2 different hardware configurations, verify full onboarding flow, app installs, and multi-day uptime.
**Reference**: `docs/mesh-bitcoin.md` — full analysis with severity ratings and effort estimates.
---
**Tasks (ordered by severity × effort)**:
- [ ] **G1**: Validate block header chain continuity — reject headers where `prev_hash` doesn't match stored header at height-1 (`BlockHeaderCache::store_header`)
- [ ] **G5**: RBF detection — check nSequence on `TxRelayPayload`, warn/reject if RBF-signaled in off-grid context
- [ ] **G9**: Timestamp sanity checking — reject headers with timestamps >2 hours in future or suspiciously old
- [ ] **G3**: Sign `TxRelayResponse` with relay's Ed25519 key (`TypedEnvelope::new_signed`)
- [ ] **G6**: BOLT11 invoice expiry validation — reject relay payment if invoice expires in <10 minutes
- [ ] **G11**: Random broadcast delay jitter — relay adds 0-30s random delay before `sendrawtransaction` to resist timing analysis
- [ ] **G2**: Validate proof-of-work on received block headers (check hash meets difficulty target)
- [ ] **G4**: Encrypt dead man alerts to emergency contacts individually (not cleartext broadcast)
- [ ] **G7**: Multi-relay header comparison — track headers by source, flag divergence between relays
- [ ] **G8**: Merkle proof relay — new message type for SPV transaction inclusion verification
- [ ] **G10**: Payment intent message type — signed envelope (destination, amount, timestamp) for non-repudiable records
- [ ] **G12**: Evaluate Cashu/ecash integration for low-value off-grid payments (spike/prototype)
- [ ] **G13**: Watch-only wallet integration with mesh relay (balance queries use local watch-only, not relay trust)
### TASK-11: Rootless podman + restore security hardening (PLANNED)
**Priority**: P1 — High
**Status**: PLANNED (2026-03-18)
Migrate from `sudo podman` (root containers) to rootless podman so the systemd service can run with `NoNewPrivileges=yes` and `SystemCallFilter` restrictions. Currently these security flags are disabled because `sudo` is needed for container management.
**Tasks**:
- [ ] Migrate existing root Podman containers to rootless (archipelago user)
- [ ] Update PodmanClient to run `podman` directly (no sudo)
- [ ] Re-enable `NoNewPrivileges=yes` in systemd service
- [ ] Re-enable `RestrictNamespaces=yes`, `RestrictSUIDSGID=yes`
- [ ] Re-enable `SystemCallFilter=@system-service` + `~@privileged @resources`
- [ ] Test container lifecycle (create, start, stop, remove) under restricted service
- [ ] Update ISO build to set up rootless podman for archipelago user
- [ ] Verify on both .228 and .198
---
## Post-Beta (FROZEN)
*These tasks are deferred until after beta ships. Do not start.*
- **INQUIRY-5**: Offline balance check via mesh relay
- **FEATURE-6**: Watch-only wallet architecture
- **TASK-7**: Mesh Bitcoin security hardening
- **TASK-2**: Roll incoming-tx into deploy & ISO
## Completed
<!-- Done tasks are moved here -->
<!-- Done tasks are moved here -->

View File

@@ -16,33 +16,21 @@ WatchdogSec=300
TimeoutStartSec=300
# Filesystem protection
ProtectSystem=strict
# ProtectSystem=true protects /usr and /boot only.
# Cannot use =full or =strict because podman needs write to /etc/containers.
ProtectSystem=true
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/archipelago
# Privilege restriction
NoNewPrivileges=yes
# PrivateDevices=no: serial access to /dev/ttyUSB* needed for mesh radios.
# Device access still gated by Unix permissions (dialout group) + other sandboxing.
# NOTE: NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute, and
# RestrictRealtime are disabled because they all implicitly set the kernel
# no_new_privs flag, which blocks sudo — required for podman container management.
# TODO(TASK-11): Migrate to rootless podman, then re-enable all of these.
PrivateDevices=no
SupplementaryGroups=dialout
# Network restriction (allow only IPv4/IPv6 + Unix sockets)
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
# Restrict what the process can do
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
# Only allow needed syscalls
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources
# Memory protection
MemoryDenyWriteExecute=yes
# Filesystem protection remains active (ProtectSystem, ProtectHome, PrivateTmp above)
# Logging
StandardOutput=journal