Problema

En entornos de self‑hosting es frecuente combinar varios repositorios de respaldo (NAS, servidores remotos, contenedores LXC) y usar la opción mirror de Zerobyte para mantener copias idénticas. Cuando se configura un backup scheduler que escribe en un repositorio SFTP y, a la vez, se intenta replicar ese mismo backup a otro repositorio SFTP con credenciales distintas, Zerobyte muestra el mensaje:

Both use SFTP backends with different credentials. Consider creating a new backup scheduler with the desired destination instead.

El síntoma impide que la cadena de espejo (mirror) funcione y obliga a recurrir a soluciones ad‑hoc como bind mounts o copias manuales. El problema no es exclusivo de una instalación concreta; ocurre siempre que Zerobyte intenta enlazar dos destinos SFTP bajo el mismo scheduler.

Causa

Zerobyte (basado en Restic) modela cada scheduler como una única definición de repositorio. La lógica interna verifica que, si el destino es SFTP, todas las rutas que participan en la operación compartan el mismo cliente SSH. Cuando se detectan dos backends SFTP con claves o usuarios diferentes, el motor aborta para evitar inconsistencias de permisos y posibles colisiones de metadatos.

Las causas típicas son:

  1. Credenciales distintas: usuario/clave SSH o clave privada diferentes entre los dos servidores.
  2. Configuración implícita de host distinto: aunque la clave sea la misma, el nombre de host o la IP varían y el cliente SSH crea sesiones separadas.
  3. Uso de la misma scheduler para varios destinos: Zerobyte no permite mezclar varios backends SFTP bajo una única definición; cada backend debe pertenecer a su propio scheduler.
  4. Montajes NFS vs SFTP: combinar un repositorio NFS (montado directamente) con otro SFTP dentro del mismo scheduler también dispara la validación, aunque el error mencione “different credentials”.

Solución

1. Separar los destinos en schedulers independientes

La forma más limpia es crear un scheduler para cada repositorio SFTP y luego encadenarlos mediante la opción mirror a nivel de job (no de scheduler). En la UI de Zerobyte:

  1. Crear Scheduler A → repositorio SFTP 1 (por ejemplo, user1@nas1:/backups).
  2. Crear Scheduler B → repositorio SFTP 2 (por ejemplo, user2@nas2:/mirror).
  3. En el job que respalda la fuente, seleccionar Scheduler A como origen y habilitar Mirror to Scheduler B.

Esto mantiene cada backend con su propio cliente SSH y elimina la colisión de credenciales.

2. Re‑usar la misma clave y usuario

Si la política de seguridad lo permite, crear una cuenta de servicio única en ambos servidores y usar la misma clave privada. Con la misma identidad, Zerobyte reconoce ambos destinos como el mismo backend y permite el espejo. Pasos rápidos:

# Generar clave única (si no existe)
ssh-keygen -t ed25519 -f ~/.ssh/zerobyte_id -N ""

# Copiar a ambos servidores
ssh-copy-id -i ~/.ssh/zerobyte_id user@nas1
ssh-copy-id -i ~/.ssh/zerobyte_id user@nas2

En la configuración del scheduler, apuntar ambos a user@host:/path usando ~/.ssh/zerobyte_id como private key.

3. Utilizar un bind mount o NFS para el espejo

Cuando la política de credenciales no permite unificar usuarios, montar el repositorio remoto como un punto de montaje local (NFS, CIFS o sshfs) y usar ese punto como destino del espejo. El flujo es:

  • Montar nas2:/mirror en /mnt/remote-mirror (por ejemplo, con sshfs).
  • Configurar el scheduler de espejo para apuntar a /mnt/remote-mirror (tipo local).

Esto evita que Zerobyte vea dos backends SFTP simultáneos. La desventaja es la dependencia del montaje activo durante la ejecución del job.

4. Emplear Restic directamente para la replicación

Zerobyte expone la línea de comandos de Restic. Se puede lanzar un comando Restic que copie de un repositorio a otro:

