TL;DR — Resumen Rápido
Guía rsync: algoritmo delta, flags esenciales, copias remotas por SSH, snapshots incrementales con --link-dest, automatización con cron y modo daemon en Linux.
rsync es la herramienta estándar de Linux para copia eficiente de archivos y copias de seguridad remotas. Su algoritmo de transferencia delta calcula checksums en ambos lados y envía solo los bytes que difieren, haciéndolo mucho más rápido que scp para transferencias repetidas de árboles de directorios grandes. Esta guía cubre desde los flags básicos hasta scripts de copia incremental en producción con rotación --link-dest.
Requisitos Previos
- Sistema Linux (Ubuntu 22.04+, Debian 12+, RHEL 9+ o cualquier distro moderna).
- rsync instalado en las máquinas origen y destino (
sudo apt install rsync/sudo dnf install rsync). - Autenticación SSH por clave configurada para transferencias remotas.
- Acceso root o sudo para copias de seguridad a nivel de sistema.
Cómo Funciona rsync
rsync usa el algoritmo de transferencia delta para minimizar los datos enviados por la red:
- El emisor lista archivos y calcula checksums deslizantes de bloques pequeños.
- El receptor comprueba qué bloques ya tiene.
- Solo se transmiten los bloques faltantes o modificados.
- Los metadatos (permisos, marcas de tiempo, propietario) se sincronizan por separado.
Para un directorio grande que cambia solo un 1% al día, rsync típicamente transfiere menos del 1% del total en ejecuciones posteriores. La primera transferencia siempre es una copia completa; cada ejecución posterior es incremental por defecto.
Propiedades clave:
- Basado en checksum — detecta cambios aunque la marca de tiempo no se haya actualizado.
- Transferencia atómica — los archivos se escriben con nombre temporal y se renombran al completarse.
- Multiplataforma — funciona en Linux, macOS y Windows (mediante WSL o Cygwin).
- Versión de protocolo negociada — cliente y servidor acuerdan la versión más alta compatible al conectarse.
Sintaxis Básica
rsync [OPCIONES] ORIGEN DESTINO
| Patrón | Significado |
|---|---|
rsync -a /src/ /dst/ | Copia el contenido de /src/ en /dst/ |
rsync -a /src /dst/ | Copia el directorio /src dentro de /dst/ |
rsync -a usuario@host:/remoto/ /local/ | Obtiene del remoto al local |
rsync -a /local/ usuario@host:/remoto/ | Envía del local al remoto |
La barra final en el origen importa. /src/ significa “copia el contenido de src”; /src significa “copia el directorio src dentro del destino.”
Flags Esenciales
rsync -avzP --delete \
--exclude='*.tmp' \
--exclude='.cache/' \
/home/usuario/ usuario@servidorbackup:/backups/home/
| Flag | Efecto |
|---|---|
-a | Archivo: recursivo + preserva permisos, propietario, marcas de tiempo, symlinks, dispositivos |
-v | Verbose: muestra cada archivo transferido |
-z | Comprime datos durante la transferencia (útil en enlaces lentos; omitir en LAN rápida) |
-P | Muestra progreso por archivo + conserva archivos parciales (--progress --partial combinados) |
--delete | Elimina en destino los archivos ausentes en origen — crea un espejo exacto |
-n / --dry-run | Simula la transferencia sin realizar cambios |
--exclude=PATRÓN | Omite archivos que coincidan con el patrón |
--include=PATRÓN | Fuerza la inclusión aunque un exclude más amplio los omitiera |
-e ssh | Usa SSH como transporte (predeterminado en rsync moderno; agrega opciones con -e 'ssh -p 2222') |
--checksum | Compara contenido de archivos (no solo tamaño+mtime); más lento pero detecta corrupción silenciosa |
--bwlimit=KBPS | Limita el ancho de banda (p.ej. --bwlimit=10000 para 10 MB/s) |
--log-file=RUTA | Escribe un log de transferencia en el archivo especificado |
--stats | Muestra estadísticas resumidas al finalizar la transferencia |
Siempre haz un dry-run primero
rsync -avzn --delete /importante/ usuario@host:/backup/importante/
Revisa la salida y luego vuelve a ejecutar sin -n para aplicar los cambios.
Sincronización Remota por SSH
Enviar (local → remoto)
rsync -avz -e "ssh -i ~/.ssh/backup_ed25519" \
/var/www/html/ \
backupuser@192.168.1.50:/backups/webroot/
Obtener (remoto → local)
rsync -avz -e "ssh -i ~/.ssh/backup_ed25519" \
backupuser@192.168.1.50:/backups/webroot/ \
/var/www/html/
Puerto SSH personalizado
rsync -avz -e "ssh -p 2222" /src/ usuario@host:/dst/
Restringir la clave SSH de backup
En el servidor de backup, en ~/.ssh/authorized_keys, agrega un comando forzado para que la clave solo pueda ejecutar rsync:
command="rsync --server --daemon .",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...clave...
Esto limita el daño si el equipo cliente resulta comprometido.
Limitación de Ancho de Banda
En sistemas en producción, rsync sin restricciones puede saturar un enlace. --bwlimit acepta kilobytes por segundo:
# Limitar a 5 MB/s
rsync -avz --bwlimit=5000 /origen/ usuario@host:/dest/
# Limitar a 1 MB/s para tareas de backup en segundo plano
rsync -avz --bwlimit=1000 --delete /home/ usuario@host:/backups/home/
Para una limitación más dinámica, combina rsync con ionice y nice:
nice -n 19 ionice -c 3 rsync -avz --bwlimit=2000 /origen/ usuario@host:/dest/
Preservar Permisos, Propietario y Atributos Extendidos
El flag -a (archivo) es una abreviación de -rlptgoD:
| Sub-flag | Preserva |
|---|---|
-r | Recursión |
-l | Symlinks como symlinks |
-p | Permisos (bits chmod) |
-t | Marcas de tiempo de modificación |
-g | Propietario de grupo |
-o | Propietario de usuario (requiere root) |
-D | Archivos de dispositivo y especiales |
Para ACLs y atributos extendidos (necesarios para contextos SELinux o xattrs de macOS):
rsync -aAX /origen/ /destino/
| Flag extra | Preserva |
|---|---|
-A | ACLs POSIX |
-X | Atributos extendidos (xattrs) |
Copias Incrementales con —link-dest
--link-dest permite snapshots basados en hard links — cada directorio diario parece una copia completa pero solo los archivos nuevos o modificados ocupan espacio adicional.
Concepto
/backups/
2026-03-20/ ← datos completos, 50 GB
2026-03-21/ ← archivos sin cambios enlazados + solo archivos modificados; ~200 MB extra
2026-03-22/ ← enlazado desde 2026-03-21 + cambios de hoy; ~150 MB extra
Script
#!/bin/bash
set -euo pipefail
ORIGEN="/home/"
DEST="backupuser@192.168.1.50:/backups"
HOY=$(date +%Y-%m-%d)
AYER=$(date -d "yesterday" +%Y-%m-%d)
SSH_KEY="/root/.ssh/backup_ed25519"
rsync -avz \
-e "ssh -i $SSH_KEY" \
--link-dest="$DEST/daily/$AYER" \
--delete \
"$ORIGEN" \
"$DEST/daily/$HOY/"
echo "Backup completo: $HOY"
Rotación: diaria / semanal / mensual
#!/bin/bash
ORIGEN="/home/"
BASE="/backups"
HOY=$(date +%Y-%m-%d)
DOW=$(date +%u)
DOM=$(date +%d)
DEST_HOY="$BASE/daily/$HOY"
ENLACE_ULTIMO="$BASE/daily/latest"
rsync -a --delete \
--link-dest="$ENLACE_ULTIMO" \
"$ORIGEN" "$DEST_HOY/"
ln -sfn "$DEST_HOY" "$ENLACE_ULTIMO"
[ "$DOW" -eq 7 ] && cp -al "$DEST_HOY" "$BASE/weekly/$(date +%Y-W%V)"
[ "$DOM" -eq 01 ] && cp -al "$DEST_HOY" "$BASE/monthly/$(date +%Y-%m)"
find "$BASE/daily" -maxdepth 1 -type d | sort | head -n -7 | xargs rm -rf
find "$BASE/weekly" -maxdepth 1 -type d | sort | head -n -4 | xargs rm -rf
find "$BASE/monthly" -maxdepth 1 -type d | sort | head -n -12 | xargs rm -rf
Automatización con cron y Timers de systemd
cron
crontab -e
# Agregar:
0 2 * * * /usr/local/bin/rsync-backup.sh >> /var/log/rsync-backup.log 2>&1
Servicio + timer systemd
/etc/systemd/system/rsync-backup.service:
[Unit]
Description=Backup diario con rsync
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/rsync-backup.sh
StandardOutput=journal
StandardError=journal
/etc/systemd/system/rsync-backup.timer:
[Unit]
Description=Timer de backup diario con rsync
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=10min
Persistent=true
[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now rsync-backup.timer
Modo Daemon de rsync
Para volúmenes altos o pulls programados sin autenticación SSH interactiva, rsync puede ejecutarse como daemon independiente.
/etc/rsyncd.conf
uid = nobody
gid = nogroup
use chroot = yes
max connections = 4
log file = /var/log/rsyncd.log
[backups]
path = /backups/shared
comment = Área de backup compartida
read only = no
auth users = clientebackup
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.0/24
hosts deny = *
/etc/rsyncd.secrets
clientebackup:contraseñafuerte123
chmod 600 /etc/rsyncd.secrets
systemctl enable --now rsync
Uso del cliente
rsync -avz clientebackup@servidorbackup::backups /local/restaurar/
El doble dos puntos (::) indica modo daemon.
Monitorización y Registros
Estadísticas por ejecución
rsync -avz --stats /origen/ /dest/ 2>&1 | tee /var/log/rsync-$(date +%Y%m%d).log
Verificar fallos en scripts
rsync -avz /origen/ /dest/
EXIT=$?
if [ $EXIT -ne 0 ] && [ $EXIT -ne 24 ]; then
echo "rsync falló con código $EXIT" | mail -s "Backup fallido en $(hostname)" admin@ejemplo.com
fi
El código de salida 24 (archivos desaparecidos durante la transferencia) es normal en sistemas activos; trátalo como éxito.
rsync vs scp vs sftp vs Borg vs rclone
| Característica | rsync | scp | sftp | BorgBackup | rclone |
|---|---|---|---|---|---|
| Transferencia delta | Sí | No | No | Sí (dedup) | Parcial |
| Reanudar parciales | Sí (-P) | No | Sí | Sí | Sí |
| Cifrado | Vía SSH | SSH | SSH | AES-256 nativo | Vía SSH/API |
| Deduplicación | No | No | No | Sí | No |
| Snapshots incrementales | Sí (--link-dest) | No | No | Sí | No |
| Backends cloud | No | No | No | Solo SSH | S3, GCS, muchos |
| Compresión | Sí (-z) | No | No | lz4/zstd | Sí |
| Mejor para | Espejado, backups | Copia puntual | Archivos interactivos | Backup eficiente | Sync cloud |
Resumen
- rsync usa transferencia delta — solo se envían los bloques de archivos modificados, haciendo los backups repetidos muy rápidos.
- Usa
-aAXzpara preservar todos los metadatos incluyendo ACLs y xattrs; agrega-Ppara transferencias reanudables. - Siempre haz un dry-run con
-nantes de usar--deleteen un nuevo destino. --link-destcrea snapshots con hard links eficientes en espacio — la base de los esquemas de rotación profesionales.- Restringe las claves SSH de backup en
authorized_keyscon un comando forzado para limitar el radio de impacto. - Prefiere los timers de systemd sobre cron para backups automatizados — mejor registro y manejo de ejecuciones perdidas.
- El código de salida 24 (archivos desaparecidos) es normal en sistemas activos; trátalo como éxito en los scripts.
- Ejecuta
rsync --statsy registra la salida para detectar fallos silenciosos antes de necesitar restaurar.