Backup automatizado com Bash e rsync
1. Introdução ao backup com Bash e rsync
Automatizar backups com scripts shell é uma prática essencial para administradores de sistemas e desenvolvedores que desejam garantir a integridade dos dados sem depender de soluções comerciais complexas. O Bash oferece controle granular sobre o processo, permitindo personalizar cada aspecto da rotina de backup, desde a seleção de arquivos até o tratamento de erros.
O rsync destaca-se como ferramenta central por sua eficiência: ele transfere apenas as diferenças entre origem e destino (sincronização incremental), reduz drasticamente o tráfego de rede e o tempo de execução. Com suporte nativo a SSH, todo o tráfego é criptografado, garantindo segurança em backups remotos.
Pré-requisitos: Bash instalado (padrão em praticamente todas as distribuições Linux), rsync (geralmente disponível via gerenciador de pacotes) e configuração de chaves SSH para autenticação sem senha.
2. Estrutura básica de um script de backup
Um script de backup bem estruturado começa com a definição clara de variáveis. Isso facilita a manutenção e evita erros de digitação.
#!/bin/bash
# Variáveis de configuração
ORIGEM="/home/usuario/dados/"
DESTINO="/mnt/backup/"
LOG="/var/log/backup.log"
DATA=$(date +%Y-%m-%d_%H-%M-%S)
HOST_REMOTO="servidor-backup.local"
SSH_USER="backupuser"
# Verificação de diretórios
if [ ! -d "$ORIGEM" ]; then
echo "$DATA - ERRO: Diretório de origem não encontrado: $ORIGEM" >> "$LOG"
exit 1
fi
if [ ! -d "$DESTINO" ]; then
echo "$DATA - ERRO: Diretório de destino não encontrado: $DESTINO" >> "$LOG"
exit 1
fi
# Comando rsync essencial
echo "$DATA - Iniciando backup..." >> "$LOG"
rsync -avz --delete --progress "$ORIGEM" "$SSH_USER@$HOST_REMOTO:$DESTINO" >> "$LOG" 2>&1
# Verificação de sucesso
if [ $? -eq 0 ]; then
echo "$DATA - Backup concluído com sucesso" >> "$LOG"
else
echo "$DATA - ERRO: Backup falhou" >> "$LOG"
exit 1
fi
O comando rsync -avz --delete --progress combina: modo archive (-a) que preserva permissões, timestamps e links simbólicos; verbose (-v) para saída detalhada; compressão (-z) para economizar largura de banda; --delete para remover arquivos no destino que não existem mais na origem; e --progress para acompanhamento em tempo real.
3. Implementando backup incremental e diferencial
Backups completos copiam todos os arquivos a cada execução, consumindo muito espaço e tempo. Backups incrementais copiam apenas alterações desde o último backup (completo ou incremental), economizando recursos. Backups diferenciais copiam alterações desde o último backup completo.
O rsync permite implementar backups incrementais eficientes usando --link-dest. Essa opção cria hard links para arquivos inalterados, ocupando espaço apenas para os arquivos modificados.
#!/bin/bash
# Configuração de rotação
BASE="/backup/semanal"
DIARIO="/backup/diario/$(date +%Y-%m-%d)"
SEMANA_ANTERIOR="/backup/semana_anterior"
# Backup incremental com hard links
rsync -avz --delete --link-dest="$SEMANA_ANTERIOR" "$ORIGEM" "$DIARIO"
# Rotação semanal: mover backup diário mais antigo para semanal
if [ "$(date +%u)" -eq 7 ]; then # Domingo
mv "$DIARIO" "$BASE/$(date +%Y-%m-%d)"
fi
Neste exemplo, o backup diário referencia o backup semanal anterior via --link-dest. Arquivos idênticos são representados por hard links, economizando espaço em disco. A rotação semanal move o backup mais antigo para um diretório separado.
4. Tratamento de erros e logging
Um script robusto deve capturar e registrar erros de forma adequada. O redirecionamento 2>&1 combina saída padrão e de erro no mesmo arquivo de log, facilitando a análise.
#!/bin/bash
LOG="/var/log/backup.log"
ERRO_LOG="/var/log/backup_erro.log"
# Função de logging com timestamp
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG"
}
# Execução com captura de código de retorno
log "Iniciando backup"
rsync -avz --delete "$ORIGEM" "$DESTINO" >> "$LOG" 2>&1
RSYNC_EXIT=$?
if [ $RSYNC_EXIT -ne 0 ]; then
log "ERRO: rsync falhou com código $RSYNC_EXIT"
echo "Backup falhou em $(date)" >> "$ERRO_LOG"
# Notificação via syslog
logger -p user.err "Backup falhou: código $RSYNC_EXIT"
# Opcional: envio de e-mail
# mail -s "Falha no backup" admin@exemplo.com < "$ERRO_LOG"
exit $RSYNC_EXIT
fi
log "Backup concluído com sucesso"
O código de retorno $? do rsync é crucial: 0 indica sucesso, valores diferentes indicam falhas específicas (1 para erros de sintaxe, 2 para erros de conexão, etc.). A função logger envia mensagens para o syslog, permitindo monitoramento centralizado.
5. Agendamento com cron e systemd timers
O cron é o agendador tradicional do Unix. Para executar o script diariamente às 2h da manhã:
# Editar crontab: crontab -e
0 2 * * * /usr/local/bin/backup.sh
Cuidados importantes com cron:
- Variáveis de ambiente como PATH são limitadas. Defina caminhos absolutos no script ou configure PATH no crontab.
- Redirecione saída para log: 0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup_cron.log 2>&1
Systemd timers oferecem vantagens como logging integrado via journald e gerenciamento de dependências:
# /etc/systemd/system/backup.service
[Unit]
Description=Script de backup automatizado
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/backup.timer
[Unit]
Description=Timer para backup diário
Requires=backup.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target
Ative com: systemctl enable --now backup.timer
6. Segurança e boas práticas
Para backups remotos via SSH, configure chaves sem passphrase ou use ssh-agent para armazenar a senha na memória:
# Gerar chave (sem passphrase para automação)
ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N ""
# Copiar chave pública para o servidor remoto
ssh-copy-id -i ~/.ssh/backup_key.pub usuario@servidor
No servidor remoto, restrinja o que pode ser executado com a chave editando ~/.ssh/authorized_keys:
command="/usr/local/bin/restrito-rsync.sh",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-ed25519 AAA... chave-backup
Nunca exponha senhas no script. Use variáveis de ambiente ou arquivos .env protegidos:
# .env (permissões 600)
SSH_PASS="minha_senha"
# No script
source /caminho/.env
export SSHPASS="$SSH_PASS"
rsync -avz --rsh="sshpass -e ssh" "$ORIGEM" "$DESTINO"
7. Monitoramento e testes do backup
Antes de colocar em produção, teste o script em ambiente isolado. Crie um diretório de teste com arquivos de exemplo e verifique o comportamento.
Script de verificação pós-backup:
#!/bin/bash
# Verifica integridade comparando checksums
ORIGEM="/home/usuario/dados/"
DESTINO="/mnt/backup/"
LOG_VERIFICACAO="/var/log/backup_verificacao.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_VERIFICACAO"
}
log "Iniciando verificação de integridade"
# Gerar checksums da origem
find "$ORIGEM" -type f -exec sha256sum {} \; > /tmp/origem.sha256
# Gerar checksums do destino
find "$DESTINO" -type f -exec sha256sum {} \; > /tmp/destino.sha256
# Comparar
if diff /tmp/origem.sha256 /tmp/destino.sha256 > /dev/null 2>&1; then
log "Verificação concluída: todos os arquivos íntegros"
else
log "ERRO: Discrepância encontrada nos checksums"
diff /tmp/origem.sha256 /tmp/destino.sha256 >> "$LOG_VERIFICACAO"
fi
rm -f /tmp/origem.sha256 /tmp/destino.sha256
Para alertas automáticos, integre com serviços como Slack via webhook:
WEBHOOK_URL="https://hooks.slack.com/services/TOKEN"
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Backup concluído com sucesso"}' \
"$WEBHOOK_URL"
8. Exemplo completo e considerações finais
Script funcional completo com todas as funcionalidades discutidas:
#!/bin/bash
# =============================================
# Script de Backup Automatizado com Bash e rsync
# Versão: 2.0
# =============================================
# Configurações
ORIGEM="/home/usuario/dados/"
DESTINO_LOCAL="/mnt/backup/local/"
DESTINO_REMOTO="backup@servidor:/backup/"
LOG="/var/log/backup_automatizado.log"
EXCLUIR="--exclude='.cache' --exclude='tmp'"
# Timestamp
DATA=$(date '+%Y-%m-%d %H:%M:%S')
DATA_ARQUIVO=$(date '+%Y%m%d_%H%M%S')
# Função de log
log() {
echo "$DATA - $1" >> "$LOG"
}
# Verificação de pré-requisitos
for cmd in rsync ssh; do
if ! command -v $cmd &> /dev/null; then
log "ERRO: $cmd não encontrado. Instale antes de executar."
exit 1
fi
done
# Backup local
log "Iniciando backup local"
rsync -avz --delete $EXCLUIR "$ORIGEM" "$DESTINO_LOCAL" >> "$LOG" 2>&1
if [ $? -ne 0 ]; then
log "ERRO: Backup local falhou"
exit 1
fi
log "Backup local concluído"
# Backup remoto via SSH
log "Iniciando backup remoto"
rsync -avz --delete -e "ssh -i ~/.ssh/backup_key" $EXCLUIR "$ORIGEM" "$DESTINO_REMOTO" >> "$LOG" 2>&1
if [ $? -ne 0 ]; then
log "ERRO: Backup remoto falhou"
exit 1
fi
log "Backup remoto concluído"
log "Todos os backups concluídos com sucesso"
exit 0
Para estender o script: adicione compactação com gzip, suporte a múltiplas origens com loops, ou backup de bancos de dados com mysqldump antes do rsync.
Melhores práticas resumidas:
- Sempre teste em ambiente isolado antes de produção
- Use logging detalhado com timestamps
- Configure notificações para falhas
- Mantenha chaves SSH seguras e restritas
- Documente o script para manutenção futura
Backups automatizados com Bash e rsync oferecem uma solução poderosa, flexível e gratuita para proteção de dados. Com os conceitos apresentados, você pode construir sistemas de backup robustos adaptados às suas necessidades específicas.
Referências
- Documentação oficial do rsync — Manual completo com todas as opções e exemplos de uso do rsync
- Guia de SSH keys do Arch Linux — Tutorial detalhado sobre configuração e segurança de chaves SSH
- Bash Scripting Guide - Linux Documentation Project — Referência avançada para scripts shell, incluindo tratamento de erros e funções
- Systemd Timers vs Cron — Documentação oficial do systemd para criação de timers, com exemplos práticos
- Automatizando backups com rsync e cron - DigitalOcean — Tutorial prático com exemplos de backup local e remoto
- Guia de logging no Bash — Documentação GNU sobre redirecionamento de saída e logging em scripts
- Boas práticas de segurança para scripts shell — Ferramenta online para análise estática de scripts, recomendando correções de segurança