SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

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. É um diretório no formato próprio do restic, cheio de blobs cifrados, que apenas o restic consegue ler. Nunca o edite manualmente; interaja com ele através dos comandos do restic e do endereço -r.

Snapshot. É uma imagem dos ficheiros num determinado momento. Cada execução da cópia de segurança cria um snapshot. Cada snapshot pode ser restaurado de forma independente. Cada um comporta-se como uma cópia completa dos seus dados naquele 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. A primeira cópia envia tudo. Cada execução seguinte envia aproximadamente o que mudou. Um snapshot noturno de 20 GB em que 50 MB mudaram custa cerca de 50 MB. É por isso que manter dezenas de snapshots é barato.

Cifragem por predefinição. Um repositório restic está sempre cifrado (AES-256). O restic recusa criar ou abrir um repositório com uma palavra-passe vazia, a menos que passe --insecure-no-password (restic 0.17.0 e posteriores). Por isso, um repositório configurado como neste guia precisa da sua palavra-passe em cada comando. O servidor de cópias ou o fornecedor de armazenamento vê apenas blobs cifrados. A consequência é grave: se perder a palavra-passe, os dados desaparecem de forma permanente e por conceção. Guarde uma cópia da palavra-passe num local que não seja este servidor. Isto é suficientemente importante para voltar a ser referido mais duas vezes abaixo.

Instalar restic no Ubuntu 24.04

sudo apt update && sudo apt install -y restic
restic version

No 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 works

Se 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-password

Copie 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 init
created restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1

A 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 init

Tudo 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 saved

A 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 snapshots

Cada 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 check
sudo chmod 700 /usr/local/bin/restic-backup.sh

As 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.target

Ative 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 -f

systemctl 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:

ToolGenerate the backup service and timer

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.

Uma cópia de segurança é apenas um rumor até ser restaurada

Trate esta frase como uma regra. Uma tarefa de cópia de segurança que termina com sucesso todas as noites prova apenas que uma tarefa foi executada. Não prova que os seus dados possam ser recuperados. Duas verificações eliminam essa dúvida.

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 cópias é detetada na noite seguinte, e não no dia da restauração. Uma vez por mês, execute a versão mais profunda. Esta versão 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 é escolhido aleatoriamente em cada execução, a documentação do restic é explícita: não há garantia de que execuções repetidas cubram todos os ficheiros pack, independentemente do número de execuções. Se quiser que as execuções mensais percorram todo o repositório sem pagar nunca por um descarregamento completo, utilize a forma com grupos fixos: --read-data-subset=1/10 num mês, 2/10 no mês seguinte e assim sucessivamente até 10/10. O restic divide os ficheiros pack em dez grupos aproximadamente iguais e verifica apenas o grupo n. Assim, um ciclo completo de dez execuções lê cada grupo uma vez.

Segundo, o exercício de restauração. Ainda na shell root usada acima, restaure um diretório real do snapshot mais recente para uma localização temporária e compare-o com os ficheiros em produção:

restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/ssh

diff sem imprimir nada significa que todos os bytes foram recuperados de forma idêntica. Esta é a única evidência que conta. Elimine /srv/restore-drill depois. Faça este exercício mensalmente. Uma ou duas vezes por ano, faça a versão completa: restaure o snapshot mais recente inteiro numa VPS temporária e confirme que a aplicação inicia realmente a partir dele. No dia em que precisar que isto funcione sob pressão, vai querer já ter executado este procedimento como rotina.

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.gz

mysqldump 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

As cópias de segurança do restic estão cifradas?

Sim, sempre. Todos os repositórios restic estão cifrados com AES-256 e não existe um modo sem cifragem. O restic também recusa uma palavra-passe vazia, a menos que passe --insecure-no-password (disponível desde o restic 0.17.0). Por isso, um repositório configurado como neste guia precisa da sua palavra-passe em cada comando. A máquina ou o fornecedor que armazena o repositório mantém apenas blobs cifrados. Assim, um servidor de cópias comprometido não expõe os seus ficheiros. A consequência é absoluta: sem a palavra-passe, ninguém consegue recuperar os dados. Guarde uma cópia fora do servidor.

O restic faz cópias de segurança incrementais?

Cada snapshot do restic comporta-se como uma cópia de segurança completa, mas utiliza armazenamento incremental. O restic divide os ficheiros em blocos e envia apenas os blocos que o repositório ainda não armazenou. 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 uma cópia de segurança do restic?

Execute restic snapshots para encontrar o ID do snapshot. Depois, execute restic restore <id> --target /some/empty/dir para o restaurar, adicionando --include /path para restaurar apenas uma parte. 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 os ficheiros em /some/empty/dir/etc/ssh. Pratique este procedimento antes de precisar dele, porque uma cópia de segurança não testada é apenas um rumor.

Com que frequência devo executar a cópia de segurança do restic?

Todas as noites é o mínimo razoável para um servidor. A deduplicação torna o processo barato, porque 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 copiados 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 exercício de restauração mensalmente, porque um agendamento sem verificação proporciona apenas uma falsa sensação de segurança.

O que acontece se eu perder a palavra-passe do repositório restic?

As cópias de segurança ficam irrecuperáveis. A cifragem do restic não tem porta traseira nem mecanismo de reposição. Por isso, a palavra-passe é tão importante como as próprias cópias de segurança. Guarde uma cópia no seu gestor de palavras-passe e noutro local durável que não seja o servidor copiado. Enquanto ainda tiver acesso, restic key add pode registar uma segunda palavra-passe para o mesmo repositório. Assim, fica com uma palavra-passe de reserva.