O mascote urso-polar da NordBastion em pé em um cofre nórdico de pedra escura ao lado de um rack de servidores, erguendo uma chave ciano brilhante, enquanto uma corrente de cinco blocos holográficos ciano marcados com cadeados atravessa em arco um portal rúnico rumo a um segundo rack de servidores ao longe sob uma aurora tênue
Tutorial · Opsec·16 min de leitura · 45 min prático

Backup de VPS criptografado.
Fora do local, deduplicado, e fora de alcance.

Backup de VPS criptografado em seis passos: de um servidor desprotegido a um repositório criptografado e verificado numa segunda máquina, numa segunda jurisdição — restic e Borg comparados, dumps de banco de dados que restauram limpos, um timer systemd, e um repositório somente-anexação que um servidor comprometido não consegue apagar. A segunda máquina custa $3.90 por mês. Testado no Debian 12.

As seis etapas
  1. 01

    Inventário

    O que não pode ser reconstruído

  2. 02

    Instalar

    restic ou Borg

  3. 03

    Destino

    Um segundo bastião

  4. 04

    Inicializar

    Repositório + primeira execução

  5. 05

    Automatizar

    Dumps, timer, retenção

  6. 06

    Simulação

    Restaure, e cronometre

Antes de começar · Para que serve

Quatro formas de os dados morrerem. Só uma delas é um disco quebrado.

Quase toda discussão sobre backup dá errado no primeiro minuto, porque as duas pessoas conversando têm falhas diferentes em mente. Uma está imaginando um disco morto. A outra está imaginando uma manhã de terça-feira em que a conta simplesmente sumiu. Elas precisam de respostas diferentes, e uma configuração que só sobrevive à primeira parece segura até ser testada pela segunda.

Existem quatro modos de falha que vale a pena projetar para evitar, e eles não são variações de um mesmo tema — cada um derrota uma defesa diferente.

Hardware. A NVMe falha, o nó hospedeiro morre, o array perde dois membros ao mesmo tempo. Essa é a falha para a qual todo mundo se planeja, e é a mais rara em infraestrutura virtualizada moderna. Armazenamento redundante resolve isso. Armazenamento redundante não resolve mais nada, e é por isso que RAID não é um backup e nunca foi: ele copia toda escrita fielmente, inclusive a escrita que diz "apagar tudo".

Humano. Um script de migração rodado contra produção. Um DROP TABLE no terminal errado. Um rsync com os argumentos invertidos. Essa é, de longe, a causa mais comum de perda real de dados, e a única defesa contra ela é o histórico — uma cópia de antes do erro, guardada em algum lugar que o erro não alcançou. O tempo é o ingrediente: se a única cópia é um espelho trinta segundos atrasado, ele já contém o erro.

Malicioso. Alguém consegue root, ou um ransomware entra por uma aplicação sem patch. A primeira coisa que o ransomware moderno faz é procurar configuração de backup — credenciais, compartilhamentos montados, chaves de nuvem — e destruir o que encontrar, justamente porque uma restauração funcional transforma uma catástrofe numa tarde. Uma credencial de backup que pode apagar é uma credencial de backup que o atacante herda. É para essa falha que existe o capítulo de somente-anexação deste guia.

De custódia. Nada quebrou e nada foi atacado; você simplesmente perdeu o acesso. Uma conta suspensa por um sinal automático de fraude, um cartão que falhou enquanto você estava viajando, uma contestação, uma revisão de compliance, uma ordem judicial contra o provedor. A máquina está intacta e inacessível, e todo snapshot dentro daquela conta fica inacessível junto com ela. Essa é a falha que nenhuma quantidade de redundância dentro de um único provedor consegue responder, e o motivo pelo qual um backup sério vive sob um teto diferente.

Defesa Hardware Erro humano Ransomware Conta perdida
RAID / armazenamento redundanteSimNãoNãoNão
Snapshot do provedor, mesma contaSimParcialmenteNãoNão
Repositório fora do local, chave com permissão de escritaSimSimNãoSim
Repositório fora do local, somente-anexação, outra jurisdiçãoSimSimSimSim

A última linha é o que o restante deste guia constrói. Ela não é mais cara que a linha acima — a configuração de somente-anexação é gratuita e a segunda jurisdição custa o mesmo $3.90 que a primeira.

A regra 3-2-1, reformulada para um único VPS. Três cópias dos dados, em dois tipos diferentes de armazenamento, uma delas fora do local. A formulação clássica vem de uma era de fitas e servidores de escritório, e o espírito sobrevive à tradução melhor que a letra. Para uma única máquina autogerenciada, isso se traduz em: os dados em produção no VPS, um repositório numa segunda máquina em outro lugar, e — para qualquer coisa genuinamente insubstituível — uma terceira cópia que você pode segurar na mão, num disco em casa ou numa gaveta. O número que realmente importa não é três. É quantas coisas independentes precisam dar errado antes que os dados sumam. Dois é o mínimo que vale a pena ter.

Antes de começar · Escolha da ferramenta

restic, Borg, ou rsync. Dois deles são backups.

A categoria que você quer se chama ferramenta de snapshot com deduplicação e criptografia. Ela divide cada arquivo em blocos definidos pelo conteúdo, criptografa cada bloco na máquina dona dos dados e o armazena uma única vez, não importa quantos snapshots o referenciem. Isso dá três propriedades ao mesmo tempo: muitos pontos de restauração por pouco mais de espaço que um só, texto em claro que nunca sai da origem, e uma transferência que só move o que mudou.

