PUNTOS CLAVE
- No existe una herramienta única que combine backups diferenciales/incrementales puros con estructura de archivos plana y soporte FTP nativo. Hay que elegir qué compromiso asumir.
- rdiff-backup es la opción más cercana: el último backup es un directorio navegable normal; los históricos se guardan como diffs. No soporta FTP nativo; requiere SSH en ambos extremos.
- rsnapshot (wrapper de rsync con
--link-dest) ofrece snapshots completamente navegables usando hard links. Para FTP es necesario montar el destino vía curlftpfs. - El problema de fondo es arquitectónico: los diferenciales eficientes necesitan un índice. La estructura plana y los diferenciales son dos objetivos que tiran en direcciones contrarias.
- La solución práctica más robusta para FTP real es combinar lftp (mirror + sincronización incremental) con scripts de rotación de carpetas con timestamp.
El backup diferencial en Linux con estructura de archivos plana es uno de esos requisitos que parece razonable sobre el papel, pero que choca con una realidad arquitectónica bastante incómoda: los motores de backup diferenciales eficientes necesitan algún tipo de índice o base de datos para saber qué ha cambiado. Y en el momento en que hay un índice, ya no tienes una estructura completamente plana.
He visto esta pregunta en foros técnicos varias veces, y la respuesta honesta es que tienes que elegir en qué punto del espectro te quedas. Este artículo revisa las opciones reales, sin omitir las limitaciones que casi nadie menciona.
¿Existe algún software de backup para Linux con estructura de archivos plana y backups diferenciales?
#Por qué estos dos requisitos se pelean entre sí
Antes de entrar en herramientas concretas, conviene entender por qué la combinación que se menciona en este post es difícil de encontrar. No es una cuestión de que nadie haya pensado en hacerlo; es que las dos propiedades tienen necesidades técnicas contradictorias.
Un backup diferencial o incremental tiene que saber, en el momento de ejecutarse, qué archivos han cambiado desde el último backup. Para saberlo sin leer todos los archivos del origen byte a byte —lo cual sería absurdamente lento—, necesita algún mecanismo de seguimiento: un hash de cada archivo, un árbol de metadatos, una base de datos de estados anteriores. Eso es, por definición, un repositorio.
La estructura plana, en cambio, implica que el destino no tiene nada propio: los archivos están ahí tal cual, sin capas de abstracción encima. Cuando combinas ambas cosas, el resultado es siempre un compromiso: o la estructura plana no es completamente plana (hay metadatos auxiliares), o los diferenciales no son tan eficientes (necesitas comparar archivos en lugar de consultar una base de datos).
TÉRMINO RELACIONADO
#rdiff-backup: el más cercano a lo que buscas
rdiff-backup es probablemente la herramienta que mejor se aproxima al equilibrio que describes, aunque con matices importantes que conviene conocer antes de montarlo en producción.
El mecanismo es elegante: el directorio de destino contiene siempre una copia exacta y navegable de la última versión de tus datos. Puedes abrirlo con el gestor de archivos, hacer un ls, copiar archivos directamente sin necesitar el software de backup. Hasta aquí, perfecto.
Los históricos (versiones anteriores) se almacenan en un subdirectorio oculto llamado rdiff-backup-data, que contiene diffs inversos. Cada vez que ejecutas un nuevo backup, rdiff-backup actualiza la copia actual y genera el diff que permite reconstruir el estado anterior. El resultado es que el presente es siempre accesible de forma directa, y el pasado requiere el software para restaurarlo.
# Instalación en Ubuntu/Debian
sudo apt install rdiff-backup
# Backup local básico
rdiff-backup /ruta/origen/ /mnt/disco_backup/mi_backup/
# Backup remoto vía SSH (requiere rdiff-backup en el servidor destino)
rdiff-backup /ruta/origen/ usuario@servidor-remoto::/ruta/backup/
# Listar todos los incrementos disponibles
rdiff-backup list increments /mnt/disco_backup/mi_backup/
# Restaurar a un estado de hace 7 días
rdiff-backup restore --restore-as-of 7D /mnt/disco_backup/mi_backup/ /ruta/restauracion/
# Limpiar incrementos con más de 30 días de antigüedad
rdiff-backup remove older-than 30D /mnt/disco_backup/mi_backup/El problema con FTP es directo: rdiff-backup no soporta FTP ni SFTP de forma nativa. Requiere SSH en ambos extremos y, además, que el software esté instalado en el servidor de destino. Si tu destino es un servidor FTP sin capacidad de instalar software, rdiff-backup no te vale para ese escenario remoto. Sí funciona perfectamente para backups locales o a servidores con acceso SSH completo.
PROBLEMA COMÚN
#rsnapshot y el truco de los hard links
La segunda opción seria es rsnapshot, un wrapper alrededor de rsync que automatiza lo que se conoce coloquialmente como «snapshots con hard links». La idea es tan simple como efectiva.
Cada vez que ejecutas un backup, rsnapshot crea un directorio con fecha (daily.0, daily.1, etc.). Si un archivo no ha cambiado respecto al backup anterior, en lugar de copiarlo de nuevo, crea un hard link al mismo inodo en el backup anterior. En disco solo existe una copia del dato; en el sistema de ficheros, aparece en ambos directorios.
El resultado desde el punto de vista del usuario es que cada directorio de backup parece una copia completa, independiente y navegable. Puedes ir a daily.3 y abrir cualquier archivo directamente. Sin software. Sin restauración previa. La eficiencia en disco la gestiona el sistema operativo mediante los hard links.
# Instalación
sudo apt install rsnapshot
# Configuración mínima en /etc/rsnapshot.conf
# (los campos separados por tabuladores, no espacios)
snapshot_root /mnt/backup/snapshots/
retain daily 7
retain weekly 4
backup /home/usuario/datos/ localhost/
# Ejecución manual de backup diario
rsnapshot daily
# Automatización vía cron: añadir a /etc/cron.d/rsnapshot
0 2 * * * root /usr/bin/rsnapshot daily
0 3 * * 1 root /usr/bin/rsnapshot weeklyLas limitaciones también son reales. Los hard links solo funcionan dentro del mismo sistema de ficheros; no puedes crear un hard link entre particiones diferentes, y mucho menos hacia un servidor remoto. Para FTP, la única vía es montar el servidor FTP como un directorio local mediante curlftpfs antes de que rsnapshot empiece a trabajar. Funciona, pero con matices.
# Instalar curlftpfs para montar el servidor FTP
sudo apt install curlftpfs
# Crear punto de montaje
sudo mkdir /mnt/servidor_ftp
# Montar el servidor FTP (con credenciales en el comando, solo para test)
sudo curlftpfs ftp://usuario:contraseña@ftp.mi-servidor.com/ /mnt/servidor_ftp/
# Para producción, usar credenciales en ~/.netrc (permisos 600)
# y montar sin credenciales en el comando:
sudo curlftpfs ftp://ftp.mi-servidor.com/ /mnt/servidor_ftp/
# Verificar el montaje
ls /mnt/servidor_ftp/
# Desmontar cuando termines
sudo fusermount -u /mnt/servidor_ftp/NOTA TÉCNICA
#lftp: la solución directa para FTP real
Si el requisito de FTP es innegociable y quieres algo que funcione de verdad, lftp merece más protagonismo del que suele recibir en estas discusiones.
lftp tiene un modo mirror que sincroniza un directorio local contra un servidor FTP, copiando solo los archivos que han cambiado (comparando tamaño y fecha de modificación). No es un diferencial en el sentido académico del término —no usa hashes ni índices sofisticados—, pero en la práctica transfiere solo los cambios reales, que es lo que la mayoría de usuarios necesita.
# Instalación
sudo apt install lftp
# Mirror del servidor FTP hacia un directorio local (descarga)
lftp -e "mirror --continue --parallel=4 /remoto/ /local/backup/; quit" \
-u usuario,contraseña ftp://ftp.mi-servidor.com
# Mirror inverso: subir cambios locales al servidor FTP (upload)
lftp -e "mirror --reverse --continue --delete --parallel=4 /local/origen/ /remoto/; quit" \
-u usuario,contraseña ftp://ftp.mi-servidor.com
# Script de backup con rotación de carpetas con timestamp
#!/bin/bash
FECHA=$(date +%Y-%m-%d_%H%M)
DESTINO="/mnt/backup/${FECHA}"
mkdir -p "$DESTINO"
lftp -e "mirror --continue /datos_remotos/ ${DESTINO}/; quit" \
-u $FTP_USER,$FTP_PASS ftp://$FTP_HOST
# Mantener solo los últimos 7 backups
ls -td /mnt/backup/*/ | tail -n +8 | xargs rm -rfLa estructura de destino es completamente plana: cada carpeta con timestamp contiene una copia navegable de los datos en ese momento. No hay repositorio, no hay base de datos, no hay software necesario para abrir los archivos.
TIP PRO
--link-dest para obtener lo mejor de ambos mundos: usa lftp para descargar desde FTP al servidor local, y luego rsync con --link-dest para generar snapshots con hard links de esa copia local. El resultado es backups navegables eficientes en disco sin necesidad de repositorio propietario.#Comparativa real de herramientas
| Herramienta | Estructura plana | Diferencial/Incremental | FTP nativo | Programable | Licencia |
|---|---|---|---|---|---|
| rdiff-backup | ✓ (último backup) | ✓ (diffs inversos) | ✗ (SSH requerido) | ✓ (cron/systemd) | GPL v2 |
| rsnapshot | ✓ (todos los snapshots) | ✓ (hard links) | ⚠ (via curlftpfs) | ✓ (cron/systemd) | GPL v2 |
| lftp mirror | ✓ (copia directa) | ⚠ (por fecha/tamaño) | ✓ | ✓ (script + cron) | GPL v3 |
rsync + --link-dest |
✓ (todos los snapshots) | ✓ (hard links) | ⚠ (via curlftpfs) | ✓ (script + cron) | GPL v3 |
| Duplicity | ✗ (tar.gz cifrados) | ✓ (diferencial real) | ✓ | ✓ (cron/systemd) | GPL v2 |
| BorgBackup | ✗ (repositorio) | ✓ (deduplicación) | ✗ | ✓ | BSD |
#¿Cuál te conviene?
La respuesta depende de qué requisito de tu lista es innegociable.
Si el FTP es un nice-to-have y tu servidor destino tiene SSH: Ve directamente a rdiff-backup o rsnapshot. Ambos son maduros, bien documentados y cumplen todos tus demás requisitos. rdiff-backup es más elegante (el último backup es siempre accesible directamente); rsnapshot te da acceso directo a todos los snapshots históricos sin excepción.
Si el FTP es imprescindible y el destino es un servidor FTP puro sin SSH: La opción más limpia es lftp con rotación de carpetas mediante script. No es un diferencial en sentido estricto, pero en la práctica transfiere solo los cambios y la estructura de destino es completamente navegable. Añadir hard links sobre una copia local previa con rsync da el paso hacia snapshots más eficientes.
Si quieres diferencial real con FTP y te da igual la estructura plana: Duplicity es la única que combina FTP nativo con backups diferenciales auténticos. El inconveniente es que los archivos se guardan en formato .tar.gz (aunque sin cifrado si no lo configuras) y necesitas el software para restaurar. Es un precio razonable a pagar.
#La arquitectura híbrida que funciona en producción
La solución que personalmente recomendaría para quien tiene el requisito de FTP y quiere estructura plana es un esquema de dos pasos, sin magia:
- Usar lftp mirror para sincronizar el servidor FTP hacia un directorio local en tu máquina de backup. Programarlo cada noche.
- Sobre esa copia local, ejecutar rsync con
--link-destpara generar un snapshot con timestamp. Los archivos sin cambios quedan como hard links; los nuevos o modificados se copian.
#!/bin/bash
# Script de backup híbrido: FTP → local → snapshots con hard links
# Guardar como /usr/local/bin/backup_ftp.sh y dar permisos de ejecución
set -e
FTP_HOST="ftp.mi-servidor.com"
FTP_USER="mi_usuario"
FTP_PASS="mi_contraseña"
FTP_RUTA="/datos"
STAGING="/var/backup/staging" # Espejo local del FTP
SNAPSHOTS="/var/backup/snapshots" # Directorio de snapshots navegables
FECHA=$(date +%Y-%m-%d_%H%M)
SNAPSHOT_NUEVO="${SNAPSHOTS}/${FECHA}"
SNAPSHOT_ULTIMO="${SNAPSHOTS}/ultimo"
# Paso 1: Sincronizar FTP hacia directorio staging local
# Solo transfiere archivos nuevos o modificados (por fecha/tamaño)
lftp -e "mirror --continue --delete --parallel=4 ${FTP_RUTA}/ ${STAGING}/; quit" \
-u "${FTP_USER},${FTP_PASS}" "ftp://${FTP_HOST}"
# Paso 2: Crear snapshot con hard links usando rsync
# Los archivos sin cambios quedan como hard links al snapshot anterior
rsync -a \
--link-dest="${SNAPSHOT_ULTIMO}" \
"${STAGING}/" \
"${SNAPSHOT_NUEVO}/"
# Actualizar el enlace simbólico al último snapshot
ln -sfn "${SNAPSHOT_NUEVO}" "${SNAPSHOT_ULTIMO}"
# Mantener solo los últimos 14 snapshots
ls -1dt "${SNAPSHOTS}"/20*/ 2>/dev/null | tail -n +15 | xargs -r rm -rf
echo "Backup completado: ${SNAPSHOT_NUEVO}"La clave de este script está en que --link-dest apunta siempre al snapshot anterior. rsync compara el estado actual del staging con ese snapshot y crea hard links para lo que no ha cambiado. El resultado es que cada carpeta en snapshots/ parece un backup completo y navegable, pero en disco solo ocupa el espacio de los cambios reales.
Esto lo escribo en julio de 2026, con las versiones estables actuales de lftp 4.9.x y rsync 3.2.x disponibles en los repositorios de Ubuntu 24.04. El comportamiento de curlftpfs y la integración con servidores FTP de hosting compartido puede variar bastante según el proveedor; hay servidores que no exponen correctamente las fechas de modificación vía FTP, lo que rompe la detección de cambios de lftp. En ese escenario, la única alternativa es usar hashes, lo que implica descargar todo el contenido para comparar, o aceptar un Duplicity sin estructura plana.
#Caso real: backup de un hosting compartido con FTP obligatorio
Vi este escenario exacto hace un par de años con un cliente que tenía un hosting compartido antiguo donde el proveedor (uno de esos que todavía sobreviven cobrando por FTP puro sin acceso SSH) no permitía ninguna conexión que no fuera FTP o FTPS.
Al principio intenté resolver el problema con curlftpfs más rsnapshot. Funcionaba en laboratorio, pero en producción el montaje FUSE perdía la conexión durante transferencias largas y dejaba el punto de montaje en estado zombie. Los backups terminaban corrompidos o incompletos sin que el script de cron lo detectara. Que ocurra a las 3 de la madrugada y lo descubras solo cuando intentas restaurar algo urgente es el tipo de experiencia que te queda grabada.
La solución final fue exactamente el esquema de dos pasos descrito arriba, con lftp para la parte FTP y rsync con hard links para los snapshots locales. Llevan funcionando sin incidencias desde entonces. El cliente puede conectarse al servidor local y abrir cualquier archivo de cualquier snapshot directamente. Y si el servidor FTP falla, tiene 14 días de histórico navegable sin depender de ningún software de restauración.
#¿Qué instalo, entonces?
Depende de tu escenario concreto, y no hay una respuesta única que valga para todos los casos.
rdiff-backup si tienes SSH en el destino y quieres la solución más limpia con acceso directo al último backup y diffs históricos en una subcarpeta oculta.
rsnapshot si quieres todos los snapshots históricos completamente navegables y tu destino es local o accesible vía SSH. La configuración inicial es algo más verbosa pero el resultado es muy sólido.
lftp + rsync con hard links si el FTP es obligatorio y quieres la estructura plana completa. Requiere scripting manual, pero es predecible, sin dependencias de repositorio y fácil de diagnosticar cuando algo falla.
Lo que no recomendaría para producción es curlftpfs como pieza central de la cadena de backup en entornos donde la conexión de red no sea perfectamente estable. Los filesystems FUSE sobre conexiones de red que se cortan son una fuente inagotable de estados inconsistentes, y un backup que falla silenciosamente es peor que no tener backup.
Si tienes la posibilidad de convencer a tu proveedor de hosting de habilitar SFTP o SSH, hazlo. El ecosistema de herramientas con soporte SSH es infinitamente más robusto que el de FTP puro, y la diferencia en fiabilidad es notable. Cualquier sysadmin que haya tenido que depurar un backup roto a través de FTP a las 2 de la tarde sabe de lo que hablo.