Como parei de me preocupar e passei a adorar minha solução de backups

Postado em 12 September, 2020 | 16 minutos

Nesse texto vou mostrar como montei minha solução de backup com algumas propriedades interessantes:

  • Sincroniza com Android, usando syncthing.
  • Caso os dispositivos sejam comprometidos, os backups não poderão ser deletados/sequestrados (modo append-only).
  • Monitorado: caso um backup falhe, um alerta será gerado, usando healthchecks.io.
  • Caso tudo pegue fogo, como utilizar serviços em nuvem de forma segura.

Edits

  • 10Apr2021: Adicionado observação para rodar o borg como usuário root e salvar pacotes instalados (diff)
  • 16Nov2021: Nova localização da pasta do WhatsApp no Android 11 e outras pequenas atualizações (diff)
  • 27Mar2022: Atualização das dependências para o borg 1.2 e dump banco de dados postgres em container (diff)
  • 14Ago2022: Comentário sobre a mudança da operação prune, a partir da versão 1.2 (diff)

Agradecimentos

Primeiramente, esse texto não seria possível sem o apoio do Gustavo Gus, que além de sempre me incentivar e orientar nesses desafios, me introduziu ao borg e revisou esse texto. Confira a pagina pessoal dele: gus.computer.

Também gostaria de agradecer os amigues que sempre me apoiam e incentivam a disseminar o conhecimento.

Backup: Uma medida para evitar desastres

Toda forma de armazenamento digital de dados pode falhar. Ter backups é importante, pois precisamos ter cópias reservas caso o disco rígido falhe ou em caso de furto do computador/celular.

Regra 3-2-1

A regra 3-2-1 é uma recomendação muito popular de como fazer backups, ela diz:

  • 3: mantenha 3 cópias dos dados importantes: 1 original e mais 2 backups.
  • 2: salve os backups em 2 tipos de mídias: por exemplo, se você tiver um backup num HD externo e caso o seu computador seja infectado por um ransomware, o seu backup pode ser comprometido.
  • 1: tenha 1 backup “fora de casa” (pode ser outro local físico ou na nuvem).

Um vídeo excelente explicando essa regra é: Data Backup: The 3-2-1 Rule – canal ExplainingComputers.

A ideia geral dessa regra é a seguinte: caso tenha um problema no computador, temos uma cópia local de fácil e rápido acesso. E em caso de um desastre no local, temos uma cópia remota reservada que podemos restaurar.

Começando pelo começo: Fazendo backup do Android com Syncthing

Por padrão, a maioria dos Android já faz backup das fotos (via Google Fotos) e das conversas do WhatsApp (via Google drive). Ou seja, esses dois Apps mais comuns já estão replicados.

Mas o diabo está nos detalhes. O backup do WhatsApp (e das Fotos) está descriptografado, ou seja, o Google e qualquer um que conseguir acesso a sua conta do Google Drive conseguirá acessar todo o histórico de conversas do WhatsApp (e seus nudes do Google Fotos).

Além disso, como já vamos montar uma infraestrutura para fazer backup para o computador é interessante aproveitá-la para fazer backup do seu dispositivo Android com mais controle e privacidade.

O Syncthing é uma forma para sincronizar os seus arquivos entre os seus dispositivos, de forma fácil, segura e sem armazenar na nuvem (ou qualquer dispositivo que não seja seu).

Como usar o Syncthing

O primeiro passo pra usar o syncthing é instalar no seu computador. Se você usa um sistema operacional baseado no Debian GNU/Linux, basta digitar sudo apt install syncthing.

Vale observar que a versão do Syncthing que muitas distros empacotam tende a ser uma versão mais antiga, então, é recomendado instalar a versão mais recente pelo site do desenvolvedor.

Além de GNU/Linux, o Syncthing funciona no Windows, macOS e *BSD.

No celular, infelizmente ele só está disponível para Android.

Uma vez instalado no computador, vamos agora instalar no Android: ele está disponível na loja de aplicativos livres F-droid e na Play Store.

Linkando o computador com o Android

Primeiro, no computador,

  1. Execute o Syncthing no computador e uma interface web será aberta.
  2. clique no canto superior direito: Actions -> Show ID. Um QR code será exibido.

Segundo, no seu dispositivo Android,

  1. Abra o Syncthing no Android e libere as permissões necessárias.
  2. Toque na aba “devices”, e depois toque no “+” no canto superior direito. No campo “Device ID” no canto direito toque no ícone de QR code.
  3. Será necessário instalar o app Barcode scanner. Uma vez instalado, toque novamente no ícone do QR code e escaneie o QR code do seu computador.
  4. Por fim, de um nome para o computador no Android.

Último passo, volte para o seu computador,

  1. Na interface web aberta haverá um aviso informando que um dispositivo novo quer se conectar. Aceite e dê um nome para o seu Android.

Sincronizando uma pasta entre o Android e o computador

Primeiro, no Android,

  1. No Syncthing, vá na aba “Folder”, toque no ícone “+” no canto superior direito.
  2. Dê um nome para a pasta, toque no ícone de pasta, e escolha a pasta que quer sincronizar e ative o computador.
  3. Opcional, mas uma boa pratica, toque na opção “file versioning” e selecione a opção “TrashCan”. Dessa forma caso o computador delete um arquivo haverá um backup.
  4. Por fim, toque no ícone de check (✔️) no canto superior direito.

Segundo, no computador,

  1. Um aviso aparecerá na interface web informando que o dispositivo quer compartilhar uma pasta. Clique em “Add”, coloque o caminho do local para ser armazenado.
  2. Opcional, mas uma boa prática, clique na opção “file versioning” e selecione a opção “TrashCan”. Dessa forma caso o android delete um arquivo haverá um backup.
  3. Por fim clique em “Save”.

Pronto! Agora a pasta selecionada estará sincronizada entre o computador e o Android.

Eu pessoalmente sincronizo as seguintes pastas:

Print do syncthing: sincronizo as pastas: WhatsApp, Pictures, DCIM, Signal e syncthing

Print do syncthing: sincronizo as pastas: WhatsApp, Pictures, DCIM, Signal e syncthing

  • Edit 16Nov2021: Apartir do Android 11 a pasta do WhatsApp mudou: antes era /storage/emulated/0/WhatsApp agora está em /storage/emulated/0/Android/media/com.whatsapp/WhatsApp (conforme o printscreen atualizado acima).

Syncthing - considerações finais

Como não esquecer executar o Syncthing? Para os backups sempre serem feitos, você pode deixar o Syncthing sempre rodando no Android, mas outra opção é abrir uma vez por dia apenas. Um app que me ajuda muito para não esquecer é o Habits, também disponível na F-droid.

Caso você tenha algum firewall instalado no seu computador, é importante liberar as portas do Syncthing, assim a transferência de dados quando você estiver na sua rede local será bem mais rápida. As portas usadas pelo Syncthing são: 22000/tcp e 21027/udp. Caso utilize o ufw, veja as instruções na documentação oficial syncthing-ufw-firewall.

Para melhorar a experiência de usuário, uma boa sugestão é instalar o cliente gráfico do Syncthing disponível no pacote syncthing-gtk. Caso utilize Windows: SyncTrayzor e macOS: syncthing-macos. Com o ícone na barra de tarefas, utilizar o syncthing é muito mais amigável e fácil.

A seguir no texto vou ensinar como configurar para fazer backup do computador num Raspberry Pi. Pode ser interessante rodar o Syncthing diretamente no Raspberry, dessa forma o backup do Android não dependerá do computador. No site tem instruções de como acessar a interface web do Syncthing no Raspberry e as instruções para iniciar o Syncthing automaticamente via Systemd.

Backup do computador: quando tudo era mato: rsync e rssh para security

Antes de eu conhecer o borg, usava o clássico Rsync para fazer os backups do computador no Raspberry Pi.

O Rsync é um programa que faz backups incrementais de forma rápida.

Como eu tinha um receio de caso meu computador fosse comprometido ele poderia comprometer o Raspberry. Descobri o rssh. Ele é um shell restrito que permite apenas o scp, rsync, sftp etc … dessa forma caso comprometido, se tentar acessar o raspberry, mesmo com as credenciais corretas não será permitido, exibindo o erro abaixo:

This account is restricted by rssh.
Allowed commands: scp sftp rsync

If you believe this is in error, please contact your system administrator

Usava o Rsync com os seguintes argumentos, executado pelo cron:

rsync -avh --stats -P --log-file=~/rsync-home.log /home/ rasp:/caminho/na/rasp

BorgBackups: O Santo graal dos backups

Quando conheci o Borgbackup (vulgo borg) minha mente explodiu! Tem tudo que eu sentia que o Rsync não entregava, como:

  • Todos os backups são backups completos, não incrementais, dessa forma tenho o “histórico” (versionamento) dos arquivos.
    • E muito mais eficiente em espaço! O Borg ocupa bem pouco espaço em disco!
  • Os backups são criptografados!
  • Os backups são comprimidos, dessa forma os meus arquivos csv enormes ficam bem menores.
  • Tem um modo, que vamos detalhar logo menos, chamado “append-only” dessa forma o backup só será acessado para acrescentar novas coisas, não deletar; ótimo para a segurança!

Não por acaso o Borg já foi chamado como o Santo Graal dos backups.

Borg em ação:

$ borg create -v --stats /path/to/repo::{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f} /path/to/be/backuped
------------------------------------------------------------------------------
Archive name: nuc-2020-09-06T10:38:03.675158
Archive fingerprint: 8a7d8a10a54211c74e3dff1e3f5f67f65c1a85935d5e2a5ee23adb8d0fce588c
Time (start): Sun, 2020-09-06 10:38:03
Time (end):   Sun, 2020-09-06 10:38:09
Duration: 5.21 seconds
Number of files: 11645
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:                4.78 GB              4.38 GB            103.36 MB
All archives:               84.61 GB             77.59 GB              9.51 GB
                       Unique chunks         Total chunks
Chunk index:                   16246               228864
------------------------------------------------------------------------------

Acima temos a saída do borg depois de adicionados alguns arquivos num repositório de backup e executado para fazer um novo backup. Note o quão eficiente em espaço é o borg: se cada backup fosse um “tar” seriam gastos 84.61 GB . Se o tar fosse comprimido 77.59 GB, mas o borg gastou apenas 9.51GB! Esses números se referem a todos os backups do repositório (all archives).

Interfaces do Borg: borgmatic e Vorta:

O borg é utilizado através da linha de comando. Para automatizar e tornar mais fácil a operação dele temos algumas interfaces:

Pra quem usa desktop temos o Vorta:

Vamos falar mais do Borgmatic, mas para quem quer uma interface gráfica linda pro borg temos o Vorta.

Borgmatic: Torna o borg automático e completo

O Borgmatic permite que através de um único arquivo de configuração yaml seja gerenciado todas as ações do borg, além de coisas como fazer backups de bancos de dados, além de outras integrações.

Borgmatic: instalando e configurando

Podemos instalar através do pacote do Debian com um sudo apt install borgbackup borgmatic, mas não teremos a versão mais recente. Há duas opções: baixar o binário para o computador e o Raspberry Pi (não oficial), ou compilar.

Instalando através do gerenciador de pacotes do Python Pip

Primeiro, instale as dependências:

sudo apt-get install python3 python3-dev python3-pip \
libacl1-dev libacl1 \
libssl-dev openssl \
liblz4-dev libzstd-dev libxxhash-dev \
build-essential \
pkg-config python3-pkgconfig

Depois, instale o Borg e Borgmatic (instale no computador e no Raspberry Pi):

pip3 install -U pip setuptools wheel
pip3 install -U borgbackup borgmatic

Observação: no meu Raspberry Pi 3 demorou 7 minutos os comandos acima.

Adicionando no $PATH: tive alguns problemas dizendo que o Borg não estava instalado, porém como ele está instalado em ~/.local/bin/borg, só precisei criar um link simbólico com sudo ln -s $(which borg) /usr/bin/.

Observação: O método acima funciona bem para a maioria das situações, mas tive alguns problemas de permissão, principalmente com contêineres docker pois os arquivos dos volumes dos mesmos estavam sendo gerados com outro usuário e grupo do usuário atual. Nesses casos podemos rodar o borg com super usuário root, fazendo:

sudo pip3 install --user -U pip setuptools wheel
sudo pip3 install --user -U borgbackup borgmatic

Se atente para não esquecer o –user (como root/sudo), pois sem isso o pip vai sobre sobrescrever o python da sua distro, podendo causar problemas.

Arquivo de configuração borgmatic

Para gerar o seu arquivo de configuração, basta rodar o comando generate-borgmatic-config. Por exemplo, o arquivo no Borgmatic que uso é:

location:
    source_directories:
        - /etc/
        - /home/
        - /root/
        - /var/spool/ # salvar as crontabs
    repositories:
        - usuario@rasp:/mnt/bak/borgbackups/borg_pc # hd_externo na rasp
        - usuario@rasp:/mnt/borgbackups/borg_pc
        - usuario@repo2:/mnt/borgbackups/borg_pc
    exclude_patterns:
        - '*/.cache/'
        - '*.pyc'
    exclude_caches: true
    bsd_flags: false
    exclude_if_present: .nobackup

storage:
    encryption_passphrase: "# senha gerada no keepassxc"

retention:
    keep_within: 48H
    keep_hourly: 2
    keep_daily: 7
    keep_weekly: 12
    keep_monthly: -1
    keep_yearly: -1
    prefix: ''

consistency:
    checks:
         - data
         - archives
    prefix: ''

hooks:
    healthchecks: https://hc-ping.com/seu_uuid
    before_backup: 
        - /script_que_faz_port_knocking
        - docker exec -i postgres_container /bin/bash -c "PGPASSWORD=db_pass pg_dump --username db_user db_name" > /caminho/db.sql
        - apt list --installed > ~/apt.installed # salva os pacotes instalados

Esse arquivo faz o backup dos diretórios /etc/ e /home/, no Raspberry Pi (no HD externo e outro diretório) e repo2 não incluindo caches.

Além disso, para não ocupar todo o disco, é definida uma política de retenção (prune). Dessa forma os backups antigos serão deletados. Os backups das últimas 48 horas jamais serão deletados e teremos no máximo dois backups por dia, os backups dos últimos 7 dias, 12 semanais etc … e mantemos todos os mensais e todos anuais.

Observação: Apartir da versão 1.2 do borg, a operação prune não libera de fato o espaço em disco, foi criada uma nova operação chamada compact, então quando rodar o prune chame o compact em seguida.

O Borgmatic também checa a integridade dos backups (opção check do borg/borgmatic) (parte consistency), caso os arquivos sejam corrompidos no disco.

Também salva o dump de bancos de dados Mysql/MariaDB e PostgreSQL.

No meu caso, o meu Raspberry Pi está protegido por port knocking (técnica para proteger serviços numa rede). A porta do ssh fica fechada e só abre após uma sequência de portas são batidas apenas para o IP que acertou e por um período de tempo. Então o Borgmatic executa esse script antes do backup.

healthchecks.io: É um serviço que monitora se uma tarefa (no nosso caso o backup) está sendo feito na frequência esperada. Caso o backup deixe de ser feito com exito vamos receber um email e/ou uma mensagem no Telegram (tem outras integrações). Crie sua conta no site e coloque o link que o borgmatic deve pingar.