Dois programas dominam esse espaço e ambos são excelentes. O restic é um único binário estático em Go com uma ampla gama de back-ends de armazenamento. O BorgBackup é um programa em Python que fala SSH com uma cópia de si mesmo do outro lado. Tudo abaixo é a diferença honesta entre os dois.

Propriedade restic BorgBackup rsync / rclone
Criptografia do lado do clienteSempre ativo, não é opcionalSempre ativo, não é opcionalSomente via um remote rclone crypt
DeduplicaçãoBlocos definidos por conteúdoBlocos definidos por conteúdoNenhum, ou árvores de hardlink
Histórico de snapshotsSim, com políticas de retençãoSim, com políticas de retençãoUm espelho deste exato momento
Requisitos do destinoNada — SFTP, S3, REST, rcloneBorg instalado nas duas pontasUma conta SSH ou uma API
Imposição de somente-anexaçãoVia rest-server ou object lockEmbutido, sobre SSH puroNenhum
Bom paraQuase todo mundo, na maioria dos back-endsUma máquina SSH sua, somente-anexaçãoEspelhamento, não backup

O rsync está na tabela porque é a primeira coisa que a maioria das pessoas usa, e porque é genuinamente a ferramenta errada: um espelho reproduz fielmente uma exclusão, e um espelho de um disco criptografado em repouso não está, em si, criptografado em lugar nenhum. Ele ganha seu lugar dentro de um backup como a coisa que move um arquivo já pronto, não como o arquivo em si.

Este guia mostra tanto o restic quanto o Borg para todo comando que difere, para que você possa seguir com qualquer um dos dois. Onde uma única escolha precisa ser feita — o exemplo prático, o timer, o script — ele usa o restic, porque aí o destino não precisa de nada além de uma conta SSH, o que mantém a segunda máquina simples.

Passo 01 · Inventário

O que não pode ser reconstruído. Anote antes de automatizar.

Fazer backup do sistema de arquivos inteiro é uma escolha defensável e também um desperdício. A maior parte de um servidor está a um gerenciador de pacotes de distância de ser recriada, e cada gigabyte extra que você carrega deixa o repositório mais lento para podar, mais caro para manter e mais lento para pesquisar quando você está com pressa. O exercício útil é o oposto: liste o que uma instalação nova não devolveria a você.

Para um VPS autogerenciado típico, essa lista é curta, e sempre contém estas cinco coisas:

  • 01Conteúdo do banco de dados. Não o diretório de dados — o dump. O Passo 05 explica o porquê.
  • 02Arquivos enviados pelo usuário. Volumes do Docker, um diretório de uploads ou mídia, um armazenamento de e-mail. Geralmente é a maior parte dos bytes.
  • 03Configuração e segredos. Os arquivos Compose, os arquivos .env, as chaves de criptografia, os tokens de API. Pequenos, e a diferença entre uma restauração de duas horas e uma de dois dias.
  • 04Estado do sistema que você editou. O /etc inteiro é pequeno o suficiente para levar por completo — configuração do sshd, regras de firewall, units do systemd, entradas de cron, o roteamento de e-mail no qual você passou uma noite.
  • 05Qualquer coisa com uma identidade vinculada. Uma chave de serviço oculto do Tor, uma chave de assinatura do Matrix, uma chave privada do WireGuard, a carteira de um node. Perca uma dessas e o serviço não volta — um serviço diferente com o mesmo nome volta no lugar.

Transforme a lista em dois arquivos no servidor de origem. Uma lista de inclusão mantém a intenção visível; uma lista de exclusão mantém o ruído de fora. As duas são lidas pelo comando de backup, e as duas devem fazer parte do próprio backup.

/etc/backup/include.txt

/etc
/opt
/root
/var/backups
/var/lib/docker/volumes
/home

/etc/backup/exclude.txt

# Caches and rebuildable artefacts
**/node_modules
**/.cache
**/*.tmp
/var/lib/docker/volumes/*/_data/cache
# Log noise — keep the config, drop the volume
/var/log/journal
# Never back up the mount point you restore into
/mnt/restore

Duas notas sobre essa linha do Docker, porque ela costuma pegar as pessoas de surpresa. Os named volumes ficam em /var/lib/docker/volumes e são o que você quer; os bind mounts ficam onde você os colocar, geralmente ao lado do arquivo Compose, e são cobertos por /opt. Imagens de contêiner não são dados — elas voltam com um pull, e um backup que as carrega está carregando gigabytes que não precisa.

Por fim, meça o resultado antes de construir qualquer coisa em torno dele. O número diz qual nível de repositório pedir e se a primeira execução vai levar quatro minutos ou quarenta:

du -sh --exclude=/var/lib/docker/overlay2 /etc /opt /root /home /var/lib/docker/volumes
Passo 02 · Instalar

Um único binário na origem. Nada mais muda.

Instale a ferramenta na máquina dona dos dados. No Debian e no Ubuntu as duas estão empacotadas, e para o restic o pacote da distribuição costuma estar uma ou duas versões atrasado — o que importa, porque recursos de repositório e melhorias de desempenho chegam nas versões pontuais. Instale o pacote, e deixe o restic se atualizar sozinho:

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

Para o Borg, o pacote da distribuição é a escolha certa, porque a versão na origem e a versão no destino precisam se entender, e um par correspondente do mesmo lançamento da distribuição é o jeito menos doloroso de conseguir isso:

apt install -y borgbackup
borg --version

