Skip to content

Auditoría exhaustiva del stack SYNVirt — Reporte final

Synced read-only from /home/synnet/mirrors/synvirt-product/docs/synvirt-stack-audit-2026-07-01.md. Edit at the source, not here.

Auditoría exhaustiva del stack SYNVirt — Reporte final

Section titled “Auditoría exhaustiva del stack SYNVirt — Reporte final”

Read-only audit · flota .11/.12/.13 + dev.synvirt.mx · repo /home/synvirt/dev (VERSION 0.15.0) · fecha 2026-07-01


  • El plano hypervisor está sano y al día. Ningún paquete core (qemu/zfs/libvirt/ovs) tiene Candidate más nuevo que el Installed en la flota — Installed == Candidate en los tres nodos. “N releases detrás de upstream” es comportamiento normal de Debian-stable, no una brecha de soporte: qemu llega como 10.0.8+ds-0+deb13u1+b2 (el sufijo +deb13uN ES el backport de seguridad). El backend Rust también está genuinamente current (axum 0.8.9, tonic 0.14.6, openraft 0.9.24 = último estable, tokio 1.52.1).
  • Lo urgente es un solo maintenance window rolling: kernel 6.12.94-1 (DSA-6355-1, 53 CVEs, necesita reboot) + libssh2 +deb13u1 (CVE-2026-55200, CVSS 9.2 RCE, PoC público 2026-06-29). Ningún CVE del batch está en CISA-KEV ni confirmado explotado in-the-wild; libssh2 es el único con PoC. El resto (openssl/ceph/urllib3/unbound/krb5/inifiles-perl) es rutina — meterlo en el mismo window.
  • Corrección importante vs la premisa operativa: .12 (synvirt-02) NO está caída — está arriba, healthy y API-responsive (0.15.0+build.1281-dirty, keepalived active, en BACKUP correcto). La flota está a membresía completa. Verificado independientemente.
  • La deuda real vive en dos capas que Debian NO mantiene por vos: (1) el guest-installer targetea .NET 8, que hace End of Support el 2026-11-10 (~4 meses) — el único cliff duro y con countdown de todo el stack; (2) el dashboard web-ux-v2 quedó en Vite 5 + Vitest 2 + Tailwind 3, todos en majors sin mantenimiento, mientras web-installer-v2 ya movió a Vite 6 + Tailwind 4.
  • Gaps de producto confirmados que sí bloquean productización: el motor de backup no existe (metadata-only, restore devuelve E_BACKUP_NOT_IMPLEMENTED — CONFIRMADO independientemente), RBAC arranca en ReportOnly (no protege hasta que un operador lo prenda), licensing es stub, y el baseline de CI está en rojo (vitest 5 fails, daemon sin rustfmt). Dos “memorias viejas” quedaron desmentidas y no deben desviar el roadmap: el ejecutor de Live Motion es real (el gap es la ruta offline/cold), y los detectores de observabilidad ya están cableados a datos reales (solo queda 1 placeholder).

Core stack (Debian mantiene estos — “atrás de upstream” ≠ “sin soporte”)

Section titled “Core stack (Debian mantiene estos — “atrás de upstream” ≠ “sin soporte”)”
Componente Flota instalado Techo Debian trixie (+backports) Último upstream (jul-2026) Majors/releases atrás ¿Soportado?
qemu-system-x86 1:10.0.8+ds-0+deb13u1+b2 …+b2 (== installed) 11.0.0 (2026-04-22) ~3 (10.1/10.2/11.0) — backport +deb13u1
OpenZFS (zfsutils-linux) 2.4.2-1~bpo13+1 (backports) main 2.3.2-2 · backports 2.4.2-1~bpo13+1 2.4.3 (2026-06-11) flota en línea 2.4 = current — 2.3.x y 2.4.x mantenidos + backport
Open vSwitch 3.5.0-1+b1 3.5.0-1+b1 3.5.4 (2026-03-31, rama 3.5) mismo major, 4 patch
libvirt 11.3.0-3+deb13u2 11.3.0-3+deb13u2 12.4.0 (2026-06-13) ~1 major + minors — backports +deb13u2
Kernel (running) 6.12.90+deb13.1 (.11/.12) · 6.12.90+deb13 (.13) 6.12.94-1 (trixie-security, pendiente) mainline 6.18+ (6.12 es LTS) LTS, no aplica — 6.12 LTS→dic-2028; Debian full→2028-08
Debian 13.5 (2026-05-16) 13.5 13.5 current — full 2028-08 / LTS 2030-06

Corrección de premisa (folded-in): trixie NO trae OpenZFS 2.4.x — main trae 2.3.2-2. La flota corre 2.4.2 porque el ISO pinea backports (zfs.pref.chroot:5-7, Pin-Priority 990). Cualquier plan que asuma features 2.4-only sobre trixie stock (uncached IO, quotas por defecto, AES-GCM AVX2) es incorrecto — necesita backports o DKMS.

Skew intra-flota: .13 corre la ABI +deb13 (paquete 6.12.90-1, -2) mientras .11/.12 corren +deb13.1 (6.12.90-2). No es solo un kernel sin rebootear: .13 tiene un paquete linux-image distinto instalado.

Dev host rezagado (build box, no producción): qemu +b1 (un binNMU atrás de +b2), zfs 2.3.2-2 (main, no backports), kernel 6.12.74+deb13+1 (un point-release atrás), root FS al 84%, 129 upgradables (53 security). Prioridad baja.

App-libs (SYNVirt las vendorea — Debian NO las backportea)

Section titled “App-libs (SYNVirt las vendorea — Debian NO las backportea)”
Componente Flota/repo pin Último upstream Majors atrás ¿Soportado / EOL?
.NET (guest-installer) net8.0-windows (SynVirtSetup.csproj:5) .NET 10 LTS 2 (8→10) EOS 2026-11-10 — cliff duro ~4 meses
Vite (dashboard) ^5.4.11 (web-ux-v2/package.json:58) 8.1.2 3 Vite 5 sin mantenimiento
Vite (installer) ^6.0.5 (web-installer-v2:23) 8.1.2 2 atrás, pero mantenido
Vitest (dashboard) ^2.1.6 (:59) 4.1.9 2 Vitest 2 EOL
Tailwind (dashboard) ^3.4.15 (:55) 4.3.x 1 v3.4 terminal (v4 es rewrite)
Tailwind (installer) ^4.0.0 (:21) 4.3.x 0 current
TypeScript ~5.6.3 (ambos) 6.0.3 stable / 7.0 RC 1 staleness (sin modelo de security-backport)
Vue 3 ^3.5.13 (ambos) 3.5.39 / 3.6 beta 0
axum (first-party) 0.70.7.9 (0.8.9 transitivo) 0.8.9 1 (first-party) current-ish
tokio 1.52.1 1.52.3 0 (2 patch)
tonic / prost =0.14.6 / =0.14.3 0.14.x 0 (exact-pin)
openraft =0.9.24 0.9.24 (0.10 solo alpha) 0 — último estable
zbus "4"4.4.0 5.16.0 1 major funciona, migración pendiente

Lectura: el backend Rust no necesita sprint de upgrade. El frontend está partido en dos toolchains (Vite 5+TW3 vs Vite 6+TW4) y el dashboard es el rezagado. El único deadline real es .NET 8.


3. Batch de seguridad pendiente + urgencia

Section titled “3. Batch de seguridad pendiente + urgencia”

100% de los upgradables en cada nodo son de *-security (11 en .11, 5 en .12, 16 en .13 — verificado). No hay ruido cosmético: todo importa. Ninguno en CISA-KEV.

Paquete (fix trixie) CVE(s) clave Severidad Toma efecto / relevancia flota
linux-image-amd64 6.12.90→6.12.94-1 (DSA-6355-1) 53 CVEs (CVE-2025-22069, CVE-2026-45838…45846, -52908…52911, -46315…46331) privesc/DoS/info-leak local predominante; sin RCE remoto ni KEV APLICAR YA. Requiere REBOOT. Mayor reducción de superficie. En hypervisor el riesgo real es guest→host / privesc local. Rolling one-at-a-time preservando quorum Raft + VIP .100.
libssh2-1t64 →+deb13u1 (DSA-6365-1) CVE-2026-55200 (OOB write→RCE), -55199 (DoS pre-auth), CVE-2026-7598, CVE-2025-15661 CVSS 9.2 CRÍTICO; PoC público 2026-06-29; no KEV APLICAR YA. Es lib cliente (curl/git/php) — RCE cuando un cliente libssh2 habla con server SSH malicioso/MITM. El sshd de la flota usa OpenSSH, así que la superficie server-side es limitada, pero costo de parche trivial. Reiniciar servicios que linkean libssh2.
openssl / libssl3t64 3.5.6-u1→u2 CVE-2026-42767 (NULL-deref DoS, CMP-client-only) Baja (DoS, FIPS no afectado) Rutina. Impacto casi nulo (nadie corre CMP client). Blast-radius TLS amplio al reiniciar.
librados2 / librbd1 (Ceph) →+deb13u1 (DSA-6321-1) CVE-2024-47866 (RGW S3 DoS), -31884, CVE-2025-52555 Moderada — casi todo RGW/S3, no RBD Rutina. Storage es ZFS zvols; libs son deps transitivos, sin RGW.
python3-urllib3 →+deb13u2 CVE-2026-9375 (decompression-bomb bypass) Moderada (DoS cliente) Rutina.
libunbound8 / unbound →+deb13u3 CVE-2026-44608, -44390, -42960… (~10, DoS resolver) Moderada Rutina — solo si corre como resolver. Reiniciar unbound.
krb5 →+deb13u1 (DSA-6293-1) CVE-2026-40355 (NULL-deref), -40356 (OOB read) DoS remoto condicional (solo GSS acceptor con NegoEx) Rutina. Flota improbable como acceptor Kerberos. (Solo pendiente en .13.)
libconfig-inifiles-perl →+deb13u1 (DSA-6354-1) CVE-2026-11527 (exec shell / overwrite vía filenames) Moderada en papel, nicho Rutina. Solo si algo parsea filenames .ini attacker-controlled.

Caveat “parcheado ≠ vivo” — MEDIDO en gap-close (importante)

Section titled “Caveat “parcheado ≠ vivo” — MEDIDO en gap-close (importante)”

La crítica levantó que “already-applied” podría no estar vivo en procesos long-running. Se midió read-only y el resultado es tranquilizador:

  • Exposición residual de shared-libs = 0 en 0/3 nodos. Ningún proceso mapea .so borrado/actualizado. Se corrige el hallazgo de recon: los “2 procesos en .12 sobre libs post-update” eran iscsid mapeando /SYSV00000000 (deleted) — shm SysV borrado por diseño, no una librería parcheada. Falso positivo.
  • Exposición de VMs vivas = 0. Los 8 qemu corriendo (6 en .11, 1 en .12, 1 en .13) ejecutan el qemu +b2 actual (mtime 2026-05-09) y openssl 3.5.6 actual. Prueba por inode: el guest más viejo de .11 (pid 2876, desde Jun-26) mapea /usr/bin/qemu-system-x86_64 inode 1049358 y libcrypto.so.3 inode 1063084 = idénticos a los on-disk → no hubo replace desde el launch. Los (deleted) que el conteo naïve reporta son buffers memfd de display/virtio-gpu, benignos.
  • Único código stale genuino: el binario synvirt-console en .11 (pid 2119) y .13 (pid 2027) corre texto viejo en memoria tras un hot-deploy que reemplazó el binario on-disk. Es frescura de app, no gap de seguridad de OS — remediable con restart del console (no ejecutado).

Reboot-required signalling: Debian no emite /var/run/reboot-required y needrestart/checkrestart no está instalado en ningún host → los operadores no tienen señal built-in de “este nodo necesita reboot/restart para activar el fix”. Considerar instalar needrestart.