Passo a passo

  1. Crie o seu arquivo de configuração do Borgmatic, se quiser, adapte a partir do meu arquivo e mude as pastas que você deseja fazer backup (source_directories) e onde serão salvos (repositories).

Vale lembrar que devido ao cartão SD do Raspberry Pi, não é aconselhável salvar nada crítico nele pois depois de algum tempo o cartão simplesmente corrompe e tudo é perdido. Há algumas boas práticas para mitigar isso, mas não há milagres! Então conecte um HD externo criptografado no Raspberry Pi e salve os backups lá.

  1. Gere sua senha segura usando um gerenciador de senhas como o KeePassXC e coloque no campo encryption_passphrase.

  2. Por fim, crie a sua conta no healthchecks.io, configure as integrações (se quer receber alertas por email, Telegram etc …), e coloque o link do check no arquivo.

  3. Com o seu arquivo de configuração pronto, salve-o em: ~/.config/borgmatic/config.yaml

O próximo passo é criar uma chave ssh para conectar no seu Raspberry Pi,

  1. No terminal, faça: ssh-keygen -t ed25519 -C "usuario@PC.borg", lembrando que essa chave não pode ter senha (então só de um enter sem digitar nada), pois o backup vai rodar automaticamente. Caso já tenha uma chave importante com senha que usa pra outras coisas é interessante ter uma chave dedicada pro borg sem senha (configure seu ~/.ssh/config para controlar qual chave usar etc …)

  2. Copiando a sua nova chave ssh no Raspberry Pi: ssh-copy-id -i ~/.ssh/id_ed25519 usuario@192.168.1.160 (ajuste o usuario e o IP) e digite a senha, depois veja se fazendo ssh usuario@192.168.1.160 ele logará no Raspberry Pi automaticamente sem pedir senha.

  3. Para iniciar o repositório: borgmatic init -e repokey-blake2

  4. Adicionando no crontab: para rodar o backup automaticamente, vamos colocar para ser executado via cron, faça:

$ crontab -e
5 */2 * * * ~/.local/bin/borgmatic create --stats --files --log-file ~/borgmatic.log --verbosity 1 --monitoring-verbosity 1 --log-file-verbosity 2

Repare que a opção create do borgmatic foi especificada, dessa forma o borgmatic vai apenas criar o backup, caso queira que o Borgmatic além de criar seja feito o check e prune, retire a opção create, dessa forma o Borgmatic fará o prune, depois o create e por fim o check.

Isso fará que o backup seja executado a cada 2 horas no minuto 5, dica: o site crontab.guru ajuda a entender a sintaxe do cron.

Observação, se optou por rodar o borg como root (por causa dos problemas de permissão), faça:

$ sudo crontab -e -u root
5 */2 * * * PATH=$PATH:/usr/bin:/usr/local/bin /root/.local/bin/borgmatic create --stats --files --log-file ~/borgmatic.log --verbosity 1 --monitoring-verbosity 1 --log-file-verbosity 2

Por fim, é preciso testar se o backup funcionou. Vamos restaurar um backup feito pelo borg para ver se todos os arquivos estão lá e se tudo funciona como deveria:

$ borgmatic list

t430-2020-09-07T16:00:09.936979  Mon, 2020-09-07 16:00:12 [c9...5f]
t430-2020-09-07T16:24:16.752983  Mon, 2020-09-07 16:24:21 [fa...97]
t430-2020-09-07T16:28:19.692725  Mon, 2020-09-07 16:28:22 [93...9d] <--(mais recente)

$ mkdir /tmp/borg_teste
$ borg mount /mnt/bak/borgbackups/borg_pc/::t430-2020-09-07T16:28:19.692725 /tmp/borg_teste/
$ cd /tmp/borg_teste/
$ du -shxc *
6.1G	home
6.1G	total