Uma palavra sobre versões principais antes de você confiar anos de histórico a um repositório: o formato de repositório do Borg mudou entre suas linhas principais, e mover um repositório através dessa fronteira é uma conversão, não uma atualização. Leia as notas de versão daquela que você está instalando, e mantenha o destino na mesma linha principal que a origem. O restic tem sido compatível com versões futuras ao longo de seus lançamentos e adiciona recursos atrás de uma versão explícita de repositório, então a preocupação equivalente ali é menor.

Nenhuma das duas ferramentas precisa de um daemon, um agente ou uma porta aberta na origem. Vale dizer isso em voz alta: o sistema de backup que você está instalando não adiciona nenhum serviço escutando nem nenhuma nova superfície de ataque à máquina que ele protege. Tudo o que ele faz é de saída, numa agenda, via SSH.

Passo 03 · Destino

Um segundo bastião, e uma chave que não consegue apagar. Esse é o passo que importa.

O host do repositório tem um único trabalho e quase nenhum requisito. Ele não precisa de núcleos de CPU, porque nunca lê seus dados — ele guarda blobs criptografados que não consegue abrir. Não precisa de memória, porque o trabalho de deduplicação acontece na origem. Ele precisa de disco, um endereço estável, e de estar em algum lugar onde os problemas da máquina de origem não o alcancem.

No painel: Pedido → VPS → Sentinel, imagem Debian 12, e — o ponto principal — um bastião diferente daquele em que a origem roda. Helsinki em produção, Reykjavík guardando. Nenhum e-mail é exigido para abrir a conta, e a fatura é quitada em Monero, Bitcoin, Lightning ou qualquer um dos outros ativos suportados, o que significa que a segunda máquina não reintroduz a identidade que a primeira tomou cuidado para evitar.

Destino do repositório Mensal Armazenamento Conjunto de trabalho que guarda Custo para restaurar
Sentinel$3.90120 GB NVMe~30 GBNada — sem medição
Garrison$7.90240 GB NVMe~70 GBNada — sem medição
Ravelin$16.90480 GB NVMe~150 GBNada — sem medição
Bulwark$32.90960 GB NVMe~300 GBNada — sem medição
Armazenamento de objetos classe S3~$0.023/GBElásticoQualquer umSaída medida

A coluna do conjunto de trabalho assume snapshots diários mantidos por um ano com uma taxa de mudança normal; um repositório que guarda principalmente arquivos que mudam pouco vai muito mais longe, um cheio de binários grandes reescritos vai menos longe. A última linha está ali pela escala, e pelo detalhe que as pessoas esquecem até o dia ruim: o armazenamento de objetos também cobra pelo download, e o download é o que você faz numa emergência.

No destino — um usuário sem privilégios e um diretório.

adduser --disabled-password --gecos "" backup
install -d -m 0700 -o backup -g backup /srv/restic/web01

O usuário de backup não tem senha, não tem sudo e não tem nada para acessar. Ele existe para ser dono de um diretório. Dê a ele seu próprio diretório por máquina de origem se você fizer backup de várias — um repositório por origem impede que o comprometimento de uma máquina afete o histórico de outra.

Na origem — uma chave que não é usada para mais nada.

ssh-keygen -t ed25519 -f /root/.ssh/id_backup -N "" -C "backup:web01"
cat /root/.ssh/id_backup.pub

Não reutilize sua chave de login. Essa aqui vive sem criptografia no disco porque um timer não supervisionado precisa usá-la às três da manhã, que é exatamente o tipo de chave que você quer restrita a um único destino e um único propósito.

De volta ao destino — restrinja o que essa chave pode fazer. Cole a chave pública em /home/backup/.ssh/authorized_keys com um prefixo na frente dela. Para restic via SFTP:

restrict,from="198.51.100.7" ssh-ed25519 AAAAC3NzaC1lZDI1... backup:web01

A opção restrict desliga o encaminhamento de portas, o encaminhamento do agente, X11 e a alocação de PTY numa palavra só, deixando apenas a transferência de arquivos e nada mais. A cláusula from= prende a chave ao endereço de origem, então uma cópia dela roubada do servidor é inútil em qualquer outro lugar. Para o Borg, vá um passo além e force o comando, que é onde vive o modo de somente-anexação dele:

command="borg serve --append-only --restrict-to-path /srv/borg/web01",restrict ssh-ed25519 AAAAC3NzaC1lZDI1... borg:web01

Essa linha é toda a defesa contra ransomware em um só lugar: seja lá o que a origem enviar, o destino só vai executar borg serve, apenas dentro daquele caminho, e apenas em um modo que só anexa. Um shell root na origem não consegue usar essa chave para apagar o mês passado.

Nomeie o destino uma vez, na origem. Coloque isso em /root/.ssh/config para que todo comando posterior seja curto e o endereço viva em exatamente um arquivo:

Host rkv-repo
    HostName 198.51.100.42
    User backup
    IdentityFile /root/.ssh/id_backup
    IdentitiesOnly yes

Depois conecte uma vez manualmente — ssh rkv-repo — para aceitar a chave do host. Um timer não supervisionado não vai responder a um prompt de fingerprint, e um primeiro backup que trava silenciosamente por uma semana é um clássico. Enquanto você estiver no destino, dê a ele o mesmo tratamento de qualquer outra máquina sua: rode também o checklist de hardenização da primeira hora nele. Ele guarda uma cópia de tudo, e merece a hora inteira.

Passo 04 · Inicializar

A frase-senha, depois o primeiro snapshot. Nessa ordem, e fora da máquina.

Gere uma frase-senha que você nunca vai digitar. Ela é lida de um arquivo por um script, então o comprimento não custa nada e não há motivo para torná-la memorizável:

