Estratégia de backup para servidores root que aguenta quando é preciso
A regra 3-2-1 num único servidor root, restic e Borg com exemplos, retenção e encriptação. E o passo que quase toda a gente salta: testar mesmo o restauro.
A checklist para os primeiros 30 minutos termina com um arquivo tar de /etc e com a constatação de que isso ainda não é um backup, mas sim uma cópia no mesmo disco. É daí que este artigo parte: como transformar isso numa estratégia que sobrevive a uma perda total.
A frase à volta da qual gira tudo: um backup do qual nunca se recuperou nada não é um backup, é uma esperança. Todo o resto serve para transformar isso numa afirmação verificada.
Todos os comandos correm como root. Se trabalha como utilizador normal, anteponha sudo a cada comando. Os sistemas de referência são o Debian 13 (trixie), o Debian 12 (bookworm), o Ubuntu 24.04 LTS e o Ubuntu 22.04 LTS. Onde os quatro divergem, fica indicado.
Antes de mudar seja o que for: o caminho de volta
No backup em si raramente se estraga alguma coisa. Perigosos são os gestos à volta dele: um restauro que escreve por cima do sistema em funcionamento, um repositório que enche o disco do sistema, ficheiros de chave que substituem o seu próprio acesso. Quatro pontos antes de começar.
1. Conheça o acesso à consola antes de precisar dele
Nos servidores root KVM e nos servidores dedicados da KernelHost, a consola VNC está na área de cliente. Não depende da pilha de rede do sistema convidado e continua a responder mesmo quando o SSH fica calado. É o caminho de fuga para quando um restauro escreveu uma sshd_config antiga ou umas authorized_keys antigas por cima das atuais. Autentique-se uma vez por essa via antes de precisar dela e verifique se sabe a palavra-passe de root.
2. Nunca restaure para / à primeira tentativa
O primeiro restauro vai sempre para um diretório vazio, por exemplo /var/tmp/restore-test. A partir daí compara e copia de volta apenas o que interessa. Um restauro direto para / também sobrescreve os ficheiros que foram alterados por bons motivos desde o backup.
3. Mantenha uma segunda sessão aberta
Enquanto mexer em chaves SSH ou no authorized_keys do destino, vale a mesma regra que na configuração de uma firewall: deixe um segundo terminal com a ligação de pé e só o feche quando uma ligação nova funcionar.
4. Verifique o espaço antes de o repositório crescer
df -h /
df -i /
A segunda linha é a que quase toda a gente esquece: um sistema de ficheiros também enche quando ainda há gigabytes livres, nomeadamente quando acabam os inodes. Um repositório local que enche o disco do sistema é uma das avarias que os administradores mais provocam a si próprios. Por isso, aqui o destino fica fora do servidor desde o início.
A regra 3-2-1 aplicada a um único servidor
- Três cópias. Os dados de produção já são a primeira cópia. São precisos, portanto, dois backups e não um.
- Dois suportes diferentes. Dois diretórios no mesmo disco são um só suporte, e dois discos no mesmo RAID também: um
rmpor descuido atinge os dois. O RAID protege contra a falha de uma unidade e contra mais nada. - Uma cópia fora de casa. Nem o mesmo servidor, nem a mesma conta de gestão e, idealmente, nem o mesmo local.
São precisos dois acrescentos. Primeiro, uma das cópias deve ficar num sítio que o próprio servidor não consiga apagar, porque quem se apoderar do seu servidor encontra lá as credenciais de acesso ao destino. Segundo, uma cópia só conta depois de ser verificada. Uma imagem do sistema dentro da mesma área de cliente é cómoda, mas como cópia fora de casa não conta.
Defina além disso dois números: quantas horas de perda de dados consegue aceitar (isso determina o intervalo entre duas execuções) e quanto tempo pode demorar o restauro (isso decide se precisa também de uma imagem do sistema).
O que deve entrar no backup e o que não deve
O erro mais frequente não é guardar de menos, é guardar tudo. Quem copia / sem exclusões leva atrás caches de pacotes, ficheiros temporários e a swap.
| O quê | Local típico | Método | Porquê |
|---|---|---|---|
| Configuração | /etc | Backup de ficheiros | Reconstruir à mão custa dias |
| Seleção de pacotes | Ficheiro de texto, ver abaixo | Backup de ficheiros | Torna a reconstrução reproduzível |
| Dados úteis | /var/www, /srv, /home | Backup de ficheiros | Impossíveis de voltar a obter |
| Bases de dados | /var/lib/mysql | Dump em vez de cópia de ficheiros | As cópias de ficheiros a quente ficam inconsistentes |
| Certificados | /etc/letsencrypt | Backup de ficheiros | Chave da conta e rate limit da autoridade certificadora |
| Container | Ficheiros compose e volumes | Backup de ficheiros | As imagens voltam a descarregar-se, os volumes não |
| Não guardar | /proc, /sys, /dev, /run, /tmp | excluir | Interfaces do kernel sem conteúdo de ficheiro |
| Não guardar | /var/cache, swap | excluir | Podem ser gerados de novo a qualquer momento |
apt-mark showmanual > /root/lista-pacotes.txt
dpkg --get-selections > /root/estado-pacotes.txt
wc -l /root/lista-pacotes.txt /root/estado-pacotes.txt
O apt-mark showmanual lista apenas os pacotes instalados de propósito, sem as dependências que vieram atrás: é a lista curta de que precisa ao reconstruir o servidor.
Ficheiros, base de dados e imagem: três métodos que não se substituem
| Método | Protege bem contra | Não protege contra | Armadilha típica |
|---|---|---|---|
| Backup de ficheiros | Apagar por engano, ficheiros isolados danificados, perda do servidor | A inconsistência de bases de dados abertas | Copiar de passagem os ficheiros da base de dados a quente |
| Backup da base de dados (dump) | A inconsistência, voltar a um estado limpo | Tudo o que está fora da base de dados | Um dump interrompido cujo ficheiro parece bom |
| Imagem do sistema | A falha total, um tempo de restauro curto | Um apagamento detetado tarde, a perda da conta | Poucos estados, todos na mesma conta |
Daqui sai uma ordem, não uma escolha. Primeiro o servidor de base de dados escreve um dump, depois corre o backup de ficheiros, e o diretório de dados fica de fora. Uma cópia de ficheiros de /var/lib/mysql a quente apanha tabelas diferentes em momentos diferentes. Se ela se deixa restaurar ou não, só o descobre no pior momento possível.
O ficheiro de credenciais, as permissões e as armadilhas do dump são tratados em Fazer backup diário das bases de dados MySQL no Debian, Ubuntu e Linux. O importante é o ponto de entrega: os dumps aterram em /var/backups/db, ficam lá um ou dois dias, e da retenção trata o repositório. O PostgreSQL guarda-se com pg_dumpall como utilizador postgres.
restic ou Borg
Ambos partem os ficheiros em blocos, guardam blocos iguais uma única vez, encriptam e mantêm estados versionados. Ambos estão empacotados nas quatro distribuições. A diferença que decide está na última linha.
| Característica | restic | Borg |
|---|---|---|
| Pacote | restic | borgbackup, comando borg |
| Encriptação | sempre ativa | à escolha, faz sentido repokey ou keyfile |
| Libertar espaço | forget com --prune | prune e depois compact |
| Proteção contra apagamento pelo servidor | Servidor REST ou armazenamento de objetos com versionamento | borg serve --append-only |
| Requisito no destino | Basta um acesso SFTP | O Borg tem de estar instalado no destino |
Num armazenamento onde não pode instalar nada, o Borg fica fora de questão. Havendo um segundo servidor Linux sob a sua gestão, o modo append-only joga a favor do Borg.
Configurar com o restic
apt update
apt install -y restic
restic version
Verifique a saída antes de criar um repositório: as quatro distribuições entregam versões muito diferentes, e um repositório escrito por uma versão mais recente nem sempre se deixa abrir por uma mais antiga.
Acesso ao destino
O destino é aqui um segundo servidor alcançado por SSH. A chave pertence ao root, porque só o root pode ler todos os ficheiros que entram no backup:
ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519_backup -C 'backup srv01'
ssh-copy-id -i /root/.ssh/id_ed25519_backup.pub backup@203.0.113.50
cat > /root/.ssh/config <<'EOF'
Host destino-backup
HostName 203.0.113.50
User backup
IdentityFile /root/.ssh/id_ed25519_backup
BatchMode yes
EOF
chmod 600 /root/.ssh/config
Controlo de sucesso: o ssh destino-backup true corre até ao fim sem qualquer saída e sem qualquer pergunta. A primeiríssima ligação pergunta pela chave do host: responda agora e não mais tarde, dentro de um serviço que não pode esperar por ninguém.
Palavra-passe e repositório
install -d -m 700 /etc/restic
head -c 32 /dev/urandom | base64 | tr -d '\n' > /etc/restic/repo.pass
chmod 600 /etc/restic/repo.pass
cat > /etc/restic/env <<'EOF'
RESTIC_REPOSITORY=sftp:destino-backup:/srv/backup/srv01
RESTIC_PASSWORD_FILE=/etc/restic/repo.pass
EOF
chmod 600 /etc/restic/env
Este ficheiro serve tanto para a shell como para o systemd. Na shell:
set -a; . /etc/restic/env; set +a
restic init
Controlo de sucesso: o restic cat config devolve uma estrutura JSON curta com o identificador do repositório. Se aparecer a pergunta Is there a repository at the following location?, o caminho não está certo ou o restic init nunca chegou a correr.
A primeira execução
cat > /etc/restic/excludes.txt <<'EOF'
/proc
/sys
/dev
/run
/tmp
/var/tmp
/var/cache
/var/lib/apt/lists
/var/lib/mysql
/swapfile
EOF
restic backup / --one-file-system --exclude-file=/etc/restic/excludes.txt --exclude-caches --tag system
O --one-file-system mantém o backup dentro do sistema de ficheiros raiz e deixa de fora as unidades de rede montadas. O --exclude-caches salta os diretórios que se marcaram a si próprios como cache. Excluir /var/lib/mysql é a aplicação prática da secção anterior.
Controlo de sucesso: a execução termina com uma linha do género snapshot 0a1b2c3d saved. A seguir:
restic snapshots
restic stats latest
Na lista aparecem a data e a hora, o nome da máquina e os caminhos. Se o restic stats latest mostrar um tamanho inesperadamente pequeno, há uma exclusão a apanhar mais do que devia.
O mesmo com o Borg
apt install -y borgbackup
borg --version
export BORG_REPO='ssh://backup@203.0.113.50/./srv01'
borg init --encryption=repokey-blake2
borg create --stats --compression zstd ::'system-{now}' /etc /var/www /home /var/backups
borg list
borg info
As quatro distribuições entregam uma versão da série 1.x. O Borg tem de existir nos dois lados, e a versão no destino não deve ser mais antiga do que a do servidor. Use um repositório próprio por servidor: assim poupa-se a ter de limitar a limpeza aos arquivos exatamente deste servidor e pode trabalhar com chaves de acesso separadas.
Controlo de sucesso: o borg list mostra o arquivo com a data e a hora, o borg info mostra o tamanho antes e depois da deduplicação.
Retenção: mais tempo do que a maioria calcula
O tempo de retenção não depende de quanto tempo quer guardar os dados, mas sim de quanto tempo passa até um estrago dar nas vistas. Um diretório apagado nota-se no próprio dia, uma tabela danificada muitas vezes só semanas depois. Quem guarda sete dias fica com sete dias de backups do estrago.
| Tipo de dados | Sugestão | Motivo |
|---|---|---|
| Dumps da base de dados | 7 diários, 4 semanais, 6 mensais | Os danos silenciosos só dão nas vistas tarde |
| Configuração | 30 diários, 12 mensais | Perceber quando mudou o quê |
| Dados úteis | 30 diários, 6 mensais | Raramente se dá logo pela falta de ficheiros apagados |
| Logs | o mais curto que for defensável | Grandes e raramente precisos num restauro |
restic forget --dry-run --keep-daily 7 --keep-weekly 4 --keep-monthly 6
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
A passagem de ensaio mostra que estados iriam desaparecer. Sem --prune vão-se apenas as referências e o espaço continua ocupado. No Borg isto faz-se em dois passos desde a versão 1.2, e o segundo comando esquecido explica a maioria dos repositórios que não querem encolher:
borg prune --list --dry-run --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg prune --list --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg compact
Controlo de sucesso: o restic snapshots ou o borg list mostra o escalonamento esperado, e o tamanho ocupado no destino baixa.
A encriptação e a chave que depois já ninguém tem
As duas ferramentas encriptam antes de os dados saírem do servidor. O destino só vê blocos ilegíveis, e é isso que torna aceitável um armazenamento alheio. O preço é claro: sem a palavra-passe ou sem a chave, os dados estão definitivamente perdidos. Não existe qualquer backdoor.
Daqui saem duas regras. Primeira: a palavra-passe pertence a um segundo sítio, normalmente a um gestor de palavras-passe. Uma palavra-passe que só existe em /etc/restic/repo.pass desaparece com o servidor, e com ela o backup. Segunda: no Borg com repokey, exporte a chave e guarde-a fora do servidor, porque nesse modo ela fica dentro do próprio repositório:
borg key export ::
Controlo de sucesso: execute o restic snapshots noutra máquina, com a palavra-passe tirada do gestor de palavras-passe. Uma palavra-passe que nunca usou a partir de outro sítio está por confirmar.
Proteger o destino contra apagamentos
Um atacante com privilégios de root também tem acesso à palavra-passe guardada e à chave para o destino. Ou seja, pode apagar o backup antes de encriptar os dados de produção. Por isso é preciso um suporte que aceite estados novos mas não permita apagar nada. No Borg, isso configura-se no authorized_keys do utilizador de backup no destino:
command="borg serve --append-only --restrict-to-path /srv/backup/srv01",restrict ssh-ed25519 AAAA... backup srv01
A partir daí, a chave só aceita backups e apenas dentro desse caminho. Conte com o seguinte: um prune corre aqui até ao fim, mas não liberta espaço nenhum, porque o apagamento não chega a ser executado no destino. A limpeza faz-se onde o servidor não tem acesso. No restic, esse papel cabe ao servidor REST em modo append-only ou a um armazenamento de objetos com versionamento. Um acesso SFTP simples não chega para isso.
Automatizar com um timer do systemd
Um timer é preferível a um cronjob, porque escreve a saída no journal, recupera as execuções falhadas e pode espalhar a hora de arranque. Sobre a construção de unidades: Criar um serviço systemd próprio.
cat > /etc/systemd/system/backup.service <<'EOF'
[Unit]
Description=Backup diário com restic
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
Nice=10
IOSchedulingClass=idle
ExecStart=/usr/bin/restic backup / --one-file-system --exclude-file=/etc/restic/excludes.txt --exclude-caches --tag system
ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
EOF
cat > /etc/systemd/system/backup.timer <<'EOF'
[Unit]
Description=Inicia o backup diário
[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now backup.timer
systemd-analyze calendar '*-*-* 02:30:00'
Várias linhas ExecStart dentro de uma unidade oneshot correm umas a seguir às outras, e uma falha corta a cadeia. A limpeza só corre, portanto, depois de um backup bem-sucedido. Se o destino for um sistema de ficheiros montado, é preciso um seguro à frente, senão a execução escreve sem ninguém dar por isso dentro do ponto de montagem vazio:
ExecStartPre=/usr/bin/mountpoint -q /mnt/backup
Controlo de sucesso:
systemctl start backup.service
systemctl list-timers backup.timer
journalctl -u backup.service -n 50 --no-pager
O systemctl list-timers tem de indicar uma próxima hora de arranque. Se ali não estiver nada, o timer não está ativado. O ponto mais importante vem no fim: uma execução que deixa de correr em silêncio é a forma normal de um backup falhar. Verifique com systemctl is-failed backup.service, ou acrescente como última linha ExecStart uma chamada a um serviço de monitorização externo que dispare o alarme quando o sinal de vida diário não chegar.
Testar o restauro
O teste pequeno, todos os meses, cinco minutos
mkdir -p /var/tmp/restore-test
restic restore latest --target /var/tmp/restore-test --include /etc/ssh/sshd_config
diff /etc/ssh/sshd_config /var/tmp/restore-test/etc/ssh/sshd_config && echo "idêntico"
Com o Borg é equivalente, e este guarda os caminhos sem a barra inicial:
cd /var/tmp/restore-test
borg extract --list ::system-2026-09-03T02:30:00 etc/ssh/sshd_config
Verifique além disso a integridade do repositório. A segunda linha de cada bloco volta a ler os dados e recalcula as somas de verificação, no restic apenas para uma parte, para que a execução não demore horas:
restic check
restic check --read-data-subset=1/7
borg check
borg check --verify-data
Controlo de sucesso: o restic check termina com no errors were found, o borg check termina sem qualquer mensagem de erro. Um repositório que só é verificado uma vez por ano pode ter estado danificado durante onze meses.
O teste grande, uma vez por ano
O teste pequeno prova que os ficheiros são legíveis. Não prova que consegue voltar a pôr o serviço a funcionar. Para isso é preciso a passagem completa num segundo servidor vazio: instalar o sistema base, aplicar a lista de pacotes, ligar o repositório, trazer os dados de volta, importar o dump e arrancar os serviços. Cronometre o tempo. Esse número é a sua duração real de restauro e, pela experiência, é um múltiplo da estimada.
Aponte o que faltou. São quase sempre as mesmas coisas: um ficheiro fora dos caminhos guardados, um serviço com a configuração em /opt, um certificado sem a chave da conta, uma base de dados sem utilizadores nem permissões. Essa lista é o que se ganha com o teste.
Erros frequentes e soluções
Host key verification failed. O serviço corre como root, e o root nunca confirmou a chave do host do destino. Execute uma vez à mão ssh destino-backup true ou ssh-keyscan -H 203.0.113.50 >> /root/.ssh/known_hosts. Na consola funciona e no timer não: é quase sempre este o erro.
Permission denied (publickey). Utilizador errado, chave errada ou permissões erradas no destino: o .ssh precisa de 700, o authorized_keys de 600, e ambos pertencem ao utilizador do destino.
Is there a repository at the following location? O restic não encontra nenhuma estrutura de repositório: caminho errado, restic init que nunca correu, ou um destino que naquele momento não está acessível.
Fatal: wrong password or no key found O ficheiro da palavra-passe não corresponde ao repositório, normalmente porque foi gerado de novo mais tarde. Verifique com cat -A /etc/restic/repo.pass se lá entrou algum espaço a mais.
repository is already locked exclusively by Uma execução interrompida deixou o seu bloqueio para trás. Verifique primeiro que já não corre nada e só depois use o restic unlock. No Borg a mensagem é Failed to create/acquire the lock com o acrescento (timeout), e o comando é borg break-lock. Os dois são arriscados enquanto uma execução ainda estiver ativa.
Warning: The repository at location ... was previously located at ... O endereço do repositório mudou e o Borg pergunta de forma interativa. Dentro de uma unidade, o comando fica assim à espera de uma resposta que nunca chega. Depois de confirmar que se trata do mesmo repositório, defina BORG_RELOCATED_REPO_ACCESS_IS_OK=yes no ficheiro de ambiente.
No space left on device no destino. Ou a limpeza não corre de todo, ou corre sem --prune ou sem borg compact. Se, pelo contrário, foi um dump que encheu o sistema de ficheiros raiz, o artigo Disco cheio: encontrar e libertar espaço no servidor Linux ajuda a resolver.
A execução dá o backup como bem-sucedido, mas não guarda quase nada. Há uma exclusão a apanhar mais do que devia, ou um caminho mal escrito. Compare o restic stats latest com o valor da véspera. Um backup que de repente fica ordens de grandeza mais pequeno é um alarme e não um sucesso.
Diferenças entre as distribuições
- Os nomes dos pacotes são iguais nos quatro sistemas:
resticeborgbackup. As versões entregues é que não. - Logs: o Debian 13 e muitas instalações de Debian 12 não trazem o rsyslog. Aí a saída da execução só se encontra no journal, ou seja, através do
journalctl -u backup.service. No Ubuntu 22.04 e 24.04 existe ainda o registo em/var/log. - Montar estados do backup: o
restic mounte oborg mountprecisam defuse3. Se o pacote faltar, o comando aborta com um aviso sobre umfusermount3em falta. O caminho sem FUSE é orestic restoreou oborg extract. - Ferramenta de base de dados: o Debian entrega apenas MariaDB, e aí chama-se
mariadb-dump, com omysqldumpcomo ligação para ela. No Ubuntu também pode correr o MySQL 8, e aí só existe omysqldump.
A verificação final
A estratégia está pronta quando conseguir provar estes sete pontos com um comando e não com uma suposição:
- O
restic snapshotsou oborg listmostra um estado desta noite. - O
systemctl list-timers backup.timerindica uma próxima hora de arranque. - O
restic checkou oborg checknão acusa qualquer erro. - Este mês recuperou um ficheiro isolado e ele ficou depois idêntico ao original.
- O escalonamento corresponde à retenção planeada e o repositório não cresce sem limite.
- A palavra-passe está num segundo sítio e já a usou a partir daí pelo menos uma vez.
- Pelo menos um suporte aceita backups sem que o servidor os possa apagar.
Se faltar o ponto quatro, o que tem é uma suposição. Se faltar o seis, lixo encriptado. Se faltar o sete, um backup que não sobrevive exatamente ao ataque para o qual é mais necessário.
Perguntas frequentes
O que significa a regra 3-2-1 num único servidor root?
Um RAID ou uma imagem do sistema já são um backup?
restic ou Borg: o que se adequa a cada caso?
Porque é que o meu repositório não fica mais pequeno, mesmo apagando estados antigos?
Posso copiar uma base de dados em funcionamento simplesmente como ficheiro?
O que acontece se perder a palavra-passe do repositório?
Com que frequência devo testar o restauro?
Porque é que o meu backup corre à mão, mas não no timer do systemd?
2026 KernelHost GmbH. Todos os direitos reservados. Este guia está protegido por direitos de autor. A sua republicação noutros sites, na íntegra, em parte ou de forma editada, não é permitida sem o nosso consentimento por escrito. Citações com indicação da fonte e ligação são expressamente bem-vindas.