Repare como o du reportou que temos 6 GB de arquivos, ou seja, tudo funcionando como deveria! Outra opção é gerar um tar com a opção export-tar.

Modo append-only

Chegamos na esperada parte do modo append-only. Esse modo faz com que o borg não possa deletar ou sobrescrever os dados inseridos anteriormente.

Afim de habilitar esse modo, nós vamos especificar que quando conectado no Raspberry Pi, o Borg deve rodar no modo append-only. No Raspberry Pi edite o arquivo ~/.ssh/authorized_keys, e adicione:

Edite o arquivo para ficar:

~/.ssh/authorized_keys:
command="borg serve --append-only --restrict-to-path /mnt/bak/borgbackups/borg_pc",restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGc+rutXNxxYCjFpD5v83kDXUVA8Ffh3dWlIeBOc5HgU usuario@PC.borg

Adicionamos antes da chave o sequinte: command="borg serve --append-only --restrict-to-path /mnt/bak/borgbackups/borg_pc",restrict.

Repare que o borg está sendo instanciado com a opção --append-only e opcionalmente passamos o --restrict-to-path que restringe quais repositórios aquela chave pode acessar (pode ser especificada múltiplas vezes).

Para testar, faça ssh usuario@192.168.1.160 e espere alguns segundos, dê um enter e aparecerá:

$ ssh usuario@192.168.1.160
PTY allocation request failed on channel 0

$LOG ERROR borg.archiver Remote: Borg 1.1.13: Got unexpected RPC data format from client.
Connection to 192.168.1.160 closed.

Repare que agora não é mais aberto um shell como antes, ele executa o borg assim que conecta.

Prune no modo append-only: com o append-only não conseguiremos que o borg faça o prune (deletar backups antigos, pra não encher o disco), nesse caso, copiei o config.yaml do borgmatic no Raspberry Pi e rodo prune e check de lá (não esqueça que na parte de repositories é preciso especificar apenas o caminho da pasta, sem usuario@rasp)(via cron tmb)(também criei um check no healtchecks dedicado pro prune e check).

O crontab na raspberry pi é o seguinte:

$ sudo crontab -e -u borguser

PATH=/home/borguser/.local/bin:/usr/local/bin:/usr/bin:/bin
# prune (e compact) executado diariamente
42 0 * * * borgmatic prune compact --stats --list --log-file ~/borgmatic-prune.log -c ~/.config/borgmatic.d/* --verbosity 1 --monitoring-verbosity 1 --log-file-verbosity 2 > /dev/null 2>&1

# checagem da integridade (check) executada semanalmente
21 2 * * 1 borgmatic check --log-file ~/borgmatic-checks.log -c ~/borgmatic.d/* --verbosity 1 --monitoring-verbosity 1 --log-file-verbosity 2 > /dev/null 2>&1

Borg no QubesOS

O cron não vem instalado por padrão nos templates do QubesOS, instale o pacote cronie para templates Fedora e cron templates Debian, e faça qvm-service --enable work crond no dom0 no Debian é apenas cron, para habilitar o cron na Qube work.

Como usar a nuvem de maneira segura

No caso do borg, a criptografia já é nativa, então basta dar um jeito de “transferir” os arquivos do borg para a nuvem, nesses casos podemos usar o rclone.org que permite acessar os provedores de nuvem populares como Google Drive, Dropbox etc…

Outra opção é usar um provedor que suporta o borg, da mesma forma que fizemos com o Raspberry Pi com uma VPS genérica pode ser usada para mesma finalidade. Algumas hospedagens populares são: DigitalOcean, Linode, vultr, buyvm, ovh e hetzner.

Por fim, outra opção é usar um provedor que integra o borg: O rsync.net suporta e tem preço promocional para quem usar o borg, a hetzner tem storage box e o meu favorito é o borgbase.com que tem um plano gratuito com 10 GB.