openssl rand -base64 32 > /root/.restic-pass
chmod 600 /root/.restic-pass
cat /root/.restic-pass

Agora pare e copie essa string para algum lugar que não seja este servidor. Um gerenciador de senhas, uma anotação em papel numa gaveta, uma segunda máquina — qualquer lugar que sobreviva à perda da origem. Essa é a mesma falha que destrói cofres de senhas e motores de automação autogerenciados: a chave que descriptografa tudo fica guardada ao lado de tudo, e as duas coisas se perdem juntas. Um repositório cuja frase-senha só existia na máquina que ele protegia não é um backup; é uma pilha de ruído muito bem organizada.

Escreva o arquivo de ambiente que todo comando posterior vai ler:

/etc/backup/restic.env

RESTIC_REPOSITORY=sftp:rkv-repo:/srv/restic/web01
RESTIC_PASSWORD_FILE=/root/.restic-pass
chmod 600 /etc/backup/restic.env
set -a; . /etc/backup/restic.env; set +a
restic init

O par equivalente para o Borg — o modo repokey guarda a chave de criptografia dentro do repositório, protegida pela frase-senha, o que é conveniente e é exatamente por isso que você também exporta uma cópia dela:

export BORG_REPO=ssh://borg@rkv-repo/srv/borg/web01
export BORG_PASSCOMMAND="cat /root/.restic-pass"
borg init --encryption=repokey-blake2
borg key export ::  /root/borg-key.txt   # copy this off the server too

O primeiro snapshot. Rode na mão, observe, e deixe terminar antes de automatizar qualquer coisa. Essa é a execução lenta — cada bloco é novo — e é ela que diz se a lista de inclusão estava certa:

restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system --verbose

Se a origem estiver servindo tráfego e o upload estiver saturando o link, limite-o. O parâmetro recebe kibibytes por segundo, então 20000 é aproximadamente 20 MB/s:

restic backup --limit-upload 20000 --files-from /etc/backup/include.txt

Quando terminar, veja o que você realmente obteve. Esses três comandos são os que você deve rodar agora, e de novo daqui a seis meses, quando já tiver parado de pensar em qualquer coisa disso:

restic snapshots                    # the list, with dates and tags
restic stats latest                 # what the newest snapshot contains
restic ls latest /etc/backup        # confirm a path you expected is in there

Aquele terceiro comando merece um momento de atenção. Metade de todos os backups quebrados não estão quebrados de jeito nenhum — são repositórios completos e saudáveis do diretório errado. Listar um caminho que você esperava encontrar, logo no primeiro snapshot, pega esse erro enquanto o arquivo de inclusão ainda está fresco na sua memória.

Passo 05 · Automatizar

Primeiro o dump, depois o snapshot. Um script, um timer, uma política de retenção.

A regra do banco de dados, dita uma vez. Um banco de dados em execução mantém estado na memória e o grava em disco no seu próprio ritmo. Leia os arquivos dele enquanto isso acontece e você obtém um conjunto de páginas de vários momentos diferentes — um arquivo que pode restaurar, pode restaurar corrompido, ou pode restaurar em algo que abre normalmente e está silenciosamente sem a última hora. Não há como saber qual desses casos por fora. Por isso o backup nunca toca nos arquivos ativos: um dump é gravado em disco primeiro, e o backup pega o dump.

Tudo entra em um único script. Coloque-o em /usr/local/sbin/nb-backup.sh, torne-o executável, e mantenha-o dentro do próprio backup:

#!/bin/sh
set -eu

# ---- 1. Consistent dumps, written where the include list will find them.
install -d -m 0700 /var/backups/db

# PostgreSQL in a container:
docker exec -t app-db pg_dumpall -U postgres | gzip -9 > /var/backups/db/postgres.sql.gz

# MariaDB / MySQL, InnoDB tables:
# docker exec -t mail-db mariadb-dump --single-transaction --all-databases \
#   | gzip -9 > /var/backups/db/mariadb.sql.gz

# SQLite — never a plain file copy:
# sqlite3 /opt/app/data/app.db ".backup '/var/backups/db/app.db'"

# ---- 2. The snapshot.
restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system

# ---- 3. Retention, then reclaim the space it freed.
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

# ---- 4. Structural check every night; read 5% of the data on Sundays.
restic check
[ "$(date +%u)" = "7" ] && restic check --read-data-subset=5%

echo "backup ok: $(date -u +%FT%TZ)"

Três detalhes nesse script fazem mais trabalho do que parece. O set -eu no topo significa que um dump com falha aborta a execução em vez de silenciosamente colocar em snapshot o dump de ontem pelos próximos seis meses. O forget e o prune são um único comando, porque uma política de retenção que nunca libera espaço é um disco que enche. E a verificação de domingo lê uma fatia dos dados reais em vez de só o índice — corrupção de repositório é rara, e silenciosa, e a única coisa que a encontra é a leitura.

O timer. Dois pequenos arquivos unit. O systemd é o agendador certo aqui, em vez do cron, porque um timer te dá o Persistent — uma execução perdida enquanto a máquina estava desligada acontece no próximo boot em vez de ser pulada em silêncio — e porque o journalctl guarda o histórico de cada execução.

/etc/systemd/system/nb-backup.service

[Unit]
Description=Nightly encrypted offsite backup
Wants=network-online.target
After=network-online.target docker.service

[Service]
Type=oneshot
EnvironmentFile=/etc/backup/restic.env
ExecStart=/usr/local/sbin/nb-backup.sh
Nice=10
IOSchedulingClass=idle