restic -r sftp:user1@nas1:/backups \
       -p ~/.ssh/zerobyte_id \
       copy sftp:user2@nas2:/mirror

Programar este comando como cron job independiente del scheduler de Zerobyte permite replicar sin tocar la UI.

Cuándo aplicar esta solución

  • Múltiples repositorios SFTP con credenciales diferentes: la separación de schedulers es la opción predeterminada.
  • Política de seguridad restrictiva: usar bind mount o sshfs es útil cuando no se pueden compartir claves.
  • Entornos con alta disponibilidad: crear schedulers independientes facilita la monitorización y el reinicio individual.
  • Necesidad de auditoría por repositorio: al tener schedulers separados, los logs de cada destino quedan aislados.

No es necesario aplicar estas medidas si:

  • Solo se usa un único repositorio SFTP.
  • Se emplea NFS o CIFS para todos los destinos (no hay backends SFTP múltiples).
  • La infraestructura ya cuenta con una cuenta de servicio unificada.

Código

# 1. Generar clave única (si no existe)
ssh-keygen -t ed25519 -f ~/.ssh/zerobyte_id -N ""

# 2. Copiar la clave a ambos servidores
ssh-copy-id -i ~/.ssh/zerobyte_id user@nas1
ssh-copy-id -i ~/.ssh/zerobyte_id user@nas2

# 3. Crear Scheduler A (ejemplo JSON)
cat > /etc/zerobyte/schedulers/sched_a.json <<EOF
{
  "name": "NAS1_SFTP",
  "backend": {
    "type": "sftp",
    "host": "nas1",
    "user": "user",
    "path": "/backups",
    "private_key": "/root/.ssh/zerobyte_id"
  }
}
EOF

# 4. Crear Scheduler B
cat > /etc/zerobyte/schedulers/sched_b.json <<EOF
{
  "name": "NAS2_SFTP",
  "backend": {
    "type": "sftp",
    "host": "nas2",
    "user": "user",
    "path": "/mirror",
    "private_key": "/root/.ssh/zerobyte_id"
  }
}
EOF

# 5. Definir job que usa Scheduler A y espejo a Scheduler B (JSON)
cat > /etc/zerobyte/jobs/backup_unas.json <<EOF
{
  "source": "/mnt/unas",
  "scheduler": "NAS1_SFTP",
  "mirror_to": "NAS2_SFTP",
  "options": {
    "compression": "auto",
    "exclude": ["*.tmp"]
  }
}
EOF

Verificación

  1. Comprobar que los schedulers se cargan sin errores

    zerobyte scheduler list
    

    Debe aparecer NAS1_SFTP y NAS2_SFTP sin mensajes de “different credentials”.

  2. Ejecutar el job manualmente

    zerobyte job run backup_unas
    

    Observar que la salida muestra dos fases: backup a NAS1 y espejo a NAS2.

  3. Validar la integridad en ambos repositorios

    restic -r sftp:user@nas1:/backups snapshots
    restic -r sftp:user@nas2:/mirror snapshots
    

    Los listados de snapshots deben coincidir.

  4. Revisar logs

    journalctl -u zerobyte -f
    

    No debe aparecer el mensaje de credenciales distintas.

Notas adicionales

  • Rotación de claves: si cambias la clave privada, actualiza ambos schedulers simultáneamente; de lo contrario volverás a encontrarte con el mismo error.
  • Performance: la replicación vía SFTP puede ser limitada por la latencia de la red. Si el espejo es crítico, considera montar el destino remoto con sshfs -C (compresión) para reducir el tiempo de transferencia.
  • Backup de configuración: guarda los archivos JSON de schedulers y jobs en un repositorio Git; así puedes restaurar rápidamente la configuración después de una caída del host.
  • LXC isolation: cuando Zerobyte corre dentro de un contenedor LXC, asegúrate de que el contenedor tenga acceso a /root/.ssh o al directorio de claves que hayas especificado. De lo contrario el cliente SSH fallará antes de que se detecte la colisión de credenciales.