Restic: backup do VPS para outro servidor
Configure o Restic no Ubuntu 24.04 para enviar backups encriptados por SFTP, executar um timer noturno e testar a restauração fora do VPS.
Por que um backup no mesmo servidor não é um backup
O Restic é uma ferramenta de backup gratuita e de código aberto que envia snapshots encriptados e deduplicados dos seus ficheiros para um repositório noutro local: um segundo VPS, uma máquina em casa ou armazenamento de objetos compatível com S3. Este guia configura-o no Ubuntu 24.04, desde a instalação até um repositório através de SFTP, passando pelo primeiro backup, por um timer noturno do systemd, por uma política de retenção e pelo teste de restauração que comprova que tudo funciona. O destino tem de ser outra máquina, porque uma cópia armazenada no mesmo servidor desaparece com o servidor.
Um diretório backup/ na máquina de origem protege-o de uma única situação: a eliminação acidental de um ficheiro. Não sobrevive à falha de um disco, porque estava nesse disco. Não sobrevive a um atacante com root, porque este elimina primeiro as cópias. Também não sobrevive ao erro de uma conta que remove o próprio VPS. O datacenter menos eficiente do mundo brinca com um tarball chamado backup_final_v2_REAL armazenado na mesma matriz que os dados, e a piada funciona porque muitos de nós já fizemos exatamente isso. A regra é manter a cópia fora da máquina, e o restic é a forma menos problemática de a cumprir.
Restic em quatro ideias
Repositório. É o local onde o restic grava os dados. Trata-se de um diretório no formato próprio do restic, composto por blobs encriptados que apenas o restic consegue ler. Nunca o edite manualmente; aceda a ele através dos comandos do restic e do endereço -r.
Snapshot. É uma imagem dos ficheiros num determinado momento. Cada execução de backup cria um snapshot, cada snapshot pode ser restaurado de forma independente e cada um funciona como uma cópia completa dos dados nesse momento.
Deduplicação. O restic divide os ficheiros em blocos definidos pelo conteúdo e envia apenas os blocos que o repositório ainda não conhece. O primeiro backup envia tudo; cada execução seguinte envia aproximadamente o que mudou. Um snapshot noturno de 20 GB em que 50 MB foram alterados ocupa cerca de 50 MB, razão pela qual é barato manter dezenas de snapshots.
Encriptação por predefinição. Um repositório restic está sempre encriptado (AES-256) e cada comando requer a palavra-passe do repositório. O servidor de backup ou o fornecedor de armazenamento vê apenas blobs encriptados. A consequência é grave: se perder a palavra-passe, os dados desaparecem permanentemente, por conceção. Guarde uma cópia da palavra-passe num local que não seja este servidor. Isto é suficientemente importante para ser referido mais duas vezes abaixo.
Instalar restic no Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionNo Ubuntu 24.04, este procedimento instala o restic 0.16.4, enquanto a versão atual disponibilizada pelo projeto é a 0.19.1. A diferença existe porque uma versão LTS (suporte de longo prazo) fixa as versões dos pacotes, mas isso não é relevante neste caso: a versão 0.16.4 inclui tudo o que é necessário para este guia. Se quiser a versão mais recente pelas melhorias de velocidade, descarregue a compilação oficial num único binário na página de releases do projeto restic no GitHub, extraia-a com bunzip2 e instale-a em /usr/local/bin/restic; não há mais nenhum passo para instalar o restic.
Crie o repositório noutro servidor através de SFTP
Precisa de uma máquina de destino: um segundo VPS pequeno é a opção habitual, mas qualquer máquina com um servidor SSH e espaço em disco disponível funciona. O Restic utiliza SFTP (transferência de ficheiros através de SSH), por isso o host de backup não precisa de ter nenhum software instalado. Neste guia, o host de backup é 10.0.0.12, com um utilizador chamado restic. Não atribua a esse utilizador o nome backup: o Ubuntu e o Debian incluem em todas as instalações uma conta de sistema reservada chamada backup (uid 34, sem shell de login), por isso adduser backup falha e ssh backup@... é criado em nologin.
A tarefa noturna será executada como root no servidor que está a ser salvaguardado, por isso root precisa de autenticação por chave no host de backup. Crie uma chave dedicada sem palavra-passe, porque não haverá ninguém presente às 3am para a introduzir, e copie-a para o host:
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login worksSe as chaves forem uma novidade para si, Noções básicas sobre gestão de chaves SSH explica o modelo, as permissões e como revogar uma chave mais tarde.
Em seguida, defina a palavra-passe do repositório. Gere uma palavra-passe forte num ficheiro acessível apenas por root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordCopie agora essa palavra-passe para o seu gestor de palavras-passe, antes de continuar. Se este VPS deixar de funcionar, o repositório e esta palavra-passe permitem recuperar tudo; sem a palavra-passe, o repositório não permite recuperar nada.
Inicialize o repositório:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1A alternativa é utilizar armazenamento de objetos compatível com S3, que é a escolha certa quando não quer manter uma segunda máquina. Qualquer bucket compatível com S3 funciona da mesma forma; apenas o endereço e duas variáveis de credenciais mudam:
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initTudo depois de init é idêntico para ambos os destinos. O resto deste guia mostra o endereço SFTP; substitua-o pelo seu.
O primeiro backup, com exclusões
Faça backup dos dados que não pode reinstalar, não de todo o sistema de ficheiros. O sistema operativo volta a estar disponível após uma reinstalação; a sua configuração e os seus dados não. Num VPS típico, isso significa /etc, /home e os locais onde as suas aplicações guardam o estado, como /srv ou /var/www. Exclua as caches, porque ocupam muito espaço, mudam todos os dias e são recriadas automaticamente:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c savedA primeira execução envia tudo, por isso demora algum tempo. Execute o mesmo comando novamente e ele termina em segundos, indicando que alguns ficheiros foram alterados e que foram adicionados alguns MiB, porque a deduplicação só envia blocos novos. Liste o que tem:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsCada snapshot mostra um ID, uma hora e os caminhos que contém. É a partir desses IDs que faz a restauração.
Execuções noturnas com um timer do systemd
Digitar o endereço do repositório em todos os comandos torna-se cansativo, e um backup executado manualmente deixa de ser feito ao fim de um mês. Um script e um timer resolvem os dois problemas. O script define as duas variáveis de ambiente que o restic lê, RESTIC_REPOSITORY e RESTIC_PASSWORD_FILE, para que todos os comandos no seu interior permaneçam curtos:
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shAs linhas forget e check são explicadas nas duas secções seguintes. Agora, vamos definir o agendamento: um serviço oneshot que executa o script e um timer que o inicia às 03:00 todas as noites. Neste caso, um timer é melhor do que uma linha do cron porque a execução fica registada no journal e Persistent=true executa um backup em falta assim que o servidor volta a estar disponível depois de uma interrupção.
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targetAtive o timer e execute o serviço uma vez manualmente para confirmar o seu funcionamento:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers mostra quando ocorrerá a próxima execução. Também pode gerar o par de ficheiros de unidade em vez de os escrever manualmente:
O padrão completo por trás destes dois ficheiros, incluindo a sintaxe de calendário e as diretivas de reforço de segurança que um serviço pode utilizar, está em executar um programa como serviço do systemd numa VPS.
Um backup é apenas um rumor até ser restaurado
Trate esta frase como um mandamento. Um trabalho de backup que termina com sucesso todas as noites prova apenas que um trabalho foi executado; não prova que os seus dados podem ser recuperados. Duas verificações eliminam essa lacuna.
Primeiro, restic check, que o script já executa todas as noites. Verifica a estrutura do repositório e o índice. Assim, a corrupção silenciosa no servidor de backup é detetada na noite seguinte, e não no dia da restauração. Uma vez por mês, execute a versão mais profunda, que descarrega e verifica criptograficamente um décimo aleatório dos dados reais:
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%Como o subconjunto é aleatório em cada execução, as execuções mensais percorrem gradualmente todo o repositório sem nunca exigir o download completo.
Segundo, o teste de restauração. Ainda na sessão de root aberta acima, restaure um diretório real do snapshot mais recente para uma localização temporária e compare-o com os ficheiros ativos:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff não produzir qualquer saída significa que todos os bytes foram recuperados de forma idêntica. Esta é a única evidência que conta. Apague /srv/restore-drill depois. Faça este teste mensalmente. Uma ou duas vezes por ano, faça a versão completa: restaure todo o snapshot mais recente numa VPS temporária e confirme que a aplicação realmente arranca a partir dele. No dia em que precisar de fazer isto sob pressão, vai querer executar um procedimento que já conhece.
Retenção: forget e prune
Sem uma política, os snapshots acumulam-se indefinidamente e o repositório continua a crescer. A linha forget do script aplica uma política todas as noites: --keep-daily 7 mantém um snapshot por dia nos últimos sete dias, --keep-weekly 4 mantém um por semana durante quatro semanas e --keep-monthly 6 mantém um por mês durante seis meses. Tudo o que não estiver protegido por uma regra é esquecido.
forget, por si só, remove apenas os registos dos snapshots; os blocos de dados permanecem no repositório até serem eliminados. É isso que --prune faz: procura blocos que já não sejam referenciados por nenhum snapshot e elimina-os. Só nesse momento o espaço em disco é efetivamente libertado. O prune executa trabalho real no repositório, por isso, num repositório grande, algumas pessoas executam forget todas as noites e --prune semanalmente; em VPS com tamanhos típicos, a execução noturna é suficiente.
Bancos de dados: faça o dump primeiro e depois faça backup do dump
O Restic copia os ficheiros à medida que os lê, enquanto um banco de dados grava continuamente nos próprios ficheiros. Um ficheiro de banco de dados ativo capturado durante uma gravação é restaurado como um banco de dados corrompido, porque a cópia mistura páginas anteriores e posteriores à gravação. A solução é padrão: peça ao mecanismo do banco de dados para gerar uma exportação consistente num ficheiro e deixe o restic fazer backup desse ficheiro.
Para PostgreSQL, adicione uma linha de dump no início de restic-backup.sh, antes do comando restic backup, e inclua o diretório do dump nos caminhos do backup:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump desempenha a mesma função para MariaDB e MySQL. Para ver um exemplo completo deste padrão, a secção de backup do Nextcloud ativa o modo de manutenção, faz o dump do Postgres e copia os ficheiros como um único conjunto consistente, exatamente o conjunto que o restic deve retirar do servidor todas as noites. Com SQLite, a ideia é a mesma, mas com uma abordagem mais simples: o guia do Vaultwarden para o contentor durante alguns segundos para criar uma cópia a frio de db.sqlite3, e esse arquivo é o que o restic envia para fora do servidor.
FAQ
Os backups do restic são encriptados?
Sim, sempre. Cada repositório restic é encriptado com AES-256. Não existe um modo sem encriptação e cada comando exige a palavra-passe do repositório. A máquina ou o fornecedor que armazena o repositório guarda apenas blobs encriptados, portanto um servidor de backups comprometido não expõe os seus ficheiros. O compromisso é absoluto: sem a palavra-passe, ninguém consegue recuperar os dados. Guarde uma cópia fora do servidor.
O restic faz backups incrementais?
Cada snapshot do restic comporta-se como um backup completo, mas utiliza armazenamento incremental. O restic divide os ficheiros em blocos e envia apenas os blocos que ainda não estão armazenados no repositório. Assim, uma execução noturna transfere aproximadamente o que mudou nesse dia. Ao contrário dos esquemas incrementais tradicionais, não existe uma cadeia para reproduzir. Qualquer snapshot é restaurado diretamente e eliminar um snapshot antigo nunca danifica um snapshot mais recente.
Como restauro ficheiros a partir de um backup do restic?
Execute restic snapshots para encontrar o ID do snapshot. Em seguida, execute restic restore <id> --target /some/empty/dir para o restaurar. Adicione --include /path para restaurar apenas parte dele. latest pode ser usado em vez de um ID. O restic recria a estrutura de diretórios original sob o destino. Por isso, restaurar /etc/ssh coloca-o em /some/empty/dir/etc/ssh. Teste este procedimento antes de precisar dele, porque um backup não testado é apenas uma suposição.
Com que frequência devo executar o backup do restic?
Todas as noites é a frequência mínima sensata para um servidor, e a deduplicação reduz o custo: cada execução envia apenas os blocos alterados desde a execução anterior. Dados que mudam rapidamente, ou cuja perda de um único dia seria grave, podem ser protegidos a cada poucas horas com o mesmo padrão de temporizador. A frequência é apenas metade do trabalho. Execute também restic check regularmente e faça um teste de restauração mensal, porque uma agenda sem verificação transmite uma falsa sensação de segurança.
O que acontece se eu perder a palavra-passe do repositório restic?
Os backups ficam irrecuperáveis. A encriptação do restic não tem porta dos fundos nem mecanismo de reposição. Por isso, a palavra-passe é tão importante como os próprios backups. Guarde uma cópia no seu gestor de palavras-passe e noutro local durável que não seja o servidor protegido pelo backup. Enquanto ainda tiver acesso, restic key add pode registar uma segunda palavra-passe para o mesmo repositório, fornecendo-lhe uma alternativa.