/etc/systemd/system/nb-backup.timer

[Unit]
Description=Nightly encrypted offsite backup

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=45m
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now nb-backup.timer
systemctl list-timers nb-backup.timer
systemctl start nb-backup.service && journalctl -u nb-backup.service -n 40 --no-pager

O atraso aleatório não é decoração. Todo servidor autogerenciado na internet roda sua manutenção exatamente às 03:00, e um backup que começa no mesmo segundo que a rotação de logs, a renovação de certificado e a atualização de contêiner passa a noite brigando com eles por I/O. Espalhar o início ao longo de 45 minutos não custa nada e elimina toda uma categoria de noites lentas misteriosas.

Depois, faça a falha ser barulhenta. Esta é a etapa que todo mundo pula, e é a que decide se tudo o que foi feito acima valeu a pena. Um backup que para de funcionar não avisa nada: o timer continua disparando, o serviço continua falhando, e o último snapshot bom vai ficando cada vez mais no passado enquanto o painel continua verde. Adicione uma unit OnFailure= ao serviço que te envie algo que você realmente vai ver, e uma vez por mês dê uma olhada no topo da lista de snapshots. Uma linha, um hábito.

restic snapshots --latest 3        # is the newest one from last night?
systemctl list-timers nb-backup.timer   # is the timer still armed?
Passo 06 · Simulação

Restaure agora, enquanto nada está pegando fogo. Um backup não testado é um boato.

Existem duas simulações, e elas respondem perguntas diferentes. A pequena pergunta "os dados realmente estão aí e são legíveis?" e leva 90 segundos. A grande pergunta "quanto tempo realmente levaria para colocar o serviço de volta no ar?" e leva uma tarde, uma vez por ano. Faça a pequena mensalmente. Faça a grande pelo menos uma vez, porque a resposta nunca é o que as pessoas imaginam.

A pequena simulação. Copie um diretório e um dump para um caminho temporário, depois compare com o que está em produção:

install -d -m 0700 /mnt/restore
restic restore latest --target /mnt/restore --include /etc/backup
restic restore latest --target /mnt/restore --include /var/backups/db

diff -r /etc/backup /mnt/restore/etc/backup && echo "config identical"
gzip -t /mnt/restore/var/backups/db/postgres.sql.gz && echo "dump readable"

Melhor ainda, quando a ferramenta oferece isso: monte o repositório como somente leitura e percorra-o como um sistema de arquivos. Cada snapshot aparece como um diretório datado, e você pode navegar pelo histórico com ls e cat em vez de restaurar qualquer coisa. Isso precisa de FUSE na máquina que faz a montagem:

restic mount /mnt/snapshots      # then: ls /mnt/snapshots/snapshots/latest/
borg mount ::  /mnt/snapshots     # the Borg equivalent

A grande simulação. Contrate um VPS descartável cobrado por hora, e reconstrua o serviço nele a partir apenas do repositório — sem anotações de memória, sem arquivos copiados da máquina em produção. Trabalhe a partir de um runbook escrito e corrija o runbook à medida que avança, porque as lacunas que você encontra são o objetivo inteiro do exercício. As descobertas mais comuns, em ordem de frequência: a frase-senha só estava na máquina morta; os registros de DNS nunca foram anotados; um diretório com bind mount ficava fora de todo caminho de inclusão; a restauração precisava de uma versão de pacote que não é mais a padrão; ninguém sabia qual contêiner precisava iniciar primeiro.

Cronometre. Anote o número no topo do runbook com a data. Esse número — não o tamanho do repositório, não o número de snapshots — é a única medida honesta de quão protegido o serviço realmente está.

E leia os dados de vez em quando. A verificação noturna checa a estrutura: que o índice bate consigo mesmo e nenhum blob está faltando. Ela não lê os blobs. Uma vez por mês, ou na execução de domingo, leia uma fatia deles — um rodízio de cinco por cento cobre todo o repositório ao longo de alguns meses sem nunca custar uma noite longa:

restic check --read-data-subset=5%
borg check --verify-data              # the Borg equivalent, slower and thorough
A parte difícil · Somente anexação

Uma chave que pode escrever, e não consegue apagar. A diferença entre uma semana ruim e um negócio fechado.

Tudo até aqui protege contra acidentes. Este capítulo protege contra um adversário, e o problema de design é desconfortável assim que você o percebe: a máquina de origem precisa alcançar o repositório toda noite, o que significa que a máquina de origem guarda uma credencial funcional para o repositório. Quem quer que possua a origem possui essa credencial. Se a credencial pode apagar, o atacante apaga — e o ransomware moderno faz exatamente isso, de propósito, antes de criptografar qualquer coisa, porque uma vítima capaz de restaurar não paga.

A solução não é uma senha melhor. É uma permissão assimétrica: a origem pode adicionar dados e não pode remover nenhum. Três formas de construir isso, em ordem decrescente de facilidade para acertar.

Um — anexação forçada apenas via SSH. Esse é o terreno natural do Borg, e é a resposta mais limpa disponível numa máquina que você possui. A entrada em authorized_keys do passo 03 força borg serve --append-only, então o lado remoto recusa exclusões, não importa o que o lado próximo peça. A poda ainda precisa acontecer, mas acontece do lado do destino, numa agenda que a origem não consegue influenciar, executada por uma conta que a origem não consegue alcançar. Um atacante com root na origem pode encher o repositório de lixo; ele não consegue remover o arquivo da noite anterior à sua chegada.

Dois — um endpoint REST somente-anexação. O rest-server, companheiro do restic, tem um modo --append-only com a mesma propriedade: novos blobs são aceitos, os existentes não podem ser removidos. Rode-o no destino atrás de TLS, aponte o RESTIC_REPOSITORY para a URL https:// em vez da sftp:, e o formato da defesa é idêntico. Custa mais um serviço no destino e compra a mesma garantia.

Três — object lock. Em armazenamento compatível com S3, versionamento mais um período de retenção com object lock torna a exclusão impossível até o período expirar, imposto pela camada de armazenamento em vez de por um programa. É a mais forte das três e a mais cara, e ela introduz uma conta de provedor — o que traz de volta o risco custodial que este guia inteiro está tentando diluir. Sensata como uma terceira cópia, incômoda como a única.

Se nenhuma dessas opções servir — SFTP puro, uma chave que pode escrever e portanto apagar — não finja o contrário; adicione uma segunda cópia independente que a origem não consiga tocar de jeito nenhum. Pull em vez de push: deixe o destino fazer login na origem, ler o que precisa, e armazenar. As credenciais então vivem na máquina que não está exposta, e um atacante na origem não encontra nada apontando para o backup. Dá um pouco mais de trabalho para configurar, e inverte o risco exatamente na direção certa.

Qualquer que seja sua escolha, verifique-a da mesma forma que verificaria qualquer outro controle de segurança — tentando quebrá-la. A partir da origem, com a chave de backup, tente apagar algo. O resultado correto é uma recusa.

borg delete ::name-of-an-old-archive
# → Remote: Repository is in append-only mode. Refusing to delete.
Notas de campo · Por serviço

O único arquivo sem o qual cada serviço não consegue voltar. Raramente é o grande.

Todo serviço tem um pequeno pedaço de estado que não é dado e não é configuração, e perdê-lo não danifica o serviço — ele o substitui por um serviço diferente que por acaso tem o mesmo nome. Links antigos quebram, pares federados recusam a nova identidade, clientes reemitem chaves. Essas são as peças, por stack, para as coisas que este site tem guias.

A camada abaixo do armazenamento

Distância é uma resposta técnica. Jurisdição é a outra metade.

Pergunte à maioria das pessoas por que o backup deveria estar em outro lugar e a resposta é incêndio, enchente, ou um datacenter perdendo energia. Tudo verdadeiro, tudo cada vez mais raro, e tudo resolvido por cem quilômetros de distância. As falhas que realmente derrubam negócios em 2026 são administrativas, e a distância sozinha não resolve nada disso.

Uma única conta é um único ponto de falha. Uma suspensão por um sinal automático de fraude, um chargeback enquanto você estava num avião, uma revisão de compliance, uma notificação de remoção endereçada à empresa em vez de a uma máquina — cada um desses casos atinge todo servidor daquela conta no mesmo instante, inclusive o que guarda os snapshots. A redundância técnica era perfeita e irrelevante. Dois provedores, ou no mínimo duas contas sob dois tetos jurídicos diferentes, é a única estrutura que responde a isso.

Uma única jurisdição é um único quadro legal. Os quatro bastiões nórdicos não são intercambiáveis — Suécia, Finlândia, Noruega e Islândia protegem cada uma algo ligeiramente diferente, e Noruega e Islândia ficam totalmente fora da União Europeia. Dividir uma máquina em produção e seu repositório entre duas delas significa que a cópia não está apenas em outro lugar; ela está sob um segundo conjunto independente de regras. A referência de jurisdições nórdicas percorre as leis uma a uma.

E o destino não aprende nada. É isso que torna a divisão barata em vez de uma troca de compensações. Tanto o restic quanto o Borg criptografam antes de qualquer coisa sair da origem, então o host do repositório armazena blobs para os quais não tem a chave. Ele não sabe quais arquivos guarda, nem quantos, nem como se chamam. Você não está estendendo confiança a um terceiro; está alugando um disco que não consegue ler a si mesmo. Essa também é a resposta honesta para "devo usar um provedor em que não confio totalmente como destino de backup?" — para um repositório criptografado, a confiança quase não entra na equação.

A latência não é um fator. De Helsinki a Reykjavík são 30 ms no backbone, de Helsinki a Stockholm 8 ms, de Stockholm a Oslo 11 ms. Um backup noturno não se importa com nenhum desses números, e uma restauração limitada pela vazão do disco também não. Escolha o par pela distância legal, não pela distância de rede — a distância de rede dentro dos países nórdicos é um erro de arredondamento.

Mais uma coisa que vale dizer claramente, porque é o motivo pelo qual este guia está neste site e não num blog genérico de sysadmin: a segunda máquina reabre toda pergunta que a primeira já havia respondido. Se o VPS em produção foi pedido sem documento de identidade e pago em Monero, e depois a máquina de backup dele é pedida com cartão de empresa e digitalização de passaporte, o par fica exatamente tão identificável quanto a metade mais fraca. O guia pilar sobre hospedagem VPS anônima percorre as três camadas — cadastro, pagamento, rede — e elas se aplicam a um destino de backup tão literalmente quanto a um servidor web.

Notas de campo · Seis armadilhas

Seis formas de um backup não ser um backup de verdade. Todas descobertas no dia ruim.

Armadilha 01 · Irreversível

A frase-senha só estava na máquina morta

O repositório está intacto, criptografado e permanentemente ilegível. Guarde a frase-senha — e, para o Borg, a chave exportada — em um gerenciador de senhas e no papel, antes do primeiro snapshot.

Armadilha 02 · Consistência

O banco de dados restaura, e então falha na primeira consulta

