Skip to content

Fases 7-8: snapshots btrfs, firma HMAC y métricas - #18

Merged
Alexendros merged 1 commit into
mainfrom
fase-7-snapper
Sep 22, 2026
Merged

Alexendros merged 1 commit into
mainfrom
fase-7-snapper

Conversation

@Alexendros

@Alexendros Alexendros commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Implementa las fases 7 y 8 del roadmap de NEUBAT.

Fase 7 - Snapshots btrfs automáticos

  • Nuevo módulo scripts/35-snapper.sh configurado desde el perfil JSON.
  • Instala snapper y snap-pac (hooks de pacman pre/post).
  • Crea configuraciones para / y /home con límites de retención personalizables.
  • Habilita snapper-timeline.timer y snapper-cleanup.timer.

Fase 8 - Firma HMAC y métricas

  • Firma HMAC-SHA256 de configuraciones cuando NEUBAT_HMAC_SECRET está definido.
  • El instalador verifica la firma tras descargar la config.
  • Métricas de duración de instalación y endpoint /api/metrics.

Validación

  • make validate: OK
  • make test: 35/35 Jest
  • make test-bash: 10/10 bats
  • make test-frontend: 2/2 Vitest
  • make build-frontend: OK
  • make validate-ansible: OK

Note

Medium Risk
Changes touch install-time security (shared HMAC secret and config verification) and post-install system behavior (snapper timers); /api/metrics exposes aggregate install data without new auth in this diff.

Overview
Adds Phase 7 (automatic btrfs snapshots) and Phase 8 (HMAC-signed configs + install metrics) across profiles, the portal API, and the installer.

Snapshots: Profiles and POST /api/install now support a snapshots block (enabled flag and cleanup limits). When enabled, the installer runs new configure_snapper logic: installs snapper/snap-pac, creates configs for / and /home, applies retention from the profile, and enables timeline/cleanup timers (failures warn but do not abort).

HMAC: NEUBAT_HMAC_SECRET signs generated install JSON with HMAC-SHA256 (signature field). The live installer verifies the same payload after fetch and aborts on mismatch; missing secret or unsigned local profiles skip verification with a warning.

Metrics: The installer records elapsed time and sends duration on /api/complete. New GET /api/metrics returns aggregated counts and average duration. Docs and tests cover env vars, API, snapper usage, signing, and nested config reads.

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

- Fase 7: snapshots btrfs automáticos con snapper + snap-pac.
  - Nuevo módulo scripts/35-snapper.sh.
  - Configuraciones por perfil: snapshots.enabled y límites de retención.
  - Habilita timers snapper-timeline y snapper-cleanup.

- Fase 8: firma HMAC-SHA256 de configuraciones y métricas.
  - El portal firma configs cuando NEUBAT_HMAC_SECRET está definido.
  - El instalador verifica la firma al descargar la config.
  - El instalador mide duración y la envía a /api/complete.
  - Nuevo endpoint /api/metrics con estadísticas agregadas.

- Añade tests: 35 Jest, 10 bats.
- Documentación actualizada en docs/INSTALL.md y .env.example.
@Alexendros
Alexendros merged commit fbbcd2c into main Sep 22, 2026
3 of 4 checks passed
@Alexendros
Alexendros deleted the fase-7-snapper branch September 22, 2026 19:41
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: de701cf5-f8fa-4d5c-98f1-cad2023ada5b

📥 Commits

Reviewing files that changed from the base of the PR and between 61b6d72 and 1e5bee6.

📒 Files selected for processing (15)
  • .env.example
  • configs/base.json
  • configs/developer.json
  • configs/production.json
  • docs/INSTALL.md
  • portal/lib/db.js
  • portal/routes/install.js
  • portal/routes/status.js
  • portal/tests/lib/db.test.js
  • portal/tests/routes/install.test.js
  • portal/tests/routes/status.test.js
  • scripts/20-archinstall.sh
  • scripts/35-snapper.sh
  • scripts/neubat-install.sh
  • tests/bash/utils.bats
 __________________________________
< I void warranties and segfaults. >
 ----------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

Comment thread scripts/20-archinstall.sh
1) error "Firma HMAC de la configuración inválida. Posible manipulación en tránsito." ;;
2) warning "Configuración sin firma HMAC; se omite la verificación" ;;
esac
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HMAC check never aborts install

High Severity

verify_config_signature inspects $? inside if ! python3, where that status is 0 rather than Python’s 1 or 2. Invalid or missing HMAC signatures therefore skip both error and warning, so a tampered config is accepted and the install continues.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

Comment thread scripts/35-snapper.sh
arch-chroot /mnt snapper -c root create-config / \
|| warning "No se pudo crear configuración snapper para /"
arch-chroot /mnt snapper -c home create-config /home \
|| warning "No se pudo crear configuración snapper para /home"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snapper fails inside chroot

High Severity

snapper create-config runs under arch-chroot without --no-dbus. A chroot has no snapperd or D-Bus, so config creation fails and is only warned. Production has snapshots.enabled true, so timeline and snap-pac setup are skipped while the install still reports success.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

Comment thread .env.example

# Secreto compartido para firmar/verificar configuraciones con HMAC-SHA256.
# Debe coincidir con el valor usado por el instalador (NEUBAT_HMAC_SECRET).
NEUBAT_HMAC_SECRET=cambia-este-secreto-por-una-cadena-larga-y-aleatoria

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HMAC secret unused in Docker

Medium Severity

NEUBAT_HMAC_SECRET is documented for Docker Compose via .env, but docker-compose.yml never injects it into the portal container (unlike ADMIN_TOKEN). The portal therefore never signs configs in the recommended deploy path, even when the secret is set.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

Comment thread portal/lib/db.js
...(Array.isArray(config.packages) ? config.packages.sort() : []),
...(Array.isArray(config.services) ? config.services.sort() : [])
];
return parts.join('|');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HMAC omits critical config fields

Medium Severity

The HMAC payload skips encryption and snapshots, and signConfig runs before those request overrides are merged. A transit attacker can disable LUKS or change snapshot policy without invalidating signature, which contradicts the claim that the downloaded config is integrity-protected.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1e5bee6. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant