Capítulo 17a Cumplimiento, almacenamiento & operación Admin: #/protect/overview

Backup & Recovery (nextxch Protect): exportación probatoria, configuración, datos, restauración y cambio de proveedor

nextxch Protect reúne en la administración, bajo Backup & Recovery, todo lo necesario para pruebas, copias de seguridad y recuperación: exportación EML con valor probatorio y un manifiesto firmado con Ed25519, copia de seguridad de la configuración con versiones, copia de seguridad de datos incremental y cifrada (directorio, recurso compartido SMB o S3 con Object Lock), restauración en el buzón desde el archivo GoBD, los elementos eliminados o una copia de seguridad de datos, recuperación bare-metal en el primer arranque y despliegue por pipeline con restauración y sincronización en vivo para un cambio de proveedor. Todo está integrado en el servidor, sin producto adicional y sin servicio externo.

Consejo operativo y nota de arquitectura

Orden para empezar: primero configure la clave de copia de seguridad en Backup & Recovery > Configuración (una frase de contraseña de al menos 12 caracteres o una clave de recuperación, solo con sesión iniciada como administrador del servidor) y guárdela fuera del servidor. La copia de seguridad de la configuración y la de datos utilizan la misma clave; el servidor solo almacena la parte pública y puede escribir copias de seguridad, pero nunca leerlas. Licencia: la copia de seguridad de la configuración, la verificación de las exportaciones probatorias, el autoservicio en Webmail, la restauración en el primer arranque y la restauración por pipeline de la configuración están incluidos en todos los niveles; la copia de seguridad de datos, la exportación probatoria, los trabajos de restauración, la parte de datos de la restauración por pipeline y la sincronización en vivo, a partir de Business.

1. Inicio rápido: clave, destino, primera copia de seguridad y verificación

Los destinos y las programaciones se configuran en Backup & Recovery > Programaciones y destinos (solo administradores del servidor). nextxch-cli inicia sesión con una clave de API o un inicio de sesión de administrador.

Referencia / configuración
# 1. Admin > Backup & Recovery > Configuration: set up the backup key
#    (passphrase of 12+ characters or recovery key, keep it safe outside the server)
# 2. Schedules & targets: add a target (directory, SMB share \\nas\backup\nextxch or S3) and "Test"
# 3. Back up the configuration (every tier) and take it along as a file:
nextxch-cli config backup --label "before migration" -o nextxch-config.zip

# 4. Data backup (Business): full first, then incremental by schedule
nextxch-cli backup run --target nas --full
nextxch-cli backup list --target nas

# 5. Verify, with the passphrase including decryption of the sample
export NEXTXCH_BACKUP_PASSPHRASE='...'
nextxch-cli backup verify --target nas --passphrase-env NEXTXCH_BACKUP_PASSPHRASE --limit 200

2. Exportación con valor probatorio: ZIP, manifiesto, firma y verificación

Los mensajes se incluyen en el ZIP byte a byte como .eml. manifest.json enumera cada archivo con SHA-256, tamaño, hash del archivo, estado de integridad, retención y conservación legal (legal hold); manifest.json.sig es una firma Ed25519 sobre los bytes exactos del manifiesto, derivada del secreto del servidor e idéntica en todos los nodos del clúster. GET /api/compliance/exports/public-key devuelve la clave pública sin inicio de sesión. La opción de descifrado solo elimina el cifrado en reposo (solo ServerAdmin y ComplianceAuditor; de lo contrario, 403 DECRYPT_NOT_ALLOWED); no es un descifrado general de S/MIME u OpenPGP. La descarga individual GET /api/compliance/messages/{id}/raw devuelve los hashes como encabezados HTTP X-Nextxch-Sha256, X-Nextxch-Stored-Sha256, X-Nextxch-Integrity y Repr-Digest. Exportación a partir de Business, verificación en todos los niveles.

Referencia / configuración
nextxch-evidence-20261111-0930-1a2b3c4d.zip
  messages/000001-<archiveId>.eml     original message, byte for byte
  messages/000002-<archiveId>.eml
  SHA256SUMS.txt                      verifiable with sha256sum -c
  manifest.json                       format nextxch-evidence-export/1, scope (incl. caseReference), items[]
  manifest.json.sig                   Ed25519: algorithm, keyId, publicKey, signedSha256, signature
  README.txt

# Start an export (202, status under GET /api/compliance/exports/{id}):
curl -X POST https://mail.company.com/api/compliance/exports -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{"scope":"mailbox","account":"anna@company.com","sinceUtc":"2026-01-01T00:00:00Z","caseReference":"Case 2026-0815"}'

# Verify offline, without access to the server (exit code 0 valid, 1 invalid/tampered, 2 usage error):
curl -s https://mail.company.com/api/compliance/exports/public-key > nextxch-evidence-key.json
nextxch-cli export verify nextxch-evidence-20261111-0930-1a2b3c4d.zip --public-key <publicKey from the file>
unzip -d export nextxch-evidence-20261111-0930-1a2b3c4d.zip && cd export && sha256sum -c SHA256SUMS.txt

3. Copia de seguridad de la configuración: contenido, cifrado, diferencias y restauración parcial

Un paquete contiene la configuración como código (config/*.yaml), archivos de estado sin secretos (server/*), reglas Sieve y los secretos cifrados en secrets.enc (AES-256-GCM, clave de datos envuelta para la clave de copia de seguridad; una copia de seguridad manual puede recibir además su propia frase de contraseña). Secciones: config:<area>, dkim, passwords, tls-certificates, api-keys, sieve, server-files, licence; licence, passwords y api-keys solo se restauran si se indican explícitamente. De forma predeterminada, la restauración es una simulación con vista previa. En todos los niveles; REST en /api/v1/config/backups.

Referencia / configuración
nextxch-cli config list                                   # versions (reason: manual, pre-update, after-change, pre-restore, import)
nextxch-cli config diff 20261101T020000Z-a1b2c3 current             # difference between two versions or to the current state
nextxch-cli config backup --label "before update" --passphrase-env BACKUP_PW -o nextxch-config.zip
nextxch-cli config import -f nextxch-config.zip           # take over a package of another server

# Partial restore: preview first, then apply
nextxch-cli config restore 20261101T020000Z-a1b2c3 --sections dkim,config:domains --domain company.com --dry-run
nextxch-cli config restore 20261101T020000Z-a1b2c3 --sections dkim,config:domains --domain company.com --yes

# REST: POST /api/v1/config/backups/{id}/restore
# {"sections":["dkim","config:domains"],"domain":"company.com","prune":false,"dryRun":true}

4. Copia de seguridad de datos: destinos, formato y catálogo

Cada ejecución genera una versión autónoma: instantánea de la base de datos por tabla (independiente del proveedor, por lo que también es posible pasar de SQLite a PostgreSQL), archivos de estado, el manifiesto del archivo GoBD y todos los blobs referenciados. Los blobs se direccionan por SHA-256 y se transfieren una sola vez; una ejecución incremental solo sube los hashes nuevos. Todo se almacena cifrado en el formato NXB1 (AES-256-GCM por bloques, vinculado al nombre del objeto). El catálogo y el índice de blobs son JSON legible sin secretos; el catálogo está firmado con la clave Ed25519 de la exportación probatoria. El formato completo se encuentra en el repositorio en docs/protect/backup-format.md. A partir de Business; REST en /api/admin/protect/backups (administradores del servidor).

Referencia / configuración
<target>/                                 directory, SMB share or s3://bucket/nextxch-backup/
  nextxch-backup.json                       target marker
  keys/backup-key-<keyId>.json              public key + sealed private key
  keys/dk-<dataKeyId>.json                  data key of one run (ECDH wrapped)
  blobs/ab/cd/<sha256>.nxb                  one mail or file content, immutable
  versions/20261111T023000Z-a1b2c3/
    catalog.json  catalog.json.sig          catalog (written last = version complete) + signature
    blobs.ndjson.gz                         blob index of the version
    db/<table>.ndjson.gz.nxb                database snapshot, one file per table
    files/<path>.nxb                        state files of the data directory
    archive-manifest.json.gz.nxb            retention, legal hold, integrity chain

# Settings via REST (PUT /api/admin/protect/backups/settings):
{"verifyEveryHours":24,"verifySampleSize":50,"alertOnFailure":true,"uploadParallelism":4}

# Back up a domain or single mailboxes:
nextxch-cli backup run --target s3-fsn1 --scope domains:company.com,company.at
nextxch-cli backup run --target s3-fsn1 --scope mailboxes:anna@company.com --no-wait

5. Restaurar en el buzón: origen, momento, destino

Orígenes: archive (archivo GoBD), recoverable (elementos eliminados) y backup (copia de seguridad de datos). Elija el momento con --point (id de instantánea, day:yyyy-MM-dd o latest) o --as-of. Destinos: original (carpeta original), restored (predeterminado, carpeta "Wiederhergestellt yyyy-MM-dd", nombre mediante --label) o account (otro buzón del mismo inquilino, por ejemplo, un buzón sucesor). Los duplicados se omiten por SHA-256, Message-ID y UID; los orígenes no se modifican. Permitido para TenantAdmin y ServerAdmin, hasta 250.000 elementos por trabajo; trabajos a partir de Business, política y autoservicio en Webmail en todos los niveles.

Referencia / configuración
nextxch-cli restore points  --account anna@company.com --source backup
nextxch-cli restore browse  --account anna@company.com --source backup --point latest --folder INBOX --filter "invoice"
nextxch-cli restore preview --account anna@company.com --source archive --as-of 2026-10-31T23:59:59Z --folder "Projects/Plant"
nextxch-cli restore start   --account anna@company.com --source archive --as-of 2026-10-31T23:59:59Z \
  --folder "Projects/Plant" --target restored --label "Plant (restored)"

# Whole mailbox into a successor mailbox:
nextxch-cli restore start --account ben@company.com --source backup --point day:2026-11-01 \
  --target account --target-account successor@company.com --passphrase-env NEXTXCH_BACKUP_PASSPHRASE
nextxch-cli restore jobs --account ben@company.com

# REST: /api/compliance/restore (sources, points, browse, preview, jobs, policy)
# Webmail: GET /api/mail/self-restore, POST /api/mail/self-restore {"ids":[...]}

6. Recuperación bare-metal: una instalación nueva más la copia de seguridad le devuelve el servidor anterior

En una instalación nueva (MSI, Docker o Linux, como máximo un inquilino, un dominio, una cuenta y aún sin inicio de sesión de administrador), /setup/ muestra "Restaurar desde copia de seguridad" debajo del inicio de sesión: subir el paquete, frase de contraseña, vista previa, restaurar, opcionalmente la copia de seguridad de datos, finalizar y reiniciar. Acceso solo con el token de configuración de un solo uso que el primer arranque escribe en el registro y en {DataDirectory}/first-run/setup-token.txt (encabezado X-Nextxch-Setup-Token), o desde el propio servidor con Setup:TrustLoopback=true. El primer inicio de sesión de administrador o Finalizar cierra el asistente definitivamente. La clave de copia de seguridad del servidor anterior no se transfiere y debe configurarse de nuevo después. El índice de texto completo de SQLite no forma parte de la copia de seguridad: la búsqueda encuentra el correo restaurado después de una reindexación.

Referencia / configuración
# Headless via CLI (same API /api/setup):
export NEXTXCH_SETUP_TOKEN="$(cat /var/lib/nextxch/first-run/setup-token.txt)"
export NEXTXCH_BACKUP_PASSPHRASE='...'
nextxch-cli setup restore --config nextxch-config.zip --data s3://dr-bucket/nextxch/ --prune --dry-run
nextxch-cli setup restore --config nextxch-config.zip --data s3://dr-bucket/nextxch/ --prune --yes

# Unattended on first start (Docker Compose, Kubernetes, MSI):
environment:
  NEXTXCH_RESTORE_FROM: s3://dr-bucket/nextxch/          # .zip, directory, s3://, https:// or config-backup:<id>
  NEXTXCH_RESTORE_PASSPHRASE: ${BACKUP_PASSPHRASE}       # without: configuration without secrets
  NEXTXCH_RESTORE_DATA_FROM: s3://dr-bucket/nextxch/     # optional, location of the data backup
  NEXTXCH_RESTORE_PRUNE: "true"                          # remove bootstrap objects
  NEXTXCH_RESTORE_WITH_CREDENTIALS: "true"               # passwords, API keys, licence (default true)
  NEXTXCH_RESTORE_S3_ENDPOINT: https://fsn1.your-objectstorage.com
  NEXTXCH_RESTORE_S3_ACCESS_KEY: ${S3_KEY}
  NEXTXCH_RESTORE_S3_SECRET_KEY: ${S3_SECRET}
# Result: {DataDirectory}/pipeline-restore/first-start.json ("ok": true = variable is ignored afterwards)
# Helm: restore.from, restore.scope, restore.mapping, restore.passphrase, restore.s3.* (replicaCount: 1)

7. Despliegue por pipeline con restauración (nextxch-cli deploy --restore)

Un comando o un paso de pipeline reconstruye un servidor a partir de una copia de seguridad: aplicar la configuración, restaurar los datos, ejecutar comprobaciones (muestra de hashes, estado, correo de prueba solo a Mailpit o a un buzón local) y, opcionalmente, instrucciones para el cambio de DNS/MX; el DNS nunca se cambia automáticamente. Cada ejecución es idempotente y, tras una interrupción, se reanuda en el último paso finalizado. El archivo de mapeo (kind RestoreMapping, esquema en GET /api/v1/deploy/mapping-schema) reescribe nombres de host, direcciones IP y rutas, decide de dónde proceden los certificados (backup, acme, files) y describe la base de datos y el almacenamiento del nuevo host; los dominios de correo nunca se renombran. Inicio de sesión con una clave de integración con el alcance deploy.restore. La configuración en todos los niveles; la parte de datos a partir de Business (excepto en el primer arranque de una instalación nueva); la parte de datos abarca el alcance all.

Referencia / configuración
# mapping.yaml
apiVersion: nextxch/v1
kind: RestoreMapping
hostnames:
  mail.old-provider.example: mail.company.com
ips:
  203.0.113.10: 198.51.100.20
paths:
  "C:\\Data\\NextxchData": /var/lib/nextxch
certificates:
  mode: acme                      # backup | acme | files
  acme: {contactEmail: hostmaster@company.com}
database:
  provider: Postgres              # must match the new host (Storage__Provider)
  connectionStringEnv: NEXTXCH_PG_CONNECTION
storage:
  blobBackend: S3
  s3: {endpoint: https://fsn1.your-objectstorage.com, bucket: nextxch-mail}

# Plan (dry run, shows every replacement), then restore with checks:
nextxch-cli deploy --restore ./nextxch-config.zip --scope config --map mapping.yaml --dry-run
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --map mapping.yaml --test-mail mailpit --dns-instructions --yes

# REST: POST /api/v1/deploy/restore (dryRun defaults to true)
# {"source":"s3://dr-bucket/nextxch/","scope":"all","mapping":"...","dryRun":false,"testMail":"mailpit","hashSample":20}
# Local package: POST /api/v1/deploy/restore/upload (application/zip) -> source "upload:<sha256>"
# Runs: GET /api/v1/deploy/restore/runs

8. Plantillas de CI: GitHub Actions, GitLab CI, Azure DevOps y Ansible

Las plantillas se encuentran en el repositorio en deploy/ci: restauración con una fase de planificación y aprobación en el entorno de producción, además de una prueba de DR nocturna que restaura en un entorno desechable y escribe un informe con la duración (RTO) y el estado (RPO). Los secretos deben estar en variables de CI enmascaradas y protegidas; los correos de prueba van a un contenedor Mailpit junto al job y nunca salen de él.

Referencia / configuración
deploy/ci/github-actions/nextxch-restore.yml        plan on a throwaway instance, container with restore on first start, checks, DNS step
deploy/ci/github-actions/nextxch-dr-probe.yml       nightly DR probe with RTO/RPO report
deploy/ci/gitlab/.gitlab-ci.yml                     restore (RESTORE_SOURCE, RESTORE_SCOPE, PLAN_ONLY ...) + DR probe (NEXTXCH_PIPELINE=dr-probe)
deploy/ci/azure-devops/azure-pipelines.yml          restore with parameters, deployment job on environment production
deploy/ci/azure-devops/azure-pipelines-dr-probe.yml nightly DR probe, report in the run summary
deploy/ci/ansible/playbook-restore.yml              role nextxch_restore: container (Linux) or MSI (Windows)
deploy/ci/mapping.example.yaml, mapping.schema.json example and JSON Schema of the mapping file

9. Sincronización en vivo para un cambio de proveedor: una breve congelación en lugar de una larga interrupción

Tras la restauración completa, el nuevo servidor sigue al anterior con ejecuciones delta: el servidor anterior sigue escribiendo su copia de seguridad de datos (por ejemplo, cada hora en S3) y cada ejecución solo transfiere los blobs, filas de tablas y archivos de estado que hayan cambiado desde la última versión transferida. El progreso se encuentra en {DataDirectory}/pipeline-restore/live-sync.json; ejecutar de nuevo el mismo comando no cambia nada o reanuda el proceso. Para la migración definitiva, el servidor anterior se congela manualmente (bloquear los puertos de correo y de clientes en su firewall, mantener el servicio en ejecución, última copia de seguridad con nextxch-cli backup run --full) y, a continuación, --cutover --source-frozen transfiere esa copia de seguridad con una comparación completa de filas. Después, reinicie el nuevo servidor y cambie el DNS. A partir de Business; REST: POST /api/v1/deploy/live-sync, POST /api/v1/deploy/live-sync/cutover, GET /api/v1/deploy/live-sync.

Referencia / configuración
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --scope all --yes                          # 1. full restore (baseline)
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --live-sync --dry-run                      # remaining delta, changes nothing
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --live-sync --interval 5m --until-cutover  # 2. follow the old server
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --cutover                                  # 3. instructions for the freeze
# old server: block ports, then  nextxch-cli backup run --full
nextxch-cli deploy --restore s3://dr-bucket/nextxch/ --cutover --source-frozen                  # 4. last backup, last run

Configuración, valores predeterminados y buenas prácticas

Ajuste / ubicación Descripción Valor predeterminado Buena práctica de producción
Konfigurationssicherung: Versionen (#/protect/config) Versiones automáticas antes de cada actualización (AutoBeforeUpdate) y después de cambios (AutoAfterChanges, agrupadas tras DebounceMinutes), además de versiones manuales, importaciones y una instantánea de seguridad antes de cada restauración. KeepLast 30 · KeepDailyDays 90 · Debounce 10 min Antes de cambios importantes, cree una versión manual con etiqueta y guarde el .zip fuera del servidor.
Sicherungsschlüssel (Passphrase / Wiederherstellungsschlüssel) ECDH P-256; la parte privada solo existe sellada (PBKDF2-SHA256 con 600.000 iteraciones, AES-256-GCM) y viaja dentro de cada paquete. Sin clave y sin frase de contraseña, una copia de seguridad de la configuración no contiene secretos. nicht eingerichtet · Passphrase ab 12 Zeichen Imprima la clave de recuperación y guárdela separada del servidor; sin ella, las copias de seguridad de datos no se pueden leer.
Datensicherung: Aufbewahrung je Ziel Las KeepLast versiones más recientes, más la versión más reciente de cada una de las últimas KeepHourly horas, KeepDaily días, KeepWeekly semanas ISO y KeepMonthly meses (UTC). 3 / 24 / 7 / 4 / 12 Conserve al menos dos versiones durante una sincronización en vivo; de lo contrario, no se puede calcular el delta (BASELINE_GONE).
S3 Object Lock (ObjectLockMode, ObjectLockDays) Los objetos se escriben con el modo Governance o Compliance y una fecha retain-until; los blobs reutilizados reciben una fecha ampliada (ahora más 1,5 veces los días de bloqueo) para que ninguna versión apunte a un objeto que pueda eliminarse demasiado pronto. Normal · 30 Tage Para la protección contra ransomware, utilice el modo Compliance en un bucket dedicado con control de versiones; los objetos bloqueados solo los elimina una ejecución posterior una vez pasada su fecha.
Zeitpläne (Frequency, Type, Scope) Cada hora, cada día o cada semana, incremental o completa, por destino y alcance (servidor, dominios, buzones); hora local del servidor, sin expresión cron. Täglich 02:30 inkr. · Sonntag 03:30 voll Las programaciones preparadas no tienen destino al principio: asígneles un destino y actívelas; de lo contrario, no se ejecuta ninguna copia de seguridad.
Automatische Prüfung (VerifyEveryHours, VerifySampleSize) Comprueba sin la clave los hashes almacenados, los encabezados de sobre, los archivos de clave, la firma del catálogo y la legibilidad del catálogo y del índice de blobs; con la frase de contraseña se descifran además la muestra y todos los archivos de tabla. alle 24 h · 50 Objekte Mantenga AlertOnFailure activado para que las copias de seguridad y las verificaciones fallidas lleguen a los destinos de alerta.
Parallele Uploads je Sicherung (UploadParallelism) Número de subidas simultáneas a destinos S3 y de directorio. 4 (1 bis 32) Para S3 con conexiones rápidas, de 8 a 16; para un NAS con SMB lento, mejor de 2 a 4.
SQL Server: ALLOW_SNAPSHOT_ISOLATION nextxch intenta activar el aislamiento de instantánea al iniciarse. Si está desactivado, las tablas se exportan una a una con READ COMMITTED (consistency read-committed) y la ejecución informa de una advertencia. an, wenn erlaubt La vista general muestra la sentencia SQL para copiar; con aislamiento de instantánea (snapshot isolation), la instantánea de la base de datos es transaccionalmente coherente.
RecoverableItemsDays (restore-policy.json) Durante cuánto tiempo las citas, contactos, tareas y notas eliminados conservan su contenido; después solo queda una marca de eliminación vacía para la sincronización. El correo eliminado de forma reversible permanece hasta que se purga. 14 Tage (nach Upgrade 30) Anótelo en la documentación de procedimientos: sin una copia de seguridad de datos, los elementos de groupware eliminados pierden su contenido una vez transcurrido este plazo.
Selbstbedienung im Webmail (SelfServiceEnabled, SelfServiceDays) Los usuarios recuperan ellos mismos los correos y elementos de groupware eliminados en Restaurar elementos eliminados (hasta 500 por ejecución). Ajustable para todo el servidor o por dominio; 0 días significa sin ventana propia. an · 0 Tage Para dominios con normas estrictas, defina allí una ventana o desactive el autoservicio.
Beweisexport: Rollen, Umfang, Download ComplianceAuditor, TenantAdmin (solo el propio inquilino) y ServerAdmin pueden exportar; alcance search, mailbox, range o legalHold, hasta 100.000 mensajes (como máximo 250.000). El enlace de descarga es válido durante 24 horas. includeSoftDeleted true · 24 h Indique siempre una referencia de caso (caseReference): figura en el manifiesto firmado y en el registro de auditoría.
Setup:TrustLoopback Permite las solicitudes del propio servidor (loopback) al asistente de configuración sin el token de configuración. De forma predeterminada, cada solicitud necesita el token de first-run/setup-token.txt. false Actívelo solo en hosts sin otros usuarios locales; de lo contrario, pase el token mediante NEXTXCH_SETUP_TOKEN.
Audit-Log & GoBD Cada paso queda en el registro de auditoría: config.backup*, data.backup.*, Compliance.EvidenceExport*, Protect.Restore*, Protect.SelfRestore, Protect.RestorePolicy, setup.* y config.restore; visible en Backup & Recovery > Registro. Ninguna restauración modifica el archivo GoBD. aktiv La copia de seguridad de datos contiene el manifiesto del archivo con retención y conservación legal (legal hold); tras una restauración se comprueba cada hash archivado y se vuelven a establecer los bloqueos.