mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-28 21:17:36 +00:00
feat(build): Add kiosk mode + VirtualBox setup + Profile Generator architecture
VM-x64 Build Improvements: - Enable kiosk mode by default with GRUB menu entries - Increase image size to 8GB (5.5GB root) for full package set - Add proper EFI boot configuration with 3 boot modes - Pre-generate SSL certificates during build - Add TTY2 autologin for emergency console access VirtualBox Support: - Add scripts/vbox-setup.sh for automated VM setup - Add wiki/VirtualBox-Setup.md with comprehensive guide - Support bridged, NAT, and host-only network modes - Auto-detect network adapter for bridged mode Architecture Documentation: - Add docs/architecture/profile-generator.md (v0.2) - Define tier × board × flavors resolution model - Document 3 CLI tools: secubox-gen, secubox-build, secubox-fetch - Add Phase 12-14 roadmap alignment for Ulule Campaign 1 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6f72146a4f
commit
33304e7b6f
130
.claude/TODO.md
130
.claude/TODO.md
|
|
@ -306,4 +306,134 @@ Advanced security features:
|
|||
|
||||
---
|
||||
|
||||
## 🔄 PHASE 12 — Meta-Script Generator (v2.0.0)
|
||||
|
||||
*SecuBox Appliance Factory — Profile-based, modular image generation with version tracking*
|
||||
|
||||
### Architecture Core
|
||||
- [ ] **P12-01** Profile hierarchy system ("gigogne" nested inheritance)
|
||||
- base/ → tier-lite/ → tier-standard/ → tier-pro/
|
||||
- Profile YAML with `inherits:` directive
|
||||
- Component capability matrix (memory, CPU, storage requirements)
|
||||
- Automatic profile selection based on detected hardware
|
||||
- [ ] **P12-02** Board-specific tweaks registry
|
||||
- boards/<board>/tweaks.yaml — hardware-specific optimizations
|
||||
- DTS/DTB overrides per board
|
||||
- Kernel module blacklist/whitelist per board
|
||||
- Performance profiles (idle, normal, busy, stressed)
|
||||
- [ ] **P12-03** Component versioning system
|
||||
- component-version.yaml per package
|
||||
- Semantic versioning with SecuBox patch suffix (e.g., 1.7.7-sb3)
|
||||
- Compatibility matrix (min memory, requires, conflicts)
|
||||
- Tag system for feature categorization
|
||||
|
||||
### Generator CLI
|
||||
- [ ] **P12-04** `secubox-gen` — Manifest generator
|
||||
```bash
|
||||
secubox-gen --profile tier-lite --board espressobin-v7 \
|
||||
--enable crowdsec,wireguard --tweak low-memory \
|
||||
--output manifest.yaml
|
||||
```
|
||||
- Interactive mode with hardware detection
|
||||
- Profile auto-selection based on target specs
|
||||
- Dependency resolution and conflict detection
|
||||
- [ ] **P12-05** `secubox-build` — Image builder from manifest
|
||||
- Reproducible builds from manifest.yaml
|
||||
- Incremental builds (delta from base image)
|
||||
- Multi-stage build with checkpoints
|
||||
- Build cache for faster iteration
|
||||
- [ ] **P12-06** `secubox-fetch` — GitHub release downloader
|
||||
- Download pre-built images for tested boards
|
||||
- GPG signature verification
|
||||
- SHA256 checksum validation
|
||||
- Automatic version matching
|
||||
|
||||
### Appliance README Generator
|
||||
- [ ] **P12-07** Auto-generated appliance documentation
|
||||
- Hardware profile summary
|
||||
- Component version table with status
|
||||
- Applied tweaks and optimizations
|
||||
- Support contact and issue reporting
|
||||
- [ ] **P12-08** Machine-readable manifest for bug reports
|
||||
- JSON export for automated support
|
||||
- Hardware capability snapshot
|
||||
- Service status at generation time
|
||||
- Version fingerprint hash
|
||||
|
||||
### Portable Application
|
||||
- [ ] **P12-09** Electron/Tauri desktop app for image generation
|
||||
- Cross-platform (Linux, macOS, Windows)
|
||||
- GitHub OAuth for release access
|
||||
- Visual board/profile selector
|
||||
- Progress tracking with logs
|
||||
- [ ] **P12-10** Web-based generator (optional)
|
||||
- Static site hosted on GitHub Pages
|
||||
- Manifest builder with live preview
|
||||
- Download link generator
|
||||
- QR code for mobile access
|
||||
|
||||
### Version Tracking & Participation
|
||||
- [ ] **P12-11** Component version registry API
|
||||
- FastAPI service for version queries
|
||||
- Compatibility checks via API
|
||||
- Update notifications
|
||||
- Usage statistics (opt-in)
|
||||
- [ ] **P12-12** Participative development workflow
|
||||
- Issue templates with device fingerprint
|
||||
- Feature request with profile context
|
||||
- Automated testing matrix based on device reports
|
||||
- Community board support voting
|
||||
|
||||
### Profile Definitions
|
||||
```yaml
|
||||
# profiles/tier-lite/profile.yaml
|
||||
name: tier-lite
|
||||
inherits: base
|
||||
description: Constrained devices (≤1GB RAM, ≤2 cores)
|
||||
constraints:
|
||||
max_memory: 1G
|
||||
max_cores: 2
|
||||
max_storage: 8G
|
||||
components:
|
||||
exclude:
|
||||
- secubox-ollama # Too heavy
|
||||
- secubox-jellyfin # Needs GPU
|
||||
optimize:
|
||||
- secubox-crowdsec: --no-hub-download
|
||||
- secubox-nginx: --worker-processes 1
|
||||
tweaks:
|
||||
kernel:
|
||||
vm.swappiness: 10
|
||||
vm.dirty_ratio: 20
|
||||
systemd:
|
||||
DefaultMemoryAccounting: yes
|
||||
DefaultTasksMax: 100
|
||||
```
|
||||
|
||||
### Board-Specific Tweaks
|
||||
```yaml
|
||||
# boards/espressobin-v7/tweaks.yaml
|
||||
board: espressobin-v7
|
||||
soc: Marvell Armada 3720
|
||||
profile: tier-lite
|
||||
capabilities:
|
||||
ram: 1GB
|
||||
cores: 2
|
||||
storage: eMMC 8GB
|
||||
network:
|
||||
- wan: eth0
|
||||
- lan: lan0, lan1
|
||||
usb: 1x USB 3.0, 1x USB 2.0
|
||||
tweaks:
|
||||
kernel_modules:
|
||||
blacklist: [bluetooth, btusb] # No BT hardware
|
||||
device_tree:
|
||||
overlay: espressobin-v7-secubox.dtbo
|
||||
network:
|
||||
default_mode: router
|
||||
wan_interface: eth0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **Reference**: See [REMAINING-PACKAGES.md](REMAINING-PACKAGES.md) for detailed inventory with complexity classification
|
||||
|
|
|
|||
591
docs/architecture/profile-generator.md
Normal file
591
docs/architecture/profile-generator.md
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
# SecuBox Profile Generator — Architecture
|
||||
|
||||
**Status** : Draft v0.2 — aligné sur ROADMAP PHASE 12
|
||||
**Cible** : SecuBox-Deb v1.5+, ANSSI CSPN 2027, Campagne 1 Ulule (4 juin 2026)
|
||||
**Auteurs** : Gandalf (CyberMind)
|
||||
**Repo cible** : `CyberMind-FR/secubox-deb` → `docs/architecture/profile-generator.md`
|
||||
|
||||
**Changelog**
|
||||
- v0.2 (2026-04-29) : Aligné sur PHASE 12 du ROADMAP. CLI éclatée en 3 outils
|
||||
(`secubox-gen` / `secubox-build` / `secubox-fetch`). Ajout §10 (registry +
|
||||
participation), §11 (scope MVP). Cross-walk P12-XX intégré.
|
||||
- v0.1 (2026-04-29) : Squelette initial.
|
||||
|
||||
---
|
||||
|
||||
## 0. Décisions ouvertes (à trancher avant figeage)
|
||||
|
||||
| # | Décision | Options | Recommandation provisoire | Bloque |
|
||||
|---|----------|---------|---------------------------|--------|
|
||||
| D1 | Sémantique d'héritage `inherits:` | Merge récursif simple / Typé strict NixOS-like / Hybride | Hybride : merge récursif + schema typé sur clés CSPN-critiques | P12-01 |
|
||||
| D2 | Modules canoniques (AUTH/…/MESH) dans le moteur | Axe orthogonal résolu / Narratif & graphique uniquement | Axe orthogonal résolu | P12-01 |
|
||||
| D3 | Langage des CLI | Python 3.11+ / Go / mixte | Python pour `secubox-gen` (logique riche) ; Go envisageable pour `secubox-fetch` (binaire portable) | P12-04/05/06 |
|
||||
| D4 | Performance profiles board (idle/normal/busy/stressed) | Build-time presets / Runtime adaptive (`tuned-adm` style) | Runtime adaptive → service ROOT, sort du périmètre P12 | P12-02 |
|
||||
| D5 | Flavors orthogonaux (stage/locale/persona) | MVP minimal (stage seul) / Tous dès v2.0.0 | MVP : `stage` seul. Locale + persona en v2.1 | P12-01 |
|
||||
| D6 | Migration in-place vs reflash | Reflash systématique / apt-bundle in-place avec PARAMETERS 4R | apt-bundle pour MINOR/PATCH ; reflash pour MAJOR | hors P12, PHASE 14 |
|
||||
| D7 | Secrets dans profils | Refs externes uniquement / SOPS / age | age + refs externes, jamais en clair | P12-01 |
|
||||
| D8 | Audit CSPN du moteur lui-même | In-scope / Out-of-scope (outil de build) | Out-of-scope, mais sortie auditée (lockfile signé) | hors P12 |
|
||||
|
||||
---
|
||||
|
||||
## 1. Hiérarchie des profils (Gigogne / Nested)
|
||||
|
||||
> **Mapping ROADMAP** : P12-01 (hiérarchie), P12-02 (boards)
|
||||
|
||||
```
|
||||
profiles/
|
||||
├── base/ # Core SecuBox (tous devices)
|
||||
│ ├── profile.yaml # Configuration de base
|
||||
│ └── services/ # Services minimaux
|
||||
├── tier-lite/ # Devices contraints (≤1GB RAM, ≤2 cores)
|
||||
│ ├── profile.yaml # inherits: base
|
||||
│ └── tweaks/ # Optimisations mémoire/CPU
|
||||
├── tier-standard/ # Devices standards (RPi4, VM)
|
||||
│ ├── profile.yaml # inherits: tier-lite
|
||||
│ └── services/ # Set complet de services
|
||||
├── tier-pro/ # Haute performance (MOCHAbin, bare metal)
|
||||
│ ├── profile.yaml # inherits: tier-standard
|
||||
│ └── features/ # Features avancées
|
||||
├── boards/ # Tweaks hardware-specific (P12-02)
|
||||
│ ├── rpi-zero-w/
|
||||
│ │ ├── tweaks.yaml # USB OTG, memory limits
|
||||
│ │ └── dts/ # Device tree overlays
|
||||
│ ├── espressobin-v7/
|
||||
│ ├── mochabin/
|
||||
│ └── vm-x64/
|
||||
├── modules/ # Modules canoniques transverses (D2)
|
||||
│ ├── auth/ # NIZK + G rotate 24h (L1 ZKP)
|
||||
│ ├── wall/ # nftables + CrowdSec
|
||||
│ ├── boot/ # secure boot, LUKS
|
||||
│ ├── mind/ # nDPId, mitmproxy bridge (L2 partiel)
|
||||
│ ├── root/ # base system, kernel, perf profiles
|
||||
│ └── mesh/ # WireGuard, Tailscale, MirrorNet (L3)
|
||||
└── flavors/ # Axes orthogonaux (D5, MVP = stage seul)
|
||||
└── stage/ # dev / staging / cspn-frozen
|
||||
# locale/ → v2.1
|
||||
# persona/ → v2.1
|
||||
```
|
||||
|
||||
**Principe directeur** : un build = `tier × board × {flavors}` aplati en un
|
||||
manifest unique versionné via lockfile. `modules/<name>/levels.yaml` expanse
|
||||
les niveaux d'activation (`disabled`/`minimal`/`standard`/`full`) en
|
||||
listes de paquets et configs.
|
||||
|
||||
**Auto-sélection (P12-01)** : `secubox-gen --auto` détecte le board
|
||||
(`/proc/device-tree/model`, DMI, etc.), mesure RAM/CPU/storage, propose un
|
||||
`tier` minimal et liste les `boards/<id>/tweaks.yaml` compatibles.
|
||||
|
||||
---
|
||||
|
||||
## 2. Sémantique d'héritage et résolution
|
||||
|
||||
> **Mapping ROADMAP** : implicite dans P12-01 (`inherits:`) — à préciser.
|
||||
|
||||
### 2.1 Modèle hybride proposé (D1)
|
||||
|
||||
Chaque clé d'un `profile.yaml` est typée par le **schema central**
|
||||
(`schema/profile.schema.json`) qui déclare son **mode de combinaison** via
|
||||
l'extension `x-secubox-merge:` :
|
||||
|
||||
| Mode | Sémantique | Exemple de clé |
|
||||
|------|------------|----------------|
|
||||
| `replace` | Le fils écrase le parent (default scalar) | `system.hostname` |
|
||||
| `merge` | Merge récursif clé à clé (default object) | `services.config` |
|
||||
| `union` | Union de listes, dédupliquée | `packages.install` |
|
||||
| `intersect` | Intersection (le fils restreint) | `kernel.modules.allowed` |
|
||||
| `frozen` | Le fils ne peut PAS modifier (CSPN) | `auth.zkp.curve`, `auth.zkp.rotation_hours` |
|
||||
| `additive` | Append uniquement, jamais retirer | `audit.rules` |
|
||||
|
||||
**Pour MVP** (P12-01 v2.0.0) : on peut shipper avec `replace`/`merge`/`union`
|
||||
uniquement, et ajouter `frozen`/`intersect`/`additive` en v2.1 quand le
|
||||
durcissement CSPN devient prioritaire. Cette dette est acceptable si elle est
|
||||
explicitement tracée.
|
||||
|
||||
### 2.2 Ordre de résolution (precedence)
|
||||
|
||||
```
|
||||
base
|
||||
→ tier-{lite|standard|pro}
|
||||
→ board-{rpi-zero-w|espressobin-v7|mochabin|vm-x64}
|
||||
→ modules.{auth,wall,boot,mind,root,mesh}.activation
|
||||
→ flavors.stage={dev|staging|cspn-frozen}
|
||||
→ CLI override (ex: --enable crowdsec,wireguard --tweak low-memory)
|
||||
```
|
||||
|
||||
Le dernier en lice gagne, sous réserve des contraintes `frozen`/`intersect`.
|
||||
|
||||
### 2.3 Détection de violations
|
||||
|
||||
Le résolveur DOIT échouer (build break) si :
|
||||
- Un fils tente de modifier une clé `frozen` héritée
|
||||
- Une clé `intersect` produit un ensemble vide
|
||||
- Le board déclare des `capabilities` incompatibles avec le `tier` (ex.
|
||||
`tier-pro` sur `espressobin-v7` 1GB RAM)
|
||||
- Un composant `requires:` un autre composant absent ou en conflit (P12-03)
|
||||
|
||||
### 2.4 Versionnage des composants (P12-03)
|
||||
|
||||
Format de version SecuBox : `<upstream>-sb<N>` (ex. `1.7.7-sb3`).
|
||||
|
||||
```yaml
|
||||
# components/secubox-crowdsec/component-version.yaml
|
||||
name: secubox-crowdsec
|
||||
version: 1.7.7-sb3
|
||||
upstream_version: 1.7.7
|
||||
secubox_patch_level: 3
|
||||
tags: [security, ids, optional]
|
||||
compatibility:
|
||||
min_memory: 512M
|
||||
min_cores: 1
|
||||
requires: [secubox-nftables]
|
||||
conflicts: [secubox-suricata]
|
||||
modules: [wall] # ownership module canonique
|
||||
cspn_sensitivity: info # none | info | eal2 | eal4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Modules canoniques et niveaux d'activation
|
||||
|
||||
> **Mapping ROADMAP** : à ajouter à PHASE 12 (absent du roadmap actuel — D2).
|
||||
|
||||
### 3.1 Mapping aux 6 modules SecuBox
|
||||
|
||||
| Module | Couleur Light 3 | Couche ZKP | Responsabilité |
|
||||
|--------|-----------------|------------|----------------|
|
||||
| AUTH | `#C04E24` | L1 | NIZK Hamiltonian, G rotation 24h, PFS |
|
||||
| WALL | `#9A6010` | — | nftables, CrowdSec, rate limiting |
|
||||
| BOOT | `#803018` | — | secure boot, LUKS, dm-verity |
|
||||
| MIND | `#3D35A0` | L2 (partiel) | nDPId, mitmproxy bridge, DPI dual-stream |
|
||||
| ROOT | `#0A5840` | — | base Debian, kernel, systemd, perf profiles |
|
||||
| MESH | `#104A88` | L3 | WireGuard, Tailscale, MirrorNet, did:plc |
|
||||
|
||||
### 3.2 Niveaux d'activation par profil-tier
|
||||
|
||||
```yaml
|
||||
# tier-lite/profile.yaml
|
||||
modules:
|
||||
auth: minimal # NIZK only, pas de HamCoin
|
||||
wall: standard
|
||||
boot: minimal # LUKS optionnel
|
||||
mind: disabled # pas de DPI sur ressources contraintes
|
||||
root: minimal
|
||||
mesh: minimal # WireGuard seul, pas de MirrorNet
|
||||
```
|
||||
|
||||
`modules/<name>/levels.yaml` définit ce que chaque niveau expanse en
|
||||
paquets/services/configs.
|
||||
|
||||
### 3.3 Hamiltonian path comme contrainte fonctionnelle
|
||||
|
||||
Le chemin canonique `AUTH→WALL→BOOT→MIND→ROOT→MESH` (charte SPIRITUALCEPT)
|
||||
sert à deux usages dans le moteur :
|
||||
1. **Ordre de boot/reload des services** au runtime
|
||||
2. **Rétrogradation automatique** : si un module amont est `disabled`, les
|
||||
modules aval qui en dépendent sont automatiquement rétrogradés
|
||||
(`full` → `standard` → `minimal`)
|
||||
|
||||
À débattre (cf. v0.1 §3 commentaire) : si trop ésotérique pour un dev
|
||||
extérieur, retomber sur un simple DAG de dépendances explicite. La charte
|
||||
graphique reste cohérente même sans contrainte fonctionnelle adossée.
|
||||
|
||||
---
|
||||
|
||||
## 4. Toolchain — Trois CLI Unix-style
|
||||
|
||||
> **Mapping ROADMAP** : P12-04 (`secubox-gen`), P12-05 (`secubox-build`),
|
||||
> P12-06 (`secubox-fetch`)
|
||||
|
||||
Découpage en 3 outils suivant la philosophie « do one thing well ». Chacun
|
||||
consomme/produit des fichiers texte versionnables (YAML, lock).
|
||||
|
||||
### 4.1 `secubox-gen` — Manifest generator (P12-04)
|
||||
|
||||
Génère un `manifest.yaml` aplati à partir d'un choix profile + board + flavors
|
||||
+ overrides CLI.
|
||||
|
||||
```bash
|
||||
# Mode déclaratif
|
||||
secubox-gen \
|
||||
--profile tier-lite \
|
||||
--board espressobin-v7 \
|
||||
--enable crowdsec,wireguard \
|
||||
--tweak low-memory \
|
||||
--stage cspn-frozen \
|
||||
--output manifest.yaml
|
||||
|
||||
# Mode interactif avec auto-détection
|
||||
secubox-gen --auto
|
||||
|
||||
# Validation seule (pas de génération)
|
||||
secubox-gen --validate --profile tier-pro --board mochabin
|
||||
|
||||
# Diff entre deux manifests
|
||||
secubox-gen diff old.yaml new.yaml
|
||||
```
|
||||
|
||||
**Responsabilités** :
|
||||
- Charge profils + flavors + board tweaks
|
||||
- Résout l'héritage (§2)
|
||||
- Vérifie contraintes (`frozen`, `intersect`, `requires`, `conflicts`)
|
||||
- Émet `manifest.yaml` aplati
|
||||
- Émet `secubox.lock` (§6) en parallèle
|
||||
|
||||
### 4.2 `secubox-build` — Image builder (P12-05)
|
||||
|
||||
Consomme un `manifest.yaml` + `secubox.lock` et produit un artefact bootable.
|
||||
|
||||
```bash
|
||||
secubox-build \
|
||||
--manifest manifest.yaml \
|
||||
--lock secubox.lock \
|
||||
--format iso-live \ # iso-live | debootstrap | chroot-tar | qcow2 | apt-bundle
|
||||
--output secubox-mochabin-1.5.3.iso
|
||||
|
||||
# Build incrémental depuis cache
|
||||
secubox-build --manifest manifest.yaml --incremental --cache /var/cache/secubox-build
|
||||
```
|
||||
|
||||
**Responsabilités** :
|
||||
- Build reproductible bit-pour-bit (modulo timestamps signés)
|
||||
- Multi-stage avec checkpoints (P12-05) → reprise si échec
|
||||
- Cache de couches debootstrap / chroot
|
||||
- Signature GPG de l'artefact final
|
||||
|
||||
**Formats de sortie** :
|
||||
|
||||
| Format | Cas d'usage | Backend |
|
||||
|--------|-------------|---------|
|
||||
| `iso-live` | Démo, install bare metal, démo Ulule | live-build |
|
||||
| `debootstrap` | Provisioning client | debootstrap + post-install hooks |
|
||||
| `chroot-tar` | CI/CD, tests | tar.zst d'un chroot |
|
||||
| `qcow2` | VM, dev | virt-builder |
|
||||
| `apt-bundle` | Upgrade in-place via `apt.secubox.in` | apt repo metadata |
|
||||
|
||||
### 4.3 `secubox-fetch` — Pre-built downloader (P12-06)
|
||||
|
||||
Pour les clients qui ne buildent pas eux-mêmes (cas dominant attendu post-Ulule).
|
||||
|
||||
```bash
|
||||
# Liste des images disponibles pour un board
|
||||
secubox-fetch list --board mochabin
|
||||
|
||||
# Téléchargement avec vérification automatique
|
||||
secubox-fetch download \
|
||||
--board mochabin \
|
||||
--version 1.5.3 \
|
||||
--tier pro \
|
||||
--output ~/Downloads/
|
||||
|
||||
# Vérification GPG + SHA256 d'une image locale
|
||||
secubox-fetch verify secubox-mochabin-1.5.3.iso
|
||||
```
|
||||
|
||||
**Responsabilités** :
|
||||
- Catalogue les releases GitHub `CyberMind-FR/secubox-deb`
|
||||
- Vérifie signature GPG (clé CyberMind release)
|
||||
- Vérifie SHA256 publié dans la release
|
||||
- Match automatique des versions selon hardware détecté
|
||||
|
||||
**Note D3** : `secubox-fetch` est un bon candidat pour Go (binaire unique
|
||||
portable, exécutable sur Mac/Win sans Python). À trancher en T-1 sprint.
|
||||
|
||||
---
|
||||
|
||||
## 5. Validation de schéma et CI gates
|
||||
|
||||
> **Mapping ROADMAP** : à ajouter à PHASE 12 ou en transverse.
|
||||
|
||||
### 5.1 JSON Schema central
|
||||
|
||||
`schema/profile.schema.json` (Draft 2020-12) déclare :
|
||||
- Toutes les clés autorisées
|
||||
- Le type de chacune
|
||||
- Le **mode de combinaison** (`x-secubox-merge`)
|
||||
- Le **module owner** (AUTH/WALL/BOOT/MIND/ROOT/MESH)
|
||||
- La **CSPN sensitivity** (none/info/eal2/eal4)
|
||||
|
||||
### 5.2 CI gates (3 niveaux)
|
||||
|
||||
1. **Lint** (chaque PR) : YAML valide + JSON Schema OK + lint des
|
||||
`component-version.yaml`
|
||||
2. **Resolve** (chaque PR) : aplatissement réussit pour la matrice canonique
|
||||
`{lite,standard,pro} × {rpi-zero-w,espressobin-v7,mochabin,vm-x64}` (avec
|
||||
exclusions cohérentes : pas de `pro × rpi-zero-w`)
|
||||
3. **Build smoke** (nightly) : ISO live boot test sur QEMU pour
|
||||
`tier-standard/vm-x64` ; au moins un boot test hardware réel par release
|
||||
sur MOCHAbin
|
||||
|
||||
### 5.3 Audit CSPN
|
||||
|
||||
Pour chaque release `stage=cspn-frozen`, génération automatique d'un rapport :
|
||||
- Diff vs. dernier profil certifié
|
||||
- Liste des clés `frozen` touchées (DOIT être vide)
|
||||
- Empreinte SHA-256 du profil aplati canonique
|
||||
- Liste des composants avec `cspn_sensitivity >= eal2`
|
||||
|
||||
---
|
||||
|
||||
## 6. Lockfile et fingerprint
|
||||
|
||||
> **Mapping ROADMAP** : P12-08 (manifest JSON pour bug reports — fusionné ici)
|
||||
|
||||
### 6.1 Format `secubox.lock`
|
||||
|
||||
Le lockfile sert simultanément à :
|
||||
- **Reproductibilité** des builds
|
||||
- **Audit CSPN** (empreinte du profil)
|
||||
- **Bug reports** (P12-08, exporté en JSON pour automation)
|
||||
- **Update notifications** (P12-11, comparaison avec registry)
|
||||
|
||||
```yaml
|
||||
schema_version: 1
|
||||
generated_at: 2026-04-29T10:23:00Z
|
||||
profile_source:
|
||||
tier: pro
|
||||
board: mochabin
|
||||
flavors: { stage: cspn-frozen }
|
||||
git_ref: v1.5.3
|
||||
profile_hash: sha256:a1b2...
|
||||
resolved_hash: sha256:c3d4... # = "version fingerprint" P12-08
|
||||
fingerprint_short: c3d4e5f6 # 8 hex chars, pour bug reports lisibles
|
||||
packages:
|
||||
- name: secubox-crowdsec
|
||||
version: 1.7.7-sb3
|
||||
upstream: 1.7.7
|
||||
sha256: ...
|
||||
- name: secubox-nftables
|
||||
version: 1.0.6-sb1
|
||||
sha256: ...
|
||||
modules_activation:
|
||||
auth: full
|
||||
wall: full
|
||||
boot: standard
|
||||
mind: standard
|
||||
root: standard
|
||||
mesh: full
|
||||
hamiltonian_path_check: passed
|
||||
cspn_audit:
|
||||
frozen_keys_modified: []
|
||||
sensitivity_changes: []
|
||||
hardware_capabilities: # snapshot pour bug reports
|
||||
ram_mb: 8192
|
||||
cores: 4
|
||||
storage_gb: 32
|
||||
detected_board: mochabin
|
||||
```
|
||||
|
||||
### 6.2 Export JSON pour automation (P12-08)
|
||||
|
||||
```bash
|
||||
secubox-gen export-lock secubox.lock --format json --output report.json
|
||||
```
|
||||
|
||||
Utilisé par les templates d'issues GitHub (P12-12) pour donner aux mainteneurs
|
||||
un contexte machine-readable sans exposer de secrets.
|
||||
|
||||
### 6.3 Politique de versionnage
|
||||
|
||||
| Niveau | Quand bumper | Stratégie de migration |
|
||||
|--------|--------------|------------------------|
|
||||
| `schema_version` | Format de profil incompatible | Migration script obligatoire |
|
||||
| `profile MAJOR` | Changement frozen (re-CSPN) | Reflash recommandé |
|
||||
| `profile MINOR` | Ajout module/feature | apt-bundle in-place |
|
||||
| `profile PATCH` | Bugfix, package bump | apt-bundle in-place automatique |
|
||||
|
||||
---
|
||||
|
||||
## 7. README appliance auto-généré
|
||||
|
||||
> **Mapping ROADMAP** : P12-07
|
||||
|
||||
À chaque build, `secubox-build` produit un `APPLIANCE-README.md` embarqué dans
|
||||
l'image (`/etc/secubox/APPLIANCE-README.md`) et publié à côté de l'artefact.
|
||||
|
||||
Contenu :
|
||||
- Hardware profile résolu (board, tier, capabilities)
|
||||
- Tableau des composants avec versions et statuts
|
||||
- Tweaks appliqués (kernel, systemd, network)
|
||||
- Modules activés et niveau (avec couleurs Light 3 en HTML companion)
|
||||
- Empreinte courte (`fingerprint_short`) pour support
|
||||
- Liens : doc support, issue tracker, registry status
|
||||
|
||||
Format : Markdown + variante HTML (charte SPIRITUALCEPT·PRINT, light bg, pas
|
||||
de noir).
|
||||
|
||||
---
|
||||
|
||||
## 8. Stratégie de migration entre profils
|
||||
|
||||
> **Mapping ROADMAP** : absent — proposition pour PHASE 14.
|
||||
|
||||
### 8.1 Cas d'usage
|
||||
|
||||
| Scénario | Stratégie | Outil |
|
||||
|----------|-----------|-------|
|
||||
| Patch (1.5.2→1.5.3) | apt upgrade + config refresh | `secubox-update` (PHASE 14) |
|
||||
| Minor (1.5→1.6) | apt-bundle + module activation diff | `secubox-update --plan` |
|
||||
| Major (1.x→2.0) | Reflash recommandé (frozen touché) | `secubox-fetch` puis flash |
|
||||
| Tier change (lite→standard) | Reflash obligatoire | `secubox-fetch` puis flash |
|
||||
|
||||
### 8.2 Procédure `secubox-update` (PHASE 14)
|
||||
|
||||
```
|
||||
[device]
|
||||
↓ fetch nouveau lock (secubox-fetch)
|
||||
[apt.secubox.in]
|
||||
↓ diff avec lock local
|
||||
[plan] ← humain valide
|
||||
↓ apt + config rendering
|
||||
[reload services par module] ← ordre Hamiltonian inverse
|
||||
[health check par module]
|
||||
↓ ok ?
|
||||
[swap PARAMETERS double-buffer 4R] ← mécanisme existant
|
||||
```
|
||||
|
||||
### 8.3 Rollback
|
||||
|
||||
Le mécanisme PARAMETERS double-buffer 4R existant couvre le rollback :
|
||||
- Buffer A = lock courant
|
||||
- Buffer B = lock précédent
|
||||
- Swap atomique en cas d'échec health check
|
||||
|
||||
---
|
||||
|
||||
## 9. Intégration CI/CD
|
||||
|
||||
> **Mapping ROADMAP** : transverse, pas un ticket P12 dédié.
|
||||
|
||||
### 9.1 Pipeline existant comme vue dérivée
|
||||
|
||||
Le pipeline actuel (10 phases / 93 paquets) devient une **vue dérivée du
|
||||
moteur** : chaque phase porte un tag `min_tier:` et `module:` qui détermine
|
||||
son inclusion dans un build donné.
|
||||
|
||||
```
|
||||
profil → secubox-gen → manifest → liste de phases activées → exécution
|
||||
```
|
||||
|
||||
### 9.2 GitHub Actions (esquisse)
|
||||
|
||||
```yaml
|
||||
name: profile-build
|
||||
on: [pull_request, push]
|
||||
jobs:
|
||||
validate:
|
||||
strategy:
|
||||
matrix:
|
||||
tier: [lite, standard, pro]
|
||||
board: [rpi-zero-w, espressobin-v7, mochabin, vm-x64]
|
||||
exclude:
|
||||
- { tier: pro, board: rpi-zero-w }
|
||||
- { tier: pro, board: espressobin-v7 }
|
||||
steps:
|
||||
- run: secubox-gen --validate --profile ${{ matrix.tier }} --board ${{ matrix.board }}
|
||||
build-smoke:
|
||||
needs: validate
|
||||
if: github.event_name == 'schedule'
|
||||
steps:
|
||||
- run: secubox-build --format iso-live --manifest <(secubox-gen --profile standard --board vm-x64)
|
||||
- run: qemu-system-x86_64 -boot d -cdrom out.iso -m 2048 ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Registry API et participation communautaire
|
||||
|
||||
> **Mapping ROADMAP** : P12-11 (registry API), P12-12 (participation)
|
||||
|
||||
### 10.1 Registry API FastAPI (P12-11)
|
||||
|
||||
Service `registry.secubox.in` (FastAPI, cohérent avec stack existant) exposant :
|
||||
|
||||
| Endpoint | Méthode | Usage |
|
||||
|----------|---------|-------|
|
||||
| `/components` | GET | Liste des composants disponibles avec versions |
|
||||
| `/components/{name}/compat` | POST | Check compatibilité (lock en input) |
|
||||
| `/profiles/{tier}/{board}` | GET | Profil canonique pré-résolu |
|
||||
| `/updates/notify` | POST | Subscribe (opt-in) aux notifs sécurité |
|
||||
| `/stats/usage` | POST | Stats d'usage opt-in (board + tier + version) |
|
||||
|
||||
**Privacy** : tout opt-in. Pas de fingerprint device sans consentement
|
||||
explicite. Conformité RGPD, hébergement EU.
|
||||
|
||||
### 10.2 Workflow de participation (P12-12)
|
||||
|
||||
- **Issue templates** GitHub avec champ `secubox-fingerprint:` auto-rempli
|
||||
via `secubox-gen export-lock --format json | jq .fingerprint_short`
|
||||
- **Feature requests** structurés avec contexte profil
|
||||
- **Matrix de tests automatisée** : un report d'install réussie par board
|
||||
alimente la liste des « boards supportés »
|
||||
- **Vote communautaire** sur les boards à supporter en priorité
|
||||
|
||||
---
|
||||
|
||||
## 11. Scope MVP et phasage
|
||||
|
||||
> **Question ouverte critique** : périmètre PHASE 12 vs Campagne 1 (4 juin 2026).
|
||||
|
||||
### 11.1 Risque identifié
|
||||
|
||||
PHASE 12 actuelle inclut **P12-09 (Electron/Tauri desktop app)** et
|
||||
**P12-10 (web-based generator)**. Ce sont deux livrables UI à part entière,
|
||||
chacun probablement aussi lourd que toute la fondation CLI/registry réunie.
|
||||
|
||||
**Si PHASE 12 livre les 12 tickets en bloc**, risque sérieux de glissement
|
||||
au-delà de la Campagne 1.
|
||||
|
||||
### 11.2 Proposition de phasage
|
||||
|
||||
| Phase | Tickets | Cible |
|
||||
|-------|---------|-------|
|
||||
| **PHASE 12 — Foundations** | P12-01 à P12-08, P12-11, P12-12 | Avril → Juin 2026 (Campagne 1) |
|
||||
| **PHASE 13 — Distribution UX** | P12-09 (Electron/Tauri), P12-10 (web) | Été 2026, post-Ulule |
|
||||
| **PHASE 14 — In-place Update** | `secubox-update`, PARAMETERS 4R intégration | Q3 2026 |
|
||||
|
||||
### 11.3 MVP critique pour Campagne 1
|
||||
|
||||
Pour démo Ulule, le minimum viable est :
|
||||
1. `secubox-gen` opérationnel sur 4 boards
|
||||
2. `secubox-build` produisant ISO live démontrable sur MOCHAbin
|
||||
3. `secubox-fetch` permettant aux backers « Le Sérieux » (690€) de récupérer
|
||||
leur image pré-buildée
|
||||
4. README appliance auto-généré dans l'image
|
||||
|
||||
Le reste (registry API, web app, Electron) peut suivre.
|
||||
|
||||
---
|
||||
|
||||
## 12. Ouverts pour la suite
|
||||
|
||||
- **Annexe A** : `schema/profile.schema.json` complet (Draft 2020-12)
|
||||
- **Annexe B** : Mapping détaillé des 93 paquets actuels → modules canoniques
|
||||
+ `min_tier` + `cspn_sensitivity`
|
||||
- **Annexe C** : Spec lockfile en JSON Schema + exemple JSON de bug report
|
||||
- **Annexe D** : `manifest.yaml` exemple complet pour
|
||||
`mochabin × tier-pro × stage=cspn-frozen` (à drafter ensuite, cf. proposition 3)
|
||||
- **Annexe E** : Audit CSPN du moteur lui-même (in-scope ou tooling externe ?)
|
||||
|
||||
---
|
||||
|
||||
## 13. Cross-walk PHASE 12 → §archi
|
||||
|
||||
| Ticket | Section principale | Sections complémentaires |
|
||||
|--------|---------------------|--------------------------|
|
||||
| P12-01 Profile hierarchy | §1 | §2 (héritage), §5 (validation) |
|
||||
| P12-02 Board tweaks | §1 (`boards/`) | D4 (perf profiles) |
|
||||
| P12-03 Component versioning | §2.4 | §6 (lockfile) |
|
||||
| P12-04 `secubox-gen` | §4.1 | §6 (émet lock) |
|
||||
| P12-05 `secubox-build` | §4.2 | §7 (README), §9 (CI) |
|
||||
| P12-06 `secubox-fetch` | §4.3 | §8 (reflash path) |
|
||||
| P12-07 Appliance README | §7 | §6 (fingerprint) |
|
||||
| P12-08 Manifest JSON bug reports | §6.2 | §10.2 (issue templates) |
|
||||
| P12-09 Electron/Tauri app | **PHASE 13** | hors §archi v0.2 |
|
||||
| P12-10 Web generator | **PHASE 13** | hors §archi v0.2 |
|
||||
| P12-11 Registry API | §10.1 | §6 (compat checks) |
|
||||
| P12-12 Participative workflow | §10.2 | §6.2 (fingerprint) |
|
||||
|
||||
---
|
||||
|
||||
*Fin du squelette v0.2. Prochaine itération suggérée : Annexe D (manifest
|
||||
exemple complet) puis Annexe A (JSON Schema).*
|
||||
|
|
@ -12,9 +12,9 @@ REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
|||
# ── Defaults ──────────────────────────────────────────────────────
|
||||
BOARD="mochabin"
|
||||
SUITE="bookworm"
|
||||
IMG_SIZE="4G" # Taille de l'image totale
|
||||
ROOT_SIZE="2.5G" # Taille partition rootfs
|
||||
DATA_SIZE="1G" # Taille partition data
|
||||
IMG_SIZE="8G" # Taille de l'image totale (increased for full install)
|
||||
ROOT_SIZE="5.5G" # Taille partition rootfs (needs ~4GB for full install)
|
||||
DATA_SIZE="2G" # Taille partition data
|
||||
OUT_DIR="${REPO_DIR}/output"
|
||||
KEEP_ROOTFS=0
|
||||
APT_MIRROR="http://deb.debian.org/debian"
|
||||
|
|
@ -870,6 +870,49 @@ EOF
|
|||
chroot "${ROOTFS}" systemctl enable secubox-firstboot.service
|
||||
ok "firstboot.sh installé"
|
||||
|
||||
# Enable kiosk service for x64/VM builds (GUI mode by default)
|
||||
if [[ $IS_X64 -eq 1 ]] || [[ "${BOARD}" == "vm-arm64" ]]; then
|
||||
# Copy kiosk service and launcher
|
||||
if [[ -f "${SCRIPT_DIR}/systemd/secubox-kiosk.service" ]]; then
|
||||
cp "${SCRIPT_DIR}/systemd/secubox-kiosk.service" "${ROOTFS}/etc/systemd/system/"
|
||||
fi
|
||||
if [[ -f "${SCRIPT_DIR}/sbin/secubox-kiosk-launcher" ]]; then
|
||||
cp "${SCRIPT_DIR}/sbin/secubox-kiosk-launcher" "${ROOTFS}/usr/sbin/"
|
||||
chmod +x "${ROOTFS}/usr/sbin/secubox-kiosk-launcher"
|
||||
fi
|
||||
if [[ -f "${SCRIPT_DIR}/sbin/secubox-kiosk-setup" ]]; then
|
||||
cp "${SCRIPT_DIR}/sbin/secubox-kiosk-setup" "${ROOTFS}/usr/sbin/"
|
||||
chmod +x "${ROOTFS}/usr/sbin/secubox-kiosk-setup"
|
||||
fi
|
||||
if [[ -f "${SCRIPT_DIR}/sbin/secubox-cmdline-handler" ]]; then
|
||||
cp "${SCRIPT_DIR}/sbin/secubox-cmdline-handler" "${ROOTFS}/usr/sbin/"
|
||||
chmod +x "${ROOTFS}/usr/sbin/secubox-cmdline-handler"
|
||||
fi
|
||||
if [[ -f "${SCRIPT_DIR}/sbin/secubox-mode" ]]; then
|
||||
cp "${SCRIPT_DIR}/sbin/secubox-mode" "${ROOTFS}/usr/sbin/"
|
||||
chmod +x "${ROOTFS}/usr/sbin/secubox-mode"
|
||||
fi
|
||||
|
||||
# Enable kiosk service and set graphical target
|
||||
chroot "${ROOTFS}" systemctl enable secubox-kiosk.service 2>/dev/null || true
|
||||
chroot "${ROOTFS}" systemctl set-default graphical.target 2>/dev/null || true
|
||||
|
||||
# Disable getty on tty1 (kiosk uses VT7, console access via tty2)
|
||||
chroot "${ROOTFS}" systemctl disable getty@tty1.service 2>/dev/null || true
|
||||
|
||||
# Enable autologin on tty2 for emergency access
|
||||
mkdir -p "${ROOTFS}/etc/systemd/system/getty@tty2.service.d"
|
||||
cat > "${ROOTFS}/etc/systemd/system/getty@tty2.service.d/autologin.conf" <<'AUTOLOGIN'
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty --autologin root --noclear %I $TERM
|
||||
Type=idle
|
||||
AUTOLOGIN
|
||||
chroot "${ROOTFS}" systemctl enable getty@tty2.service 2>/dev/null || true
|
||||
|
||||
ok "Kiosk service installed and enabled (graphical.target, TTY2 autologin)"
|
||||
fi
|
||||
|
||||
# ── Pre-generate SSL certificates for nginx ─────────────────────────
|
||||
# (firstboot will regenerate on first boot, but nginx needs certs to start)
|
||||
# Generate certs on HOST (chroot may lack /dev/urandom)
|
||||
|
|
@ -1169,14 +1212,90 @@ log "5/7 Configuration bootloader..."
|
|||
if [[ $IS_X64 -eq 1 ]] || [[ "${BOARD}" == "vm-arm64" ]]; then
|
||||
# GRUB EFI pour x64 ou arm64 VM
|
||||
cat > "${ROOTFS}/etc/default/grub" <<'EOF'
|
||||
GRUB_DEFAULT=0
|
||||
GRUB_TIMEOUT=3
|
||||
GRUB_DEFAULT="secubox-kiosk"
|
||||
GRUB_TIMEOUT=5
|
||||
GRUB_DISTRIBUTOR="SecuBox"
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet net.ifnames=1"
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet net.ifnames=1 secubox.mode=kiosk secubox.kiosk=1"
|
||||
GRUB_CMDLINE_LINUX=""
|
||||
GRUB_TERMINAL=console
|
||||
GRUB_DISABLE_OS_PROBER=true
|
||||
GRUB_DISABLE_SUBMENU=true
|
||||
EOF
|
||||
ok "GRUB configuré"
|
||||
|
||||
# Create custom GRUB menu with boot modes (40_custom)
|
||||
# This script generates menu entries dynamically based on available kernels
|
||||
cat > "${ROOTFS}/etc/grub.d/40_custom" <<'GRUBCUSTOM'
|
||||
#!/bin/sh
|
||||
exec tail -n +3 $0
|
||||
# Custom SecuBox boot menu entries will be generated by 41_secubox
|
||||
GRUBCUSTOM
|
||||
chmod +x "${ROOTFS}/etc/grub.d/40_custom"
|
||||
|
||||
# Create 41_secubox which generates proper menu entries
|
||||
cat > "${ROOTFS}/etc/grub.d/41_secubox" <<'GRUB41'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Find the latest kernel
|
||||
KVER=$(ls /boot/vmlinuz-* 2>/dev/null | sort -V | tail -1 | sed 's|/boot/vmlinuz-||')
|
||||
if [ -z "$KVER" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get root UUID
|
||||
ROOT_UUID=$(blkid -s UUID -o value /dev/disk/by-label/rootfs 2>/dev/null || echo "")
|
||||
if [ -z "$ROOT_UUID" ]; then
|
||||
ROOT_DEV="root=LABEL=rootfs"
|
||||
else
|
||||
ROOT_DEV="root=UUID=$ROOT_UUID"
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════
|
||||
# SecuBox Boot Menu
|
||||
# ══════════════════════════════════════════════════════════════════
|
||||
|
||||
menuentry "SecuBox (Kiosk Mode)" --class secubox --class debian --class os \$menuentry_id_option 'secubox-kiosk' {
|
||||
load_video
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod ext2
|
||||
search --no-floppy --label rootfs --set=root
|
||||
linux /boot/vmlinuz-${KVER} ${ROOT_DEV} ro quiet splash secubox.mode=kiosk secubox.kiosk=1 net.ifnames=1
|
||||
initrd /boot/initrd.img-${KVER}
|
||||
}
|
||||
|
||||
menuentry "SecuBox (Console Mode)" --class secubox --class debian --class os \$menuentry_id_option 'secubox-console' {
|
||||
load_video
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod ext2
|
||||
search --no-floppy --label rootfs --set=root
|
||||
linux /boot/vmlinuz-${KVER} ${ROOT_DEV} ro secubox.mode=console net.ifnames=1
|
||||
initrd /boot/initrd.img-${KVER}
|
||||
}
|
||||
|
||||
menuentry "SecuBox (Recovery - Single User)" --class secubox --class debian --class os \$menuentry_id_option 'secubox-recovery' {
|
||||
load_video
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod ext2
|
||||
search --no-floppy --label rootfs --set=root
|
||||
linux /boot/vmlinuz-${KVER} ${ROOT_DEV} ro single net.ifnames=1
|
||||
initrd /boot/initrd.img-${KVER}
|
||||
}
|
||||
EOF
|
||||
GRUB41
|
||||
chmod +x "${ROOTFS}/etc/grub.d/41_secubox"
|
||||
|
||||
# Enable kiosk mode by default (create marker files)
|
||||
mkdir -p "${ROOTFS}/var/lib/secubox"
|
||||
touch "${ROOTFS}/var/lib/secubox/.kiosk-enabled"
|
||||
echo "x11" > "${ROOTFS}/var/lib/secubox/.kiosk-mode"
|
||||
log " Kiosk mode enabled by default"
|
||||
|
||||
ok "GRUB configuré with SecuBox boot menu"
|
||||
else
|
||||
# U-Boot pour ARM hardware
|
||||
warn "U-Boot : kernel/DTB à placer dans board/${BOARD}/kernel/"
|
||||
|
|
@ -1195,20 +1314,22 @@ fallocate -l "${IMG_SIZE}" "${IMG_FILE}"
|
|||
|
||||
if [[ $IS_X64 -eq 1 ]] || [[ "${BOARD}" == "vm-arm64" ]]; then
|
||||
# GPT + ESP pour UEFI (x64 ou arm64 VM)
|
||||
# ESP: 512MB, ROOT: 5.5GB, DATA: remaining (~2GB)
|
||||
parted -s "${IMG_FILE}" \
|
||||
mklabel gpt \
|
||||
mkpart ESP fat32 1MiB 513MiB \
|
||||
mkpart ROOT ext4 513MiB 3073MiB \
|
||||
mkpart DATA ext4 3073MiB 100% \
|
||||
mkpart ROOT ext4 513MiB 6145MiB \
|
||||
mkpart DATA ext4 6145MiB 100% \
|
||||
set 1 esp on \
|
||||
set 1 boot on
|
||||
else
|
||||
# GPT pour ARM hardware (boot + rootfs + data)
|
||||
# boot: 256MB, ROOT: 5.5GB, DATA: remaining
|
||||
parted -s "${IMG_FILE}" \
|
||||
mklabel gpt \
|
||||
mkpart boot fat32 2MiB 258MiB \
|
||||
mkpart ROOT ext4 258MiB 2818MiB \
|
||||
mkpart DATA ext4 2818MiB 100% \
|
||||
mkpart ROOT ext4 258MiB 5890MiB \
|
||||
mkpart DATA ext4 5890MiB 100% \
|
||||
set 1 boot on
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ info() { echo -e "${BLUE}[info]${NC} $*"; }
|
|||
# Default WiFi (user can override)
|
||||
WIFI_SSID="${WIFI_SSID:-}"
|
||||
WIFI_PSK="${WIFI_PSK:-}"
|
||||
HOSTNAME="${HOSTNAME:-secubox-round}"
|
||||
HOSTNAME="${HOSTNAME:-eye-remote}"
|
||||
SSH_PUBKEY="${SSH_PUBKEY:-}"
|
||||
|
||||
# Source image
|
||||
|
|
@ -96,7 +96,7 @@ Options:
|
|||
-o, --output DIR Output directory (default: /tmp)
|
||||
-s, --ssid SSID WiFi SSID (optional)
|
||||
-p, --psk PSK WiFi password (optional)
|
||||
-h, --hostname NAME Hostname (default: secubox-round)
|
||||
-h, --hostname NAME Hostname (default: eye-remote)
|
||||
-k, --pubkey FILE SSH public key to install
|
||||
--browser Use Chromium kiosk mode (~250MB more)
|
||||
--framebuffer Use Python/PIL framebuffer (default, lightweight)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ DEVICE=""
|
|||
IMAGE=""
|
||||
SSID=""
|
||||
PSK=""
|
||||
HOSTNAME="secubox-round"
|
||||
HOSTNAME="eye-remote"
|
||||
USER="secubox"
|
||||
PUBKEY=""
|
||||
KIOSK=true
|
||||
|
|
|
|||
251
scripts/vbox-setup.sh
Normal file
251
scripts/vbox-setup.sh
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
#!/usr/bin/env bash
|
||||
# ══════════════════════════════════════════════════════════════════
|
||||
# SecuBox VirtualBox Setup Script
|
||||
# Downloads and configures SecuBox VM for VirtualBox
|
||||
# Usage: bash vbox-setup.sh [OPTIONS]
|
||||
# ══════════════════════════════════════════════════════════════════
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="1.0.0"
|
||||
VM_NAME="SecuBox"
|
||||
VM_MEMORY=2048
|
||||
VM_CPUS=2
|
||||
VM_VRAM=64
|
||||
GITHUB_REPO="CyberMind-FR/secubox-deb"
|
||||
VDI_FILE=""
|
||||
DOWNLOAD_URL=""
|
||||
NETWORK_MODE="bridged"
|
||||
BRIDGE_ADAPTER=""
|
||||
FORCE=0
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
CYAN='\033[0;36m'
|
||||
GOLD='\033[0;33m'
|
||||
NC='\033[0m'
|
||||
BOLD='\033[1m'
|
||||
|
||||
log() { echo -e "${CYAN}[secubox]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[ OK ]${NC} $*"; }
|
||||
err() { echo -e "${RED}[ERROR ]${NC} $*" >&2; exit 1; }
|
||||
warn() { echo -e "${GOLD}[ WARN ]${NC} $*"; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
${BOLD}SecuBox VirtualBox Setup${NC} v${VERSION}
|
||||
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Options:
|
||||
--vdi FILE Use existing VDI file instead of downloading
|
||||
--name NAME VM name (default: SecuBox)
|
||||
--memory MB RAM in MB (default: 2048)
|
||||
--cpus N CPU count (default: 2)
|
||||
--network MODE bridged|nat|hostonly (default: bridged)
|
||||
--bridge ADAPTER Bridge adapter name (auto-detected if omitted)
|
||||
--force Overwrite existing VM
|
||||
--version TAG Download specific version (default: latest)
|
||||
--help Show this help
|
||||
|
||||
Examples:
|
||||
$0 # Download latest and setup
|
||||
$0 --vdi secubox.vdi # Use existing VDI
|
||||
$0 --network nat --memory 4096 # NAT mode, 4GB RAM
|
||||
$0 --version v1.5.0 # Specific version
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--vdi) VDI_FILE="$2"; shift 2 ;;
|
||||
--name) VM_NAME="$2"; shift 2 ;;
|
||||
--memory) VM_MEMORY="$2"; shift 2 ;;
|
||||
--cpus) VM_CPUS="$2"; shift 2 ;;
|
||||
--network) NETWORK_MODE="$2"; shift 2 ;;
|
||||
--bridge) BRIDGE_ADAPTER="$2"; shift 2 ;;
|
||||
--force) FORCE=1; shift ;;
|
||||
--version) VERSION_TAG="$2"; shift 2 ;;
|
||||
--help|-h) usage ;;
|
||||
*) err "Unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check VirtualBox
|
||||
command -v VBoxManage >/dev/null 2>&1 || err "VirtualBox not found. Install it first."
|
||||
|
||||
log "SecuBox VirtualBox Setup v${VERSION}"
|
||||
echo ""
|
||||
|
||||
# Check if VM exists
|
||||
if VBoxManage showvminfo "$VM_NAME" &>/dev/null; then
|
||||
if [[ $FORCE -eq 1 ]]; then
|
||||
warn "VM '$VM_NAME' exists, removing..."
|
||||
VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null || true
|
||||
sleep 2
|
||||
VBoxManage unregistervm "$VM_NAME" --delete 2>/dev/null || true
|
||||
else
|
||||
err "VM '$VM_NAME' already exists. Use --force to overwrite or --name for different name."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Download VDI if not provided
|
||||
if [[ -z "$VDI_FILE" ]]; then
|
||||
log "Fetching latest release from GitHub..."
|
||||
|
||||
if [[ -n "${VERSION_TAG:-}" ]]; then
|
||||
RELEASE_URL="https://api.github.com/repos/${GITHUB_REPO}/releases/tags/${VERSION_TAG}"
|
||||
else
|
||||
RELEASE_URL="https://api.github.com/repos/${GITHUB_REPO}/releases/latest"
|
||||
fi
|
||||
|
||||
# Get download URL
|
||||
DOWNLOAD_URL=$(curl -fsSL "$RELEASE_URL" 2>/dev/null | \
|
||||
grep -oP '"browser_download_url":\s*"\K[^"]*vm-x64[^"]*\.vdi\.gz' | head -1)
|
||||
|
||||
if [[ -z "$DOWNLOAD_URL" ]]; then
|
||||
# Try .img.gz if .vdi.gz not found
|
||||
DOWNLOAD_URL=$(curl -fsSL "$RELEASE_URL" 2>/dev/null | \
|
||||
grep -oP '"browser_download_url":\s*"\K[^"]*vm-x64[^"]*\.img\.gz' | head -1)
|
||||
|
||||
if [[ -z "$DOWNLOAD_URL" ]]; then
|
||||
err "Could not find SecuBox VM image in releases. Check $RELEASE_URL"
|
||||
fi
|
||||
fi
|
||||
|
||||
VDI_FILE="secubox-vm-x64.vdi"
|
||||
DOWNLOAD_FILE=$(basename "$DOWNLOAD_URL")
|
||||
|
||||
log "Downloading: $DOWNLOAD_URL"
|
||||
curl -fSL --progress-bar -o "$DOWNLOAD_FILE" "$DOWNLOAD_URL"
|
||||
|
||||
log "Decompressing..."
|
||||
if [[ "$DOWNLOAD_FILE" == *.vdi.gz ]]; then
|
||||
gunzip -c "$DOWNLOAD_FILE" > "$VDI_FILE"
|
||||
elif [[ "$DOWNLOAD_FILE" == *.img.gz ]]; then
|
||||
gunzip -c "$DOWNLOAD_FILE" > "secubox-vm-x64.img"
|
||||
log "Converting IMG to VDI..."
|
||||
qemu-img convert -f raw -O vdi "secubox-vm-x64.img" "$VDI_FILE"
|
||||
rm -f "secubox-vm-x64.img"
|
||||
fi
|
||||
|
||||
rm -f "$DOWNLOAD_FILE"
|
||||
ok "Downloaded: $VDI_FILE"
|
||||
else
|
||||
[[ -f "$VDI_FILE" ]] || err "VDI file not found: $VDI_FILE"
|
||||
log "Using existing VDI: $VDI_FILE"
|
||||
fi
|
||||
|
||||
# Get absolute path
|
||||
VDI_PATH="$(cd "$(dirname "$VDI_FILE")" && pwd)/$(basename "$VDI_FILE")"
|
||||
|
||||
# Auto-detect bridge adapter
|
||||
if [[ "$NETWORK_MODE" == "bridged" && -z "$BRIDGE_ADAPTER" ]]; then
|
||||
BRIDGE_ADAPTER=$(ip -o link show | awk -F': ' '/state UP/ && !/lo|docker|veth|br-|virbr/ {print $2; exit}')
|
||||
if [[ -z "$BRIDGE_ADAPTER" ]]; then
|
||||
warn "Could not detect network adapter, using NAT mode"
|
||||
NETWORK_MODE="nat"
|
||||
else
|
||||
log "Detected network adapter: $BRIDGE_ADAPTER"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create VM
|
||||
log "Creating VM: $VM_NAME"
|
||||
|
||||
VBoxManage createvm --name "$VM_NAME" --ostype Debian_64 --register
|
||||
|
||||
# Configure VM
|
||||
log "Configuring VM..."
|
||||
VBoxManage modifyvm "$VM_NAME" \
|
||||
--memory "$VM_MEMORY" \
|
||||
--cpus "$VM_CPUS" \
|
||||
--firmware efi \
|
||||
--graphicscontroller vmsvga \
|
||||
--vram "$VM_VRAM" \
|
||||
--audio-driver pulse \
|
||||
--boot1 disk \
|
||||
--boot2 none \
|
||||
--boot3 none \
|
||||
--boot4 none \
|
||||
--rtcuseutc on \
|
||||
--ioapic on
|
||||
|
||||
# Network configuration
|
||||
case "$NETWORK_MODE" in
|
||||
bridged)
|
||||
VBoxManage modifyvm "$VM_NAME" --nic1 bridged --bridgeadapter1 "$BRIDGE_ADAPTER"
|
||||
log "Network: Bridged to $BRIDGE_ADAPTER"
|
||||
;;
|
||||
nat)
|
||||
VBoxManage modifyvm "$VM_NAME" --nic1 nat
|
||||
VBoxManage modifyvm "$VM_NAME" --natpf1 "https,tcp,,9443,,9443"
|
||||
VBoxManage modifyvm "$VM_NAME" --natpf1 "ssh,tcp,,2222,,22"
|
||||
log "Network: NAT with port forwarding (9443→9443, 2222→22)"
|
||||
;;
|
||||
hostonly)
|
||||
# Create host-only network if needed
|
||||
VBoxManage hostonlyif create 2>/dev/null || true
|
||||
HOSTONLY_IF=$(VBoxManage list hostonlyifs | grep -m1 "^Name:" | awk '{print $2}')
|
||||
VBoxManage modifyvm "$VM_NAME" --nic1 hostonly --hostonlyadapter1 "$HOSTONLY_IF"
|
||||
log "Network: Host-only ($HOSTONLY_IF)"
|
||||
;;
|
||||
*)
|
||||
err "Unknown network mode: $NETWORK_MODE"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Add storage controller
|
||||
VBoxManage storagectl "$VM_NAME" --name "SATA" --add sata --bootable on
|
||||
|
||||
# Attach VDI
|
||||
log "Attaching disk: $VDI_PATH"
|
||||
VBoxManage storageattach "$VM_NAME" \
|
||||
--storagectl "SATA" \
|
||||
--port 0 \
|
||||
--device 0 \
|
||||
--type hdd \
|
||||
--medium "$VDI_PATH"
|
||||
|
||||
ok "VM created successfully!"
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}════════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN}${BOLD} SecuBox VM Ready!${NC}"
|
||||
echo ""
|
||||
echo -e " ${CYAN}VM Name:${NC} $VM_NAME"
|
||||
echo -e " ${CYAN}Memory:${NC} ${VM_MEMORY}MB"
|
||||
echo -e " ${CYAN}CPUs:${NC} $VM_CPUS"
|
||||
echo -e " ${CYAN}Network:${NC} $NETWORK_MODE"
|
||||
echo -e " ${CYAN}Disk:${NC} $VDI_PATH"
|
||||
echo ""
|
||||
echo -e " ${GOLD}Credentials:${NC} root / secubox"
|
||||
echo ""
|
||||
if [[ "$NETWORK_MODE" == "nat" ]]; then
|
||||
echo -e " ${CYAN}WebUI:${NC} https://localhost:9443"
|
||||
echo -e " ${CYAN}SSH:${NC} ssh -p 2222 root@localhost"
|
||||
else
|
||||
echo -e " ${CYAN}WebUI:${NC} https://<VM-IP>:9443"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${BOLD}════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
# Offer to start
|
||||
read -p "Start VM now? [Y/n] " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
log "Starting VM..."
|
||||
VBoxManage startvm "$VM_NAME" --type gui
|
||||
ok "VM started!"
|
||||
echo ""
|
||||
echo "Boot modes (GRUB menu):"
|
||||
echo " 1. SecuBox (Kiosk Mode) ← Default"
|
||||
echo " 2. SecuBox (Console Mode)"
|
||||
echo " 3. SecuBox (Recovery)"
|
||||
echo ""
|
||||
echo "Console access: Ctrl+Alt+F2"
|
||||
fi
|
||||
195
wiki/VirtualBox-Setup.md
Normal file
195
wiki/VirtualBox-Setup.md
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
# SecuBox VirtualBox Setup Guide
|
||||
|
||||
Quick guide to run SecuBox in VirtualBox for testing and development.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- **VirtualBox 7.0+** with Extension Pack
|
||||
- **2GB+ RAM** available for VM
|
||||
- **8GB+ disk space** for VDI
|
||||
- **Host OS**: Linux, macOS, or Windows
|
||||
|
||||
---
|
||||
|
||||
## Quick Start (Automated)
|
||||
|
||||
```bash
|
||||
# Download and run the setup script
|
||||
curl -fsSL https://raw.githubusercontent.com/CyberMind-FR/secubox-deb/master/scripts/vbox-setup.sh | bash
|
||||
```
|
||||
|
||||
Or download manually:
|
||||
```bash
|
||||
wget https://github.com/CyberMind-FR/secubox-deb/releases/latest/download/secubox-vm-x64-bookworm.vdi.gz
|
||||
gunzip secubox-vm-x64-bookworm.vdi.gz
|
||||
bash scripts/vbox-setup.sh --vdi secubox-vm-x64-bookworm.vdi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Manual Setup
|
||||
|
||||
### 1. Download the VDI Image
|
||||
|
||||
From GitHub Releases:
|
||||
```bash
|
||||
# Latest release
|
||||
wget https://github.com/CyberMind-FR/secubox-deb/releases/latest/download/secubox-vm-x64-bookworm.vdi.gz
|
||||
|
||||
# Decompress
|
||||
gunzip secubox-vm-x64-bookworm.vdi.gz
|
||||
```
|
||||
|
||||
### 2. Create VirtualBox VM
|
||||
|
||||
```bash
|
||||
# Create VM
|
||||
VBoxManage createvm --name "SecuBox" --ostype Debian_64 --register
|
||||
|
||||
# Configure VM
|
||||
VBoxManage modifyvm "SecuBox" \
|
||||
--memory 2048 \
|
||||
--cpus 2 \
|
||||
--firmware efi \
|
||||
--graphicscontroller vmsvga \
|
||||
--vram 64 \
|
||||
--nic1 bridged \
|
||||
--bridgeadapter1 "eth0" \
|
||||
--audio-driver pulse \
|
||||
--boot1 disk \
|
||||
--boot2 none \
|
||||
--boot3 none \
|
||||
--boot4 none
|
||||
|
||||
# Add SATA controller
|
||||
VBoxManage storagectl "SecuBox" --name "SATA" --add sata --bootable on
|
||||
|
||||
# Attach VDI
|
||||
VBoxManage storageattach "SecuBox" \
|
||||
--storagectl "SATA" \
|
||||
--port 0 \
|
||||
--device 0 \
|
||||
--type hdd \
|
||||
--medium secubox-vm-x64-bookworm.vdi
|
||||
|
||||
# Start VM
|
||||
VBoxManage startvm "SecuBox" --type gui
|
||||
```
|
||||
|
||||
### 3. First Boot
|
||||
|
||||
The VM boots directly into **Kiosk Mode** (Chromium fullscreen on SecuBox WebUI).
|
||||
|
||||
**Default credentials:**
|
||||
- Username: `root`
|
||||
- Password: `secubox`
|
||||
|
||||
**Console access:** Press `Ctrl+Alt+F2` for root shell
|
||||
|
||||
---
|
||||
|
||||
## Boot Modes
|
||||
|
||||
SecuBox offers three boot modes selectable from GRUB menu:
|
||||
|
||||
| Mode | Description | Use Case |
|
||||
|------|-------------|----------|
|
||||
| **Kiosk Mode** | Fullscreen browser on WebUI | Production, demo |
|
||||
| **Console Mode** | Standard shell login | Administration |
|
||||
| **Recovery Mode** | Single-user mode | Troubleshooting |
|
||||
|
||||
To access GRUB menu: Hold `Shift` during boot or press `Escape` at BIOS.
|
||||
|
||||
---
|
||||
|
||||
## Network Configuration
|
||||
|
||||
### Bridged Mode (Recommended)
|
||||
VM gets IP from your network's DHCP:
|
||||
```bash
|
||||
VBoxManage modifyvm "SecuBox" --nic1 bridged --bridgeadapter1 "eth0"
|
||||
```
|
||||
|
||||
### NAT with Port Forwarding
|
||||
Access WebUI via localhost:
|
||||
```bash
|
||||
VBoxManage modifyvm "SecuBox" --nic1 nat
|
||||
VBoxManage modifyvm "SecuBox" --natpf1 "https,tcp,,9443,,9443"
|
||||
VBoxManage modifyvm "SecuBox" --natpf1 "ssh,tcp,,2222,,22"
|
||||
```
|
||||
- WebUI: https://localhost:9443
|
||||
- SSH: `ssh -p 2222 root@localhost`
|
||||
|
||||
### Host-Only
|
||||
Isolated network for testing:
|
||||
```bash
|
||||
VBoxManage hostonlyif create
|
||||
VBoxManage modifyvm "SecuBox" --nic1 hostonly --hostonlyadapter1 "vboxnet0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### VM tries PXE boot instead of disk
|
||||
|
||||
**Solution:** Disable network boot
|
||||
```bash
|
||||
VBoxManage modifyvm "SecuBox" --nic1 none
|
||||
# Boot once, then re-enable:
|
||||
VBoxManage modifyvm "SecuBox" --nic1 bridged --bridgeadapter1 "eth0"
|
||||
```
|
||||
|
||||
Or in GUI: Settings → System → uncheck "Network" in Boot Order
|
||||
|
||||
### Black screen after GRUB
|
||||
|
||||
**Solution:** Use VMSVGA graphics
|
||||
```bash
|
||||
VBoxManage modifyvm "SecuBox" --graphicscontroller vmsvga --vram 64
|
||||
```
|
||||
|
||||
### Kiosk doesn't start
|
||||
|
||||
**Solution:** Check kiosk service
|
||||
```bash
|
||||
# Press Ctrl+Alt+F2 for console
|
||||
systemctl status secubox-kiosk
|
||||
journalctl -u secubox-kiosk -f
|
||||
```
|
||||
|
||||
### Guest Additions
|
||||
|
||||
For better integration (shared folders, clipboard):
|
||||
```bash
|
||||
# In VM console
|
||||
apt update && apt install -y build-essential linux-headers-$(uname -r)
|
||||
mount /dev/sr0 /mnt
|
||||
/mnt/VBoxLinuxAdditions.run
|
||||
reboot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## VM Export/Import
|
||||
|
||||
### Export as OVA
|
||||
```bash
|
||||
VBoxManage export "SecuBox" -o secubox.ova
|
||||
```
|
||||
|
||||
### Import OVA
|
||||
```bash
|
||||
VBoxManage import secubox.ova
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Installation Guide](Installation-Guide.md)
|
||||
- [Kiosk Mode Configuration](Kiosk-Mode.md)
|
||||
- [Network Modes](Network-Modes.md)
|
||||
- [API Reference](API-Reference.md)
|
||||
Loading…
Reference in New Issue
Block a user