Skip to content

Fase 6: cifrado LUKS2 opcional - #17

Merged
Alexendros merged 1 commit into
mainfrom
fase-6-luks
Sep 22, 2026
Merged

Alexendros merged 1 commit into
mainfrom
fase-6-luks

Conversation

@Alexendros

@Alexendros Alexendros commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Implementa el cifrado de disco LUKS2 para las particiones de raíz y home.

Cambios principales

  • Cifrado LUKS2 opcional activado desde el perfil JSON ().
  • Dos métodos de arranque:
    • en /boot: arranque desatendido (por defecto en producción).
    • : arranque interactivo, mayor seguridad física.
  • Configuración automática de , hook en y parámetro en GRUB.
  • Utilidad para leer valores anidados del JSON sin depender de jq.
  • Soporte en la API del portal para personalizar y .
  • Tests actualizados: 30 tests Jest, 9 tests bats.
  • Documentación nueva: (panel de paquetes) y sección LUKS en .

Validación

  • OK scripts/00-preinstall.sh
    OK scripts/10-partition.sh
    OK scripts/20-archinstall.sh
    OK scripts/30-postinstall.sh
    OK scripts/40-portal-deploy.sh
    OK scripts/50-firstboot-ansible.sh
    OK scripts/build-iso-inner.sh
    OK scripts/build-iso.sh
    OK scripts/neubat-install.sh
    OK scripts/validate-install.sh
    OK portal/server.js
    OK portal/routes/install.js
    OK portal/routes/status.js
    OK portal/routes/admin.js
    OK portal/lib/db.js
    OK configs/base.json
    OK configs/developer.json
    OK configs/production.json ✅
  • cd portal && npm test

neubat-portal@1.0.0 test
jest ✅ (30/30)

  • 1..9
    ok 1 part_name añade número directo para discos sin numeración
    ok 2 part_name usa sufijo 'p' para discos con numeración
    ok 3 cfg_get devuelve valor de cadena
    ok 4 cfg_get devuelve valor por defecto cuando falta la clave
    ok 5 cfg_get devuelve lista como espacios
    ok 6 cfg_get devuelve valor por defecto cuando el valor es null
    ok 7 cfg_get_nested lee valores booleanos anidados
    ok 8 cfg_get_nested lee cadenas anidadas
    ok 9 cfg_get_nested devuelve valor por defecto en rutas inexistentes ✅ (9/9)
  • cd portal/frontend && npm install

up to date, audited 273 packages in 1s

42 packages are looking for funding
run npm fund for details

found 0 vulnerabilities
cd portal/frontend && npm test

frontend@0.0.0 test
vitest run

RUN v5.0.1 /home/alexendros/Aplicaciones/Fuentes/neubat/portal/frontend

✓ src/pages/HomePage.test.tsx (2 tests) 433ms
✓ HomePage (2)
✓ renderiza el formulario y la lista de instalaciones 314ms

Test Files 1 passed (1)
Tests 2 passed (2)
Start at 21:35:22
Duration 1.77s (environment 41%, tests 27%, import 18%, transform 9%, setup 5%, worker 1%) ✅ (2/2)

  • cd portal/frontend && npm install

up to date, audited 273 packages in 1s

42 packages are looking for funding
run npm fund for details

found 0 vulnerabilities
cd portal/frontend && npm run build

frontend@0.0.0 build
tsc -b && vite build

vite v8.3.0 building client environment for production...
transforming...
✓ 2005 modules transformed.
rendering chunks...
computing gzip size...
../public/index.html 0.43 kB │ gzip: 0.30 kB
../public/assets/index-C9aW6FZ0.css 46.27 kB │ gzip: 8.92 kB
../public/assets/index-BKnelo9s.js 420.03 kB │ gzip: 132.37 kB

✓ built in 366ms ✅

  • OK ansible/inventory/local.yml

playbook: site.yml
OK ansible/site.yml syntax ✅


Note

High Risk
Changes full-disk layout, boot/initramfs/GRUB, and stores LUKS keys or passphrases in profile/API config—including a production keyfile on /boot—so failed installs or misconfiguration can brick boot or weaken physical security.

Overview
Adds optional LUKS2 encryption for root and home during NEUBAT installs, driven by a new encryption block on install profiles and overridable via POST /api/install (encryption, plus password override).