Footgun Detalle Estado
virtio-win: build.sh vs MANIFEST iso-builder/build.sh:83 default SYNVIRT_VIRTIO_WIN_VERSION:-0.1.285 embebe el ISO completo 0.1.285 en guest-tools.iso (via synvirt-guest-tools-iso build, build.sh:426-432), contradiciendo el pin storage-safe virtio-win-0.1.271.iso de MANIFEST.toml:24. 0.1.271 es “the last release verified free of the data-corruption bug introduced in 0.1.285+ (WS2025 + SQL Server)”. El artefacto commiteado lo prueba: guest-tools.iso.manifest.json declara "version":"0.1.285". CONFIRMADO. ALTO
Rust toolchain sin pin rust-toolchain.toml:2 = channel = "stable" (canal flotante, sin versión/fecha); cero rust-version/MSRV en los 53 Cargo.toml. Builds del appliance no son reproducibles respecto al compilador, aunque el VERSION esté single-sourced. CONFIRMADO. Medio
Node sin pin Ninguno de los dos frontends declara engines.node; no hay .nvmrc/.node-version/.tool-versions en el repo. Entorno de build del bundle indefinido. CONFIRMADO. Bajo
Split Vite/Tailwind web-ux-v2 (Vite 5 + TW3/PostCSS) vs web-installer-v2 (Vite 6 + TW4/@tailwindcss/vite). Dos majors de Vite y dos de Tailwind a mantener + divergencia de design tokens. CONFIRMADO. Bajo
Deploys -dirty (traceability) Los 3 nodos corren idéntico 0.15.0+build.1281-dirty (sin skew — bien) pero todos -dirty = deploy desde working tree no commiteado, no reproducible desde tag git. Verificado por 3 métodos (API, strings del binario, --version). Medio
/etc/synvirt/release stale .11=Fix54+build.803, .12=Fix53+build.803, .13=Fix45+build.784-dirty (esquema -FixN deprecado) vs running build.1281~478 builds de desfase. Confiar en node/identity, no en el file. CONFIRMADO. Bajo
Exact-pins Raft/gRPC synvirt-cluster/Cargo.toml:43-45,58: tonic="=0.14.6", tonic-prost="=0.14.6", prost="=0.14.3", openraft="=0.9.24" (+ tonic-prost-build="=0.14.6" en build-deps). Congela el stack; bloquea uptake automático de patches. (Justificado por breaking changes de openraft; hoy 0.9.24 es el último estable.) Bajo
zbus 1 major atrás synvirt-services:17 y synvirt-webrtc:73 declaran "4" → resuelve 4.4.0; zbus 5 (5.16.0) existe. Migración D-Bus futura. CONFIRMADO. Bajo
.NET/frontend sin guard de SDK No hay global.json; test-deps viejos (Microsoft.NET.Test.Sdk 17.8.0, xunit 2.6.2). Bajo

5. Gaps de producto VERIFICADOS (ranked por impacto de productización)

Section titled “5. Gaps de producto VERIFICADOS (ranked por impacto de productización)”
# Gap file:line Estado
1 Backup (SynBaaS) no tiene motor de datos ni restore — es metadata-only pese a shipear UI /backup + store redb. create/cancel/register/restore devuelven E_BACKUP_NOT_IMPLEMENTED. Cero hits de zfs send/snapshot/chunk/qemu-img; deps solo redb+tokio+axum → data-movement físicamente imposible. La UI renderiza sample data con marca “Preview”. synvirt-backupd/src/http.rs:187 (restore→NotImplemented), 123/147/164; backup-core/src/lib.rs:11-13 CONFIRMADO (verificación independiente adversarial)
2 RBAC arranca en ReportOnly#[default] EnforcementMode::ReportOnly (loguea “would deny”, permite); wire values desconocidos caen a ReportOnly. Safe-by-default correcto, pero RBAC no protege nada en host fresco hasta que el operador prenda enforcement. synvirt-identity/src/authz.rs:60-64,78-83; test :186 CONFIRMADO (single-agent; no re-verificado adversarialmente — ver §7)
3 Licensing es stub — todo host reporta “unlicensed”; sin backend de entitlement/enforcement. web-ux-v2/src/composables/useHostSummary.ts:34 CONFIRMADO (single-agent)
4 CI baseline en ROJOvitest run: 5 failed | 701 passed (Test Files 39 failed), exit 1 (fails reales en Button.spec.ts:11, Tag.spec.ts:23, SidebarInventoryMorph.spec.ts:247). cargo fmt --check: diffs en daemon/src/api/{audit.rs:201, events.rs:775, iso_download.rs:65,155}. Clippy NO re-corrido (necesita build completo). ver arriba CONFIRMADO (single-agent; baseline no-verde ya documentado en MEMORY)
5 Migración offline/cold ausente — la ruta live SÍ está implementada y prod-wired (virsh migrate --live --persistent --undefinesource --copy-storage-all + pre-create de zvol thin + rewrite XML + rollback). El gap real es cold: bailea con “offline (cold) migration is not yet wired in this executor; use a live job”. synvirt-livemotiond/src/executor.rs:103-108; wired main.rs:57 REFUTA “executor stubbed” — memoria STALE; solo cold es el gap
6 Detectores de observabilidad — casi todos cableados — 40 en catálogo, 39 alimentados por suppliers reales fail-soft (storaged UDS, NetworkController, synvirt-certs, ipmitool, journalctl, guest-tools). Único stub residual: DaemonLogErrorRate devuelve Ok(0). Prosa “stub” stale en doc-comment y host_pool_usage.rs:3. daemon/src/main.rs:2443 (log “7 real + 33 supplier-wired — 40”), residual :2180 REFUTA “33 stubs” — memoria STALE
7 Syslog/SIEM egress OFF por defecto — cero targets seeded, default enabled:false; ninguna ruta egresa audit raw. Safe-by-default correcto; SIEM requiere opt-in explícito. synvirt-logging/src/config.rs:80-81,223; test :199 CONFIRMADO (single-agent) — nota compliance, no defecto