Os arquivos de dados ativos foram copiados em vez de despejados num dump. Escreva um dump numa etapa anterior ao backup e faça backup do dump; nunca aponte a lista de inclusão para o diretório de dados de um engine em execução.

Armadilha 03 · Raio de impacto

O invasor apagou os backups primeiro

Uma credencial com permissão de escrita numa máquina comprometida é uma credencial com permissão de escrita para o atacante. Force somente-anexação no destino, ou faça a segunda cópia por pull em vez de push.

Armadilha 04 · Capacidade

O repositório é maior que o servidor

forget sem prune apenas marca os snapshots e não libera nada. Rode os dois juntos, mantenha espaço livre no destino, e nunca faça backup de imagens de contêiner ou de node_modules.

Armadilha 05 · Silêncio

O último snapshot bom tem cinco meses

O timer falhou depois de uma atualização e nada avisou. Adicione uma unit OnFailure=, e confira o topo da lista de snapshots uma vez por mês — leva dez segundos.

Armadilha 06 · Escopo

Tudo foi restaurado, exceto um diretório

Um bind mount fora de /opt, um volume movido durante uma migração, um padrão de exclusão que casou com mais do que devia. Liste um caminho conhecido em cada novo snapshot, e releia o arquivo de inclusão depois de qualquer mudança na stack.

FAQ · Backup de VPS

Perguntas, respondidas.

Dez perguntas que surgem durante a configuração — e duas que só aparecem depois, uma única vez.

Um snapshot do provedor de VPS é um backup de verdade?

Não — é um rollback, e um útil, mas ele falha exatamente nos momentos para os quais um backup existe. Um snapshot vive dentro da mesma conta de provedor que o servidor que ele copia. Se a conta é suspensa, se um pagamento é contestado, se um atendente de suporte erra o dedo numa exclusão, ou se um atacante consegue suas credenciais do painel, o snapshot vai junto com a máquina. Ele também não dá nada granular: você não consegue puxar um único arquivo apagado de ontem, só voltar o disco inteiro e perder tudo desde então. Mantenha os snapshots — eles são o jeito mais rápido de desfazer uma atualização ruim — mas não os confunda com uma cópia que existe em algum lugar que o problema original não alcança. A regra prática: se uma credencial comprometida pode destruir as duas cópias, você tem uma cópia só.

restic ou Borg: qual devo realmente usar no backup do meu VPS?

Os dois criptografam no cliente, os dois deduplicam em nível de bloco, os dois são maduros, e os dois vão fazer o trabalho. Escolha o restic se você quer um único binário estático, um repositório que pode viver em SFTP, armazenamento de objetos compatível com S3, um servidor REST ou qualquer coisa que o rclone alcance, e absolutamente nada instalado no destino. Escolha o Borg se o destino é uma máquina SSH que você controla, você quer a imposição de somente-anexação mais forte disponível sem armazenamento com object lock, e você gosta da compressão um pouco mais apertada dele. As diferenças práticas que decidem isso: o Borg precisa do borg instalado nas duas pontas e só fala SSH ou um caminho local; o restic precisa de uma passagem de poda que trava o repositório com exclusividade por um instante. Se você não conseguir decidir, use o restic — menos peças móveis no destino vale mais que qualquer benchmark.

De quanto espaço em disco a máquina de backup precisa?

Comece pelo tamanho do que você realmente está fazendo backup — não pelo tamanho do disco em que está. Uma stack autogerenciada típica é alguns gigabytes de banco de dados e configuração, mais o que os usuários enviaram. Deduplicação e compressão então mostram seu valor: um snapshot diário de um conjunto de trabalho de 20 GB com uma política de retenção de doze meses geralmente fica entre 40 e 80 GB de repositório, porque só os blocos alterados chegam a ser armazenados duas vezes. Um Sentinel ($3.90/mês, 120 GB NVMe) cobre isso com folga. Passe para um Garrison (240 GB, $7.90) quando vários servidores fizerem backup no mesmo host de repositório, e para um Bulwark (960 GB, $32.90) quando o próprio conjunto de trabalho chegar a centenas de gigabytes. Dimensione para o repositório, depois dobre — um repositório sem espaço livre não consegue podar, e um repositório que não consegue podar só cresce.

Posso fazer backup de um banco de dados em execução apenas copiando os arquivos dele?

Você pode copiá-los. Pode não conseguir restaurá-los. Um banco de dados escrevendo em disco enquanto você o lê entrega um conjunto de arquivos de vários instantes diferentes, que é a definição de um backup rasgado — ele restaura como um banco de dados corrompido, ou pior, como um banco de dados que abre normalmente e está silenciosamente sem algumas linhas. A solução é um dump: pg_dump ou pg_dumpall para PostgreSQL, mariadb-dump --single-transaction para MariaDB e MySQL em tabelas InnoDB, e sqlite3 db .backup out.db ou VACUUM INTO para SQLite. Escreva o dump num arquivo, e então faça backup do arquivo. Se o banco de dados for grande demais para dump todas as noites, as alternativas são um snapshot do sistema de arquivos feito enquanto o engine é brevemente pausado, ou a própria ferramenta de backup físico do engine — mas para o que um único VPS roda, um dump é a escolha certa e é simples.

O que acontece se eu perder a frase-senha do repositório de backup?

Os backups se foram. Tanto o restic quanto o Borg criptografam do lado do cliente, e nenhum dos dois tem um caminho de recuperação, uma chave mestra ou um chamado de suporte que desbloqueie um repositório para você. Esse é o ponto: o host de destino — inclusive um host que não é seu — nunca vê seu texto em claro. Isso também significa que a frase-senha agora é um dado que vale exatamente tanto quanto tudo o que ela protege, e ela não pode viver só na máquina que está sendo copiada em backup. Guarde-a no seu gerenciador de senhas, e guarde uma cópia em algo físico. Para o Borg, também exporte a chave do repositório com borg key export e armazene isso junto; no modo repokey a chave vive dentro do repositório, então um repositório que você não consegue mais alcançar leva a chave junto.

Como impedir que um servidor comprometido apague os próprios backups?

Você dá a ela uma credencial que pode adicionar, mas não remover. Essa é a decisão de design mais importante de todo o exercício, porque o ransomware moderno procura primeiro a configuração de backup e a segue até a origem. Três formas de conseguir isso. Somente-anexação via SSH: no authorized_keys do destino, force o comando borg serve --append-only --restrict-to-path /srv/borg — a origem pode gravar novos arquivos e não pode apagar os antigos. Somente-anexação via REST: rode o rest-server do restic com --append-only e aponte o repositório para ele via HTTPS. Object lock: um bucket compatível com S3 com versionamento e um bloqueio de retenção. SFTP puro não te dá nada disso — uma chave que pode escrever num repositório pode apagá-lo — então, se o SFTP for seu transporte, combine-o com uma segunda cópia do tipo pull feita do lado do destino, onde as credenciais que um atacante capturou na origem não alcançam.

Com que frequência o backup deve rodar, e por quanto tempo devo guardar os snapshots?

Pergunte ao contrário: quanto trabalho você está disposto a refazer? Esse número é o seu objetivo de ponto de recuperação, e ele define o intervalo. Diário é certo para quase todo serviço autogerenciado — um servidor de e-mail, um Nextcloud, um homeserver Matrix, um motor de workflow. De hora em hora vale a pena quando os dados são transacionais e reentrada é impossível. Para a retenção, o padrão que sobrevive ao contato com a realidade é --keep-daily 7 --keep-weekly 4 --keep-monthly 12: uma semana de desfazer granular, um mês de pontos de verificação semanais, um ano de mensais, para cerca de 23 snapshots. A cauda longa importa mais do que as pessoas esperam, porque a falha que ela pega não é um disco morto — é uma corrupção ou uma exclusão que ninguém percebeu por seis semanas.

A segunda cópia do backup realmente precisa estar em outro país?

Um prédio diferente é o mínimo técnico; uma jurisdição diferente é a parte que a maioria pula e depois lamenta. Um incêndio, uma enchente ou uma falha em nível de rack são resolvidos só pela distância. O que a distância não resolve é o lado legal ou comercial: uma conta suspensa por um provedor, uma disputa de pagamento, uma notificação de remoção que atinge toda máquina sob o mesmo teto corporativo, uma ordem judicial contra uma empresa. Se as duas cópias vivem com o mesmo provedor, uma única carta atinge as duas. Dividir o par entre dois bastiões nórdicos — a máquina em produção em Helsinki, o repositório em Reykjavík, 30 ms de distância no backbone — não custa nada em latência e compra um segundo quadro legal. Os dados são criptografados antes de sair da origem de qualquer forma, então o destino não aprende nada ao guardá-los.

Quanto tempo leva o primeiro backup, e a criptografia deixa isso mais lento?

Criptografia não é o gargalo — CPUs modernas fazem AES mais rápido do que um link gigabit consegue carregar o resultado, e as duas ferramentas usam aceleração por hardware onde ela existe. O gargalo é o primeiro upload, porque tudo é novo: num uplink de 1 Gbps, um conjunto de trabalho de 20 GB leva alguns minutos na velocidade máxima, e bem mais tempo se o destino estiver limitado ou os arquivos forem muitos e pequenos. Toda execução seguinte transfere só os blocos que mudaram, o que para uma stack típica são dezenas de megabytes e termina em menos de um minuto. Se a primeira execução competir com uma carga de produção, limite a taxa — o restic aceita --limit-upload em KiB/s, o Borg aceita --upload-ratelimit — e rode sob nice e ionice.

Preciso mesmo testar as restaurações do backup?

Sim, e o motivo não é paranoia — é que as falhas mais comuns são silenciosas. O timer que parou de disparar depois de uma atualização de pacote. O padrão de exclusão que silenciosamente engoliu o diretório de uploads. O dump do banco de dados escrito num caminho que o backup nunca cobriu. O repositório que vem falhando na verificação de integridade há semanas, num log que ninguém lê. Nenhum desses avisa sozinho; todos são encontrados em 90 segundos ao restaurar um arquivo e olhar para ele. Faça uma pequena restauração mensalmente — copie um dump de banco de dados e um diretório de dados para um caminho temporário e compare — e uma reconstrução completa uma vez por ano, num VPS novo, cronometrada. O número que sai dessa reconstrução é o seu tempo de recuperação real, e raramente é o número que você imaginaria.

Consiga a segunda máquina

Um bastião de repositório numa segunda jurisdição nórdica. Sem KYC, pago em cripto.

Sentinel — 120 GB de NVMe por $3.90 por mês, em Helsinki, Stockholm, Oslo ou Reykjavík. Banda ilimitada, então restaurar não custa nada. Sem e-mail no cadastro, sem documento de identidade, e um destino que não consegue ler um único byte do que guarda.

Última revisão · 2026-08-24 · Fontes · Documentação do restic e do BorgBackup, manuais de backup do PostgreSQL e do MariaDB, sshd authorized_keys(5), systemd.timer(5) · Cadência · anualmente