When enabled, partitioning creates LUKS2 containers on p2/p3, formats btrfs on /dev/mapper/neubat_*, and post-install writes crypttab, injects the encrypt mkinitcpio hook, sets cryptdevice=... in GRUB, and supports keyfile (unattended key on /boot) or passphrase. Config loading uses new cfg_get_nested; cryptsetup is always included in the base pacstrap set.

Production enables encryption with keyfile by default; base/developer ship encryption off. Profiles also add okular and expand the developer package list (JetBrains Toolbox, API clients, GitLab runner, etc.). New docs/PACKAGES.md and an LUKS section in docs/INSTALL.md document packages and usage; Jest and bats tests cover API encryption/password and nested config reads.

Reviewed by Cursor Bugbot for commit 02157bb. Configure here.

- Añade soporte para cifrado LUKS2 de raíz y home.
- Métodos: keyfile en /boot (arranque desatendido) o passphrase (interactivo).
- Extiende cfg_get_nested() para leer configuración anidada.
- Actualiza perfiles JSON: production cifrado por defecto.
- Ajusta paquetes: añade okular, elimina audacity/shotwell.
- Configura crypttab, mkinitcpio (hook encrypt) y GRUB cmdline.
- Soporte API para encryption y password personalizados.
- Tests de utilidades bash y Jest actualizados.
- Documentación: docs/INSTALL.md §6.1 y docs/PACKAGES.md.
@gitguardian

gitguardian Bot commented Sep 22, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
37442710 Triggered Generic Password 02157bb configs/production.json View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@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: 61400f08-ae1a-42c7-a974-b8d330c9395b

📥 Commits

Reviewing files that changed from the base of the PR and between 821f1de and 02157bb.

📒 Files selected for processing (12)
  • configs/base.json
  • configs/developer.json
  • configs/production.json
  • docs/INSTALL.md
  • docs/PACKAGES.md
  • portal/routes/install.js
  • portal/tests/routes/install.test.js
  • scripts/10-partition.sh
  • scripts/20-archinstall.sh
  • scripts/30-postinstall.sh
  • scripts/lib/utils.sh
  • tests/bash/utils.bats
 _______________________________
< I turn WTF moments into TILs. >
 -------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ 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.

@Alexendros
Alexendros merged commit 61b6d72 into main Sep 22, 2026
5 of 9 checks passed
@Alexendros
Alexendros deleted the fase-6-luks branch September 22, 2026 19:35

@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 3 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 02157bb. Configure here.

Comment thread scripts/10-partition.sh
# Montaje con opciones optimizadas para SSD
log "Montando particiones..."
mount -o noatime,compress=zstd,space_cache=v2 "${p_root}" /mnt
mount -o noatime,compress=zstd,space_cache=v2 "${fs_root}" /mnt

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Encrypted /boot is unreadable by GRUB

High Severity

Root is LUKS-encrypted while /boot stays on that same filesystem; only the ESP is mounted at /boot/efi. After reboot GRUB cannot read grub.cfg, the kernel, or the initramfs, so an encrypted install does not boot. The production profile turns this path on by default.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 02157bb. Configure here.

Comment thread scripts/30-postinstall.sh
# GRUB: indicar al hook encrypt qué dispositivo abrir
if [[ -f /mnt/etc/default/grub ]]; then
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"|GRUB_CMDLINE_LINUX_DEFAULT=\"cryptdevice=UUID=${root_uuid}:neubat_root |" /mnt/etc/default/grub
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.

Keyfile never reaches the encrypt hook

High Severity

configure_luks copies the keyfile to /boot/luks-keyfile and writes crypttab, but never adds it to the mkinitcpio FILES array or a cryptkey= kernel parameter. The encrypt hook therefore cannot find the key. Containers were formatted with only that keyfile, so a passphrase prompt cannot unlock them either.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 02157bb. Configure here.

Comment thread scripts/10-partition.sh
# shellcheck disable=SC2086
printf '%s' "${LUKS_PASSPHRASE}" | cryptsetup luksFormat "${partition}" - "${cryptargs[@]}"
# shellcheck disable=SC2086
printf '%s' "${LUKS_PASSPHRASE}" | cryptsetup open "${partition}" "${mapper}" -

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Passphrase open uses invalid stdin syntax

High Severity

The passphrase path pipes the secret into cryptsetup open and appends a bare -. open does not take a positional key file; it expects --key-file -. Encrypted installs with method: passphrase fail when opening the new containers, after the disk has already been wiped.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 02157bb. 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