No under-creditar (sólidamente implementado): motor de migración live completo con job-state en SQLite que sobrevive restart del daemon; observabilidad con 39/40 detectores reales + TTL-cache + bridge hardware-alarm→SSE; failover VIP unicast-VRRP + replicación de doc Cloud en Raft cluster_kv (cloud.rs:207 config_put, :174 config_get); RBAC + logging con redacción obligatoria y colas drop-oldest; cero todo!()/unimplemented!() en todo el árbol (superficies incompletas devuelven E_*_NOT_IMPLEMENTED honesto); migrator con adapter SOAP vim_api (~1700 LOC).

Hallazgos operativos de la flota (verificados)

Section titled “Hallazgos operativos de la flota (verificados)”
  • VIP 10.10.26.100 la tiene .13 (proto keepalived secondary en ipMGMT; MASTER STATE en journal). keepalived active + config unicast 3-way válida en los 3 (.11→{.12,.13}, etc.). Mejora sobre el estado single-homed previo. Pero: priority 100 igual + nopreempt en todos = first-up-wins, sin master designado (.13 la tiene por uptime/IP más alta, no por diseño). CONFIRMADO.
  • synvirt-cert-renew.service failed en los 3 (status=226/NAMESPACE). CORRECCIÓN (folded-in): el recon dijo “falta cert-renew.sh” — falso. El script existe y es ejecutable (2220 bytes, rwxr-xr-x) en los 3. La única causa es que falta el directorio /etc/letsencrypt, listado en ReadWritePaths= del unit → systemd no arma el mount-namespace (step NAMESPACE) y ExecStart nunca corre. Fix correcto: crear/poblar /etc/letsencrypt (o sacarlo de ReadWritePaths), NO restaurar el script. Benigno para el cert interno (.11 sirve self-signed CN=synvirt.local válido a 2034); latente si el cert del VIP/DNS dependiera de LE.
  • Sin swap en ningún nodo de flota (0B); .11 es el más cargado (34/62 GiB, load ~3.4). Margen fino bajo presión de memoria. zpools todos healthy, capacidad baja (5%/3%/10%). Failed units cosméticos: systemd-networkd-wait-online (los 3), + synvirt-boot-splash/synvirt-vnic-rename en .13.

Postura de CPU / boot / confinamiento (gap-close)

