La perdida de datos no es cuestion de si ocurrira, sino de cuando. El hardware falla, el ransomware cifra y el error humano borra. La unica proteccion confiable es una estrategia de respaldo automatizada y probada. rsync es una de las herramientas mas poderosas y flexibles disponibles en Linux para este proposito — solo transfiere las diferencias entre origen y destino, funciona perfectamente sobre SSH y soporta respaldos tipo snapshot que lucen como copias completas mientras consumen una fraccion del espacio en disco.
Esta guia cubre todo lo necesario para disenar, implementar y automatizar una estrategia de respaldo con rsync de nivel produccion para tus servidores Linux.
Que Es Rsync?
Rsync (Remote Sync) es una utilidad de copia de archivos rapida y versatil para sistemas Linux y Unix. Originalmente escrita por Andrew Tridgell y Paul Mackerras, utiliza un algoritmo de transferencia delta que envia solo las diferencias entre los archivos de origen y los archivos existentes en el destino. Esto lo hace significativamente mas eficiente que herramientas como cp o scp para respaldos recurrentes.
Caracteristicas principales:
- Transferencias delta — solo se envian los bytes modificados, no archivos completos
- Preservacion de metadatos — permisos, propiedad, marcas de tiempo, enlaces simbolicos
- Integracion SSH — transferencias cifradas a servidores remotos de forma nativa
- Soporte de enlaces duros — permite respaldos tipo snapshot eficientes en disco
- Filtrado flexible — patrones de inclusion/exclusion para control granular
# Verificar si rsync esta instalado y su version
rsync --version
Si rsync no esta instalado:
# Debian/Ubuntu
sudo apt update && sudo apt install -y rsync
# RHEL/CentOS/Fedora
sudo dnf install -y rsync
Por Que Rsync para Respaldos?
Hay muchas herramientas de respaldo disponibles — tar, cp, scp, Duplicity, Borg, Restic — entonces, por que elegir rsync?
- Velocidad: Despues de la copia completa inicial, las ejecuciones subsecuentes transfieren solo los datos modificados. Un respaldo de 500 GB donde cambiaron 2 GB toma segundos, no horas.
- Simplicidad: rsync es un solo comando con opciones bien documentadas. Sin formato propietario, sin base de datos de deduplicacion que pueda corromperse.
- Transparencia: Los respaldos son archivos y directorios simples. Puedes navegar, buscar con grep y restaurar con herramientas Unix estandar — no se necesita una utilidad especial de restauracion.
- Universalidad: rsync esta disponible en cada distribucion Linux, macOS e incluso Windows (via WSL o Cygwin). Ya viene instalado en la mayoria de los servidores.
- Componibilidad: rsync se integra limpiamente con cron, temporizadores systemd, SSH y scripts de shell.
La desventaja es que rsync no proporciona cifrado en reposo, deduplicacion entre respaldos ni una base de datos de catalogo de forma nativa. Para esas funciones, considera Borg o Restic. Pero para respaldos directos, confiables y transparentes, rsync es dificil de superar.
Prerrequisitos
Antes de implementar las estrategias en esta guia, asegurate de tener:
- Dos sistemas Linux — un servidor de origen (produccion) y un destino de respaldo (disco local, NAS o servidor remoto)
- rsync instalado en origen y destino (version 3.1+ recomendada)
- Autenticacion SSH basada en llaves configurada entre origen y destino para transferencias automatizadas sin contrasena (consulta nuestra Guia de Endurecimiento SSH)
- Espacio en disco suficiente en el destino — minimo 1.5 veces el tamano de los datos que vas a respaldar
- Acceso root o sudo en ambas maquinas si necesitas preservar la propiedad y atributos especiales de archivos
# Verificar la version de rsync en ambas maquinas
rsync --version | head -1
# Verificar que la autenticacion SSH con llave funciona sin solicitar contrasena
ssh -o BatchMode=yes user@backup-server echo "SSH key auth works"
Sintaxis Basica y Opciones de Rsync
La sintaxis general de rsync es:
rsync [OPCIONES] ORIGEN DESTINO
Entender las banderas mas importantes es esencial antes de construir una estrategia de respaldo:
# Modo archivo: preserva permisos, propiedad, marcas de tiempo, symlinks, dispositivos
rsync -a /origen/ /destino/
# Archivo + detallado + tamanos legibles + progreso
rsync -avhP /origen/ /destino/
# Ejecucion en seco -- muestra lo que se transferiria sin hacer cambios
rsync -avhn /origen/ /destino/
Detalle critico: las barras finales importan.
/origen/(con barra final) copia el contenido del directorio./origen(sin barra final) copia el directorio en si. Este es uno de los errores mas comunes con rsync.
# Copia el contenido de /var/www/ dentro de /backup/www/
rsync -avh /var/www/ /backup/www/
# Copia el directorio /var/www (como subdirectorio) dentro de /backup/
# Resultado: /backup/www/
rsync -avh /var/www /backup/
Respaldos Locales
La estrategia rsync mas simple es un respaldo local a un disco o particion separada. Esto protege contra eliminacion accidental y corrupcion del sistema de archivos (pero no contra falla del hardware de toda la maquina).
# Espejo de /home a un disco externo montado en /mnt/backup
rsync -avh --delete /home/ /mnt/backup/home/
La bandera --delete es importante: elimina archivos del destino que ya no existen en el origen, manteniendo el respaldo como un espejo exacto. Sin ella, los archivos eliminados se acumulan en el respaldo indefinidamente.
# Respaldar multiples directorios en un solo comando
rsync -avh --delete \
/etc/ \
/var/www/ \
/home/ \
/mnt/backup/
# Respaldo con archivo de log para auditoria
rsync -avh --delete --log-file=/var/log/rsync-backup.log \
/home/ /mnt/backup/home/
Para respaldos a nivel de sistema que incluyen archivos de dispositivo y atributos especiales:
# Respaldo completo del sistema (requiere root)
sudo rsync -aAXvh --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
/ /mnt/backup/system/
Las banderas -aAX preservan modo archivo (-a), ACLs (-A) y atributos extendidos (-X), que son necesarios para un respaldo completo del sistema.
Respaldos Remotos por SSH
Los respaldos remotos protegen contra fallas de hardware local, incendios, robos y otros desastres fisicos. rsync usa SSH como transporte predeterminado para transferencias remotas, proporcionando cifrado sin configuracion adicional.
# Respaldo tipo push: enviar datos locales a un servidor remoto
rsync -avhz -e ssh /var/www/ backupuser@192.168.1.100:/backup/www/
# Respaldo tipo pull: traer datos de un servidor remoto al local
rsync -avhz -e ssh backupuser@192.168.1.100:/var/www/ /backup/www/
La bandera -z habilita compresion durante la transferencia, lo cual es beneficioso en enlaces de red mas lentos. En una red gigabit local, la compresion puede ralentizar las cosas debido a la sobrecarga de CPU.
Para usar un puerto SSH no estandar o una llave especifica:
# Usar un puerto SSH personalizado y archivo de identidad
rsync -avhz -e "ssh -p 2222 -i /home/backupuser/.ssh/backup_key" \
/var/www/ backupuser@remote:/backup/www/
Para respaldos automatizados, la llave SSH no debe tener frase de paso (o usar ssh-agent). Restringe la llave de respaldo en el servidor remoto para limitar sus capacidades:
# En el servidor remoto, en ~backupuser/.ssh/authorized_keys:
# Restringir la llave solo a rsync
command="rsync --server --sender -vlogDtprze.iLsfxCIvu . /backup/",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3Nz... backup@source
Respaldos Incrementales con —link-dest (Estilo Snapshot)
Esta es la estrategia de respaldo rsync mas poderosa. Usando --link-dest, puedes crear lo que parece un respaldo completo cada dia, pero solo los archivos modificados consumen espacio adicional en disco. Los archivos sin cambios se enlazan con enlaces duros al respaldo anterior.
Como funciona:
- rsync compara cada archivo de origen con el archivo correspondiente en el directorio
--link-dest - Si un archivo no ha cambiado, rsync crea un enlace duro (cero espacio adicional)
- Si un archivo ha cambiado o es nuevo, rsync lo copia normalmente
- El resultado es un directorio que luce y se comporta como un respaldo completo
# Crear un respaldo tipo snapshot
DATE=$(date +%Y-%m-%d_%H-%M-%S)
DEST="/backup/snapshots/$DATE"
LATEST="/backup/snapshots/latest"
rsync -avh --delete \
--link-dest="$LATEST" \
/home/ "$DEST/"
# Actualizar el symlink "latest"
rm -f "$LATEST"
ln -s "$DEST" "$LATEST"
El uso de disco es notable. Considera un conjunto de datos de 100 GB donde el 1% cambia diariamente:
| Dia | Tamano Aparente | Uso Real de Disco |
|---|---|---|
| Dia 1 (completo) | 100 GB | 100 GB |
| Dia 2 | 100 GB | ~1 GB (solo datos nuevos) |
| Dia 3 | 100 GB | ~1 GB |
| 30 dias total | 3,000 GB aparentes | ~129 GB reales |
Cada directorio de snapshot es completamente navegable con herramientas estandar. Puedes hacer cd al respaldo de cualquier dia y ver el estado completo de tus archivos en ese momento.
# Navegar el respaldo de hace 5 dias
ls /backup/snapshots/2026-01-17_02-00-00/home/jc/documents/
# Restaurar un archivo especifico de hace 3 dias
cp /backup/snapshots/2026-01-19_02-00-00/home/jc/report.pdf /home/jc/report.pdf
# Verificar uso real de disco por snapshot (muestra solo datos unicos)
du -sh /backup/snapshots/*/
Patrones de Exclusion y Filtros
No todo necesita ser respaldado. Excluir archivos temporales, caches y artefactos de compilacion ahorra tiempo y espacio en disco.
# Patrones de exclusion en linea
rsync -avh --delete \
--exclude='*.tmp' \
--exclude='*.log' \
--exclude='.cache/' \
--exclude='node_modules/' \
--exclude='__pycache__/' \
/home/ /backup/home/
Para reglas de exclusion complejas, usa un archivo de exclusion:
# Crear /etc/rsync-excludes.txt
cat > /etc/rsync-excludes.txt << 'EOF'
# Archivos temporales y de cache
*.tmp
*.swp
*.swo
*~
.cache/
.thumbnails/
# Artefactos de compilacion
node_modules/
vendor/
__pycache__/
*.pyc
target/
build/
dist/
# Archivos del sistema que no deben respaldarse
/proc/
/sys/
/dev/
/run/
/tmp/
/mnt/
/media/
/lost+found/
# Archivos multimedia grandes (opcional)
# *.iso
# *.mp4
EOF
# Usar el archivo de exclusion
rsync -avh --delete --exclude-from=/etc/rsync-excludes.txt \
/home/ /backup/home/
rsync tambien soporta combinaciones de inclusion/exclusion para control mas granular:
# Solo respaldar archivos .conf y .sh de /etc
rsync -avh \
--include='*/' \
--include='*.conf' \
--include='*.sh' \
--exclude='*' \
/etc/ /backup/etc-configs/
Limitacion de Ancho de Banda y Compresion
Al respaldar sobre una WAN o enlace de red compartido, necesitas controlar cuanto ancho de banda consume rsync para evitar impactar el trafico de produccion.
# Limitar ancho de banda a 5 MB/s (el valor es en KB/s)
rsync -avhz --bwlimit=5000 -e ssh \
/var/www/ backupuser@remote:/backup/www/
# Limitar a 10 Mbps (~1250 KB/s)
rsync -avhz --bwlimit=1250 -e ssh \
/var/www/ backupuser@remote:/backup/www/
Opciones de compresion:
# Habilitar compresion de transferencia (util en enlaces lentos)
rsync -avhz -e ssh /source/ user@remote:/backup/
# Omitir compresion para archivos ya comprimidos
rsync -avh --compress --skip-compress=gz/bz2/zip/7z/jpg/png/mp4/mkv \
-e ssh /source/ user@remote:/backup/
Para compresion a nivel SSH (alternativa a -z de rsync):
# Usar compresion SSH en lugar de compresion rsync
rsync -avh -e "ssh -C" /source/ user@remote:/backup/
Consejo: No habilites la compresion de rsync (
-z) y la compresion SSH (-C) simultaneamente. La compresion doble desperdicia ciclos de CPU y puede incluso aumentar el tamano de la transferencia. Usa una u otra — la-zde rsync es generalmente mas eficiente porque comprime por archivo.
Script de Respaldo Automatizado con Cron
Un script de respaldo completo debe manejar logging, reporte de errores, rotacion de snapshots y notificaciones por correo. Aqui hay un ejemplo listo para produccion:
#!/usr/bin/env bash
# /usr/local/bin/rsync-backup.sh
# Respaldo rsync tipo snapshot con rotacion y logging
set -euo pipefail
# --- Configuracion --------------------------------------------------------
SOURCE="/home/"
BACKUP_ROOT="/backup/snapshots"
REMOTE_USER="backupuser"
REMOTE_HOST="192.168.1.100"
REMOTE_DEST="${REMOTE_USER}@${REMOTE_HOST}:${BACKUP_ROOT}"
SSH_KEY="/root/.ssh/backup_ed25519"
EXCLUDE_FILE="/etc/rsync-excludes.txt"
LOG_DIR="/var/log/rsync-backup"
RETENTION_DAYS=30
BWLIMIT=0 # 0 = ilimitado, o establecer KB/s
# --- Variables derivadas --------------------------------------------------
DATE=$(date +%Y-%m-%d_%H-%M-%S)
DEST="${BACKUP_ROOT}/${DATE}"
LATEST="${BACKUP_ROOT}/latest"
LOG_FILE="${LOG_DIR}/backup-${DATE}.log"
LOCK_FILE="/tmp/rsync-backup.lock"
# --- Funciones ------------------------------------------------------------
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
cleanup() {
rm -f "$LOCK_FILE"
log "Lock file removed."
}
# --- Verificaciones previas -----------------------------------------------
mkdir -p "$LOG_DIR" "$BACKUP_ROOT"
# Prevenir ejecuciones concurrentes
if [ -f "$LOCK_FILE" ]; then
echo "Backup already running (lock file exists). Exiting."
exit 1
fi
trap cleanup EXIT
touch "$LOCK_FILE"
log "=== Backup started ==="
log "Source: $SOURCE"
log "Destination: $DEST"
# --- Ejecutar rsync -------------------------------------------------------
RSYNC_OPTS=(
-avh
--delete
--numeric-ids
--log-file="$LOG_FILE"
)
[ -f "$EXCLUDE_FILE" ] && RSYNC_OPTS+=(--exclude-from="$EXCLUDE_FILE")
[ "$BWLIMIT" -gt 0 ] 2>/dev/null && RSYNC_OPTS+=(--bwlimit="$BWLIMIT")
[ -L "$LATEST" ] && RSYNC_OPTS+=(--link-dest="$LATEST")
if rsync "${RSYNC_OPTS[@]}" "$SOURCE" "$DEST/"; then
log "rsync completed successfully."
else
RSYNC_EXIT=$?
log "ERROR: rsync exited with code $RSYNC_EXIT"
exit $RSYNC_EXIT
fi
# --- Actualizar symlink latest --------------------------------------------
rm -f "$LATEST"
ln -s "$DEST" "$LATEST"
log "Updated 'latest' symlink to $DEST"
# --- Rotar respaldos antiguos ---------------------------------------------
log "Removing backups older than $RETENTION_DAYS days..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20*" -mtime +$RETENTION_DAYS -exec rm -rf {} \;
log "Rotation complete."
# --- Reporte de uso de disco ----------------------------------------------
USAGE=$(du -sh "$BACKUP_ROOT" | cut -f1)
log "Total backup storage used: $USAGE"
log "=== Backup finished ==="
Haz el script ejecutable y programalo con cron:
# Hacer ejecutable
sudo chmod +x /usr/local/bin/rsync-backup.sh
# Editar el crontab de root
sudo crontab -e
Agrega la siguiente entrada cron:
# Ejecutar respaldo cada dia a las 2:00 AM
0 2 * * * /usr/local/bin/rsync-backup.sh >> /var/log/rsync-backup/cron.log 2>&1
# Ejecutar respaldo cada 6 horas
0 */6 * * * /usr/local/bin/rsync-backup.sh >> /var/log/rsync-backup/cron.log 2>&1
Alternativamente, puedes usar un temporizador systemd para una programacion mas robusta:
# /etc/systemd/system/rsync-backup.service
[Unit]
Description=Rsync Backup Service
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/rsync-backup.sh
Nice=10
IOSchedulingClass=idle
# /etc/systemd/system/rsync-backup.timer
[Unit]
Description=Run Rsync Backup Daily
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
# Habilitar e iniciar el temporizador
sudo systemctl daemon-reload
sudo systemctl enable --now rsync-backup.timer
# Verificar estado del temporizador
systemctl list-timers rsync-backup.timer
Restauracion desde Respaldos
Un respaldo solo es util si puedes restaurar desde el. Debido a que los respaldos rsync son archivos y directorios simples, la restauracion es directa.
Restaurar un solo archivo
# Encontrar el archivo en un snapshot especifico
ls -la /backup/snapshots/2026-01-20_02-00-00/home/jc/documents/report.pdf
# Restaurarlo
cp /backup/snapshots/2026-01-20_02-00-00/home/jc/documents/report.pdf \
/home/jc/documents/report.pdf
Restaurar un directorio completo
# Restaurar un directorio completo desde el ultimo respaldo
rsync -avh /backup/snapshots/latest/var/www/ /var/www/
Restauracion completa del sistema
# Restaurar el sistema completo (desde un USB live o entorno de rescate)
sudo rsync -aAXvh --delete \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
/mnt/backup/system/ /mnt/target/
Restaurar desde un respaldo remoto
# Traer archivos del servidor de respaldo remoto
rsync -avhz -e "ssh -i /root/.ssh/backup_ed25519" \
backupuser@192.168.1.100:/backup/snapshots/latest/var/www/ \
/var/www/
Importante: Siempre realiza una ejecucion en seco con
--dry-run(o-n) antes de restaurar, especialmente para restauraciones completas del sistema. Esto te muestra exactamente que cambiara sin modificar nada.
# Ejecucion en seco -- vista previa de lo que haria la restauracion
rsync -avhn /backup/snapshots/latest/home/ /home/
Verificacion de Integridad del Respaldo
Los respaldos que no verificas son respaldos en los que no puedes confiar. Programa verificaciones de integridad regulares.
# Comparar origen y respaldo usando checksums (no transfiere datos)
rsync -avnc /home/ /backup/snapshots/latest/home/
# La bandera -c fuerza comparacion por checksum en lugar de tamano+marca de tiempo
# -n asegura que nada se transfiera (ejecucion en seco)
Si la salida no muestra diferencias, el respaldo es una copia exacta. Cualquier discrepancia se lista con su ruta.
Para verificacion automatizada, agrega una verificacion a tu script de respaldo:
# Verificacion post-respaldo
log "Running integrity verification..."
DIFF_COUNT=$(rsync -anc --delete "$SOURCE" "$DEST/" 2>/dev/null | wc -l)
if [ "$DIFF_COUNT" -le 1 ]; then
log "Verification PASSED: backup matches source."
else
log "WARNING: $DIFF_COUNT differences found between source and backup."
fi
Tabla de Referencia de Opciones de Rsync
| Opcion | Descripcion |
|---|---|
-a | Modo archivo: equivalente a -rlptgoD (recursivo, links, permisos, tiempos, grupo, propietario, dispositivos) |
-v | Salida detallada |
-h | Tamanos de archivo legibles por humanos |
-z | Comprimir datos durante la transferencia |
-P | Equivalente a --partial --progress (reanudar parciales + mostrar progreso) |
-n | Ejecucion en seco — muestra lo que se transferiria sin hacer cambios |
-c | Usar checksums en lugar de tiempo de modificacion + tamano para determinar cambios |
--delete | Eliminar archivos en destino que ya no existen en origen |
--delete-after | Eliminar despues de completar la transferencia (mas seguro que --delete-during) |
--link-dest=DIR | Enlazar con enlaces duros archivos sin cambios desde DIR (para respaldos snapshot) |
--exclude=PATRON | Excluir archivos que coincidan con PATRON |
--exclude-from=ARCHIVO | Leer patrones de exclusion desde ARCHIVO |
--include=PATRON | Incluir archivos que coincidan con PATRON (anula exclusion) |
--bwlimit=KBPS | Limitar ancho de banda en kilobytes por segundo |
-e "ssh ..." | Especificar shell remoto y sus opciones |
--numeric-ids | Preservar UID/GID numericos (importante para respaldos entre maquinas) |
--log-file=ARCHIVO | Escribir log detallado de transferencia a ARCHIVO |
--partial | Mantener archivos parcialmente transferidos para reanudacion |
--stats | Imprimir estadisticas de transferencia al final |
--progress | Mostrar progreso de transferencia por archivo |
--backup | Hacer respaldos de archivos sobreescritos/eliminados (con --backup-dir) |
--timeout=SEGUNDOS | Establecer tiempo de espera de E/S en segundos |
Solucion de Problemas
rsync: connection unexpectedly closed
Esto usualmente indica un problema SSH. Depura con:
# Primero probar conectividad SSH
ssh -v backupuser@remote echo "Connection works"
# Ejecutar rsync con salida de depuracion SSH
rsync -avhz -e "ssh -vvv" /source/ user@remote:/backup/
Causas comunes: firewall bloqueando el puerto SSH, ruta incorrecta de llave SSH, llave SSH con frase de paso pero sin ssh-agent ejecutandose.
Errores de permiso denegado
# Ejecutar rsync como root para respaldos completos del sistema
sudo rsync -aAXvh /source/ /backup/
# O usar --no-owner --no-group si no necesitas preservar propiedad
rsync -avh --no-owner --no-group /source/ /backup/
rsync: —link-dest arg does not exist
Asegurate de que la ruta --link-dest sea absoluta y accesible:
# Incorrecto: ruta relativa
rsync --link-dest=../latest ...
# Correcto: ruta absoluta
rsync --link-dest=/backup/snapshots/latest ...
El respaldo esta tardando demasiado
# Identificar que se esta transfiriendo
rsync -avh --progress --stats /source/ /backup/ 2>&1 | tail -20
# Excluir archivos grandes innecesarios
rsync -avh --exclude='*.iso' --exclude='*.vmdk' /source/ /backup/
El espacio en disco se esta llenando en el destino
# Verificar uso de espacio por snapshot
du -sh /backup/snapshots/*/
# Eliminar manualmente snapshots antiguos
rm -rf /backup/snapshots/2026-01-01_02-00-00
# Verificar conteo de enlaces duros (conteo alto significa buena deduplicacion)
stat /backup/snapshots/latest/some-file
rsync se congela o detiene en archivos grandes
# Establecer un timeout para prevenir cuelgues indefinidos
rsync -avh --timeout=300 --partial /source/ /backup/
Resumen
Una estrategia de respaldo rsync bien disenada proporciona proteccion de datos confiable, eficiente en espacio y transparente para tus servidores Linux. Los componentes clave son:
- Respaldos locales para recuperacion rapida de eliminacion accidental
- Respaldos remotos por SSH para recuperacion ante desastres
- Respaldos incrementales tipo snapshot con
--link-destpara versionado eficiente en espacio - Archivos de exclusion para omitir caches, archivos temporales y artefactos de compilacion
- Programacion automatizada con cron o temporizadores systemd
- Verificacion regular para asegurar la integridad del respaldo
- Procedimientos de restauracion probados — un respaldo que no has probado no es un respaldo
Combina esta estrategia de respaldo rsync con el endurecimiento SSH para asegurar la capa de transporte, y sigue la Lista de Verificacion de Seguridad para Servidores Linux para proteger los servidores en si. Juntas, estas practicas forman una base solida para la administracion de servidores y la recuperacion ante desastres.