Section titled “Postura de CPU / boot / confinamiento (gap-close)”
  • Topología real: .11 baremetal (Xeon E5-2603 v3 Haswell), .12 baremetal (Xeon E-2224 Coffee Lake), .13 es GUEST VMware (EPYC 9124 Genoa). systemd-detect-virt = none/none/vmware.
  • Microcode: .11 carga 0x49 (revisión terminal de Haswell, no hay más — no-issue, no reboot); .12 carga 0xfa (la del paquete nov-2025 — OK). No requieren acción.
  • .13 (VM) tiene 2 vulnerabilidades CPU vivas: spec_rstack_overflow: "Vulnerable: Safe RET, no microcode" (SRSO/Inception, CVE-2023-20569) y tsa: "Vulnerable: Clear CPU buffers attempted, no microcode" (TSA, familia CVE-2024-36350/36357). El amd64-microcode instalado es inerte dentro de la VM — la mitigación depende del host ESXi físico no auditado (AGESA/BIOS del EPYC 9124 o microcode de ESXi). .11 y .12 limpios en /sys/.../vulnerabilities/*. Severidad media, es hypervisor de producción.
  • Secure Boot OFF/imposible fleet-wide: no hay shim-signed ni grub-efi-amd64-signed, mokutil ausente. .11/.13 en Legacy BIOS (SB no puede existir); .12 en UEFI pero sin shim firmado → sin chain-of-trust. Boot sin verified/measured boot.
  • Sin MAC confinement: AppArmor kernel-module habilitado en .11 pero el paquete userspace + aa-status no están instalados → cero perfiles cargados; security_driver de libvirt sin setear (secmodel=none, dac only); qemu vivo (pid 2876) corre unconfined. Un escape de qemu cae como user libvirt-qemu con separación solo DAC. Sin SELinux. Defense-in-depth débil (no directamente explotable remoto por sí solo).

Tier A — Operativo AHORA (semana en curso)

Section titled “Tier A — Operativo AHORA (semana en curso)”
Item Esfuerzo Impacto Por qué
A1. Maintenance window rolling: kernel 6.12.94-1 + libssh2 +deb13u1 + resto security M Alto Único batch urgente. Reboot one-at-a-time preservando quorum Raft + VIP; rebootear el holder del VIP (.13) al final. Restart de servicios que linkean libssh2. Verificar quorum entre nodos.
A2. Corregir cert-renew: crear/poblar /etc/letsencrypt (o sacarlo de ReadWritePaths=) en los 3 S Bajo-Medio Mata el failed unit fleet-wide. No restaurar el script (existe). Antes, medir expiry del cert VIP cloud.synnet.mx — ahí sí mordería.
A3. Restart de synvirt-console en .11/.13 S Bajo Correr el binario on-disk (hot-deploy dejó texto viejo en memoria). Frescura, no seguridad.
A4. Instalar needrestart en la flota S Medio Da la señal “reboot/restart requerido” que hoy no existe; sube disciplina de parcheo.
A5. Auditar microcode/BIOS del host ESXi de .13 (SRSO+TSA) S Medio La mitigación vive fuera de la flota; confirmar que el físico las cierra.

Tier B — Production-readiness (próximas 2-6 semanas)

Section titled “Tier B — Production-readiness (próximas 2-6 semanas)”
Item Esfuerzo Impacto Por qué
B1. Migrar guest-installer a .NET 10 LTS M Alto Único cliff duro: EOS 2026-11-10. Después no hay security-servicing para SynVirt-Setup.exe. Empezar ya (net8→net10 es incremental). Agregar global.json con RollForward.
B2. Poner el baseline de CI en verde (vitest 5 fails + cargo fmt) S-M Alto (leverage) Sin baseline verde, “tests pasan” no significa nada y las regresiones se esconden. Barato, alta palanca para disciplina de release.
B3. Prender enforcement de RBAC en modo gradual (broaden desde ReportOnly) M Alto Hoy RBAC es observability-only; producto comercial necesita protección real. Roll-out controlado con métricas de “would-deny”.
B4. Reconciliar el pin virtio-win en build.sh (default → derivar de MANIFEST = 0.1.271, como ya hace build-guest-tools-split.sh:25) S Alto (data-integrity) Un ISO buildeado sin override embebe el vioscsi 0.1.285 corruption-prone en guest-tools.iso. Alinear build.sh:83 con el hermano ya migrado.
B5. Modernizar el dashboard: Vite 5→6/7, Vitest 2→4, Tailwind 3→4 L Medio Alinear con web-installer-v2; salir de majors sin mantenimiento. TW3→4 es rewrite (planificar tokens).
B6. Agregar swap (o ZRAM) al menos en .11 S Medio 0B swap + load 3.4 sin fallback bajo presión de memoria.

Tier C — Fundaciones (backlog estratégico)

Section titled “Tier C — Fundaciones (backlog estratégico)”
Item Esfuerzo Impacto Por qué
C1. Motor de backup real (SynBaaS) L Alto (launch-blocker) Hoy es metadata-only; anunciar backup sin restore es trampa de expectativa/data-loss. Es la brecha de productización #1.
C2. Ruta de migración offline/cold M Medio Completa el executor (la live ya está).
C3. Pin de toolchain Rust + Node + MSRV (rust-toolchain.toml con versión, .nvmrc, engines.node) S Medio Reproducibilidad del appliance; hoy el VERSION es single-source pero el compilador flota.
C4. Deploys reproducibles (matar -dirty) M Medio Deploy desde tag/commit limpio; hoy no hay rollback trazable.
C5. Confinamiento MAC (AppArmor para qemu/libvirt) + evaluar Secure Boot M-L Medio Segunda capa sobre DAC para escapes de qemu; hardening baseline.
C6. keepalived con priorities distintas (master designado, no first-up-wins) S Bajo Failover determinístico del VIP.
C7. zbus 4→5, axum first-party 0.7→0.8, edition 2021→2024 M Bajo Deuda ordenada, no urgente.

Esta semana: un solo window rolling para el kernel + libssh2 + resto security (A1), rebooteando .13 al final por el VIP, y de paso arreglo cert-renew (A2) y reinicio el console (A3). Instalo needrestart (A4) para no volver a quedar ciego. En paralelo, sin tocar runtime: arranco la migración a .NET 10 (B1, el único reloj corriendo) y pongo el CI en verde (B2, barato y desbloquea todo lo demás), y corrijo el default de build.sh a 0.1.271 (B4, riesgo de corrupción de datos Windows por un one-liner). El backend Rust y el plano hypervisor no los toco — están current y perseguir qemu 11/libvirt 12 compra features, no seguridad. El backup real (C1) es el gran proyecto de fundación para poder decir “somos enterprise” sin asterisco.


7. Lo que NO se pudo verificar / próximos pasos

Section titled “7. Lo que NO se pudo verificar / próximos pasos”

Reversales de producto no re-verificadas independientemente: de los gaps de Dimensión-4, solo backup fue confirmado adversarialmente (CONFIRMADO). Los demás — Live Motion es real (no stub), detectores cableados, RBAC ReportOnly, syslog egress off, licensing stub — vienen de un solo agente de inspección de código y NO están en el set VERIFIED independiente. Son load-bearing para el roadmap (reversan “memorias viejas”); recomiendo re-confirmarlos localmente con grep barato: grep -n "E_BACKUP_NOT_IMPLEMENTED\|NotImplemented" .../synvirt-backupd/src/http.rs, grep -n "not yet wired\|MockExecutor" .../synvirt-livemotiond/src/executor.rs, grep -n "supplier-wired\|Ok(0" .../daemon/src/main.rs.

No auditado — pendiente:

  1. CVE IDs concretos de los bumps pendientes — NO enumerables offline. Los changelog.Debian.gz on-box solo listan CVEs ya fijados en el build instalado; los CVEs que el kernel 6.12.90/openssl 3.5.6-u1 corriendo todavía cargan viven en los .deb candidate / metadata server. Correr (con red, read-only): apt changelog linux-image-amd64 / apt changelog openssl, o consultar el security-tracker para src:linux 6.12.94-1 y src:openssl 3.5.6-1~deb13u2.
  2. Certs del VIP/DNS cloud.synnet.mx y self-certs de .12/.13 — expiry nunca medido. Ahí sí mordería una renovación LE rota (el interno de .11 está OK a 2034).
  3. Sync de chrony en .12/.13 — solo .11 confirmado (stratum 3, sub-ms). .12 rebooteó hace min; time-drift amenaza Raft/VRRP/TLS.
  4. Drift de feature-flags ZFS — ¿los pools de flota (OpenZFS 2.4.2) fueron zpool upgradeados a flags 2.4-only? Bloquearía el import en un host 2.3 (recovery/migración). No leído.
  5. Otros hosts del entorno.52 (baremetal synvirt-01, distinto de los nested), .65/.75 (nested/perf), .67 (synvirt-03 alt), .70 (Quanta BMC). Nunca sondeados; si alguno está vivo sirviendo builds viejos, cambia el cuadro de riesgo.
  6. Host físico ESXi de .13 — cierre real de SRSO/TSA depende de su microcode/BIOS (no en el inventario de flota).
  7. Skew guest-tools/agent vs daemon en dominios vivos — riesgo de flap conocido (MEMORY), no chequeado contra las VMs corriendo.
  8. spice-server (libspice-server1 0.15.2-1+b1, históricamente CVE-prone) — currency no evaluada. Clippy del daemon no re-corrido (necesita build). DPDK cerrado: dpdk_initialized=false (kernel datapath, sin superficie DPDK).