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.

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.
Inventário
O que não pode ser reconstruído
Instalar
restic ou Borg
Destino
Um segundo bastião
Inicializar
Repositório + primeira execução
Automatizar
Dumps, timer, retenção
Simulação
Restaure, e cronometre
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 redundante | Sim | Não | Não | Não |
| Snapshot do provedor, mesma conta | Sim | Parcialmente | Não | Não |
| Repositório fora do local, chave com permissão de escrita | Sim | Sim | Não | Sim |
| Repositório fora do local, somente-anexação, outra jurisdição | Sim | Sim | Sim | Sim |
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.
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 cliente | Sempre ativo, não é opcional | Sempre ativo, não é opcional | Somente via um remote rclone crypt |
| Deduplicação | Blocos definidos por conteúdo | Blocos definidos por conteúdo | Nenhum, ou árvores de hardlink |
| Histórico de snapshots | Sim, com políticas de retenção | Sim, com políticas de retenção | Um espelho deste exato momento |
| Requisitos do destino | Nada — SFTP, S3, REST, rclone | Borg instalado nas duas pontas | Uma conta SSH ou uma API |
| Imposição de somente-anexação | Via rest-server ou object lock | Embutido, sobre SSH puro | Nenhum |
| Bom para | Quase todo mundo, na maioria dos back-ends | Uma máquina SSH sua, somente-anexação | Espelhamento, 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.
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:
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
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.
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.90 | 120 GB NVMe | ~30 GB | Nada — sem medição |
| Garrison | $7.90 | 240 GB NVMe | ~70 GB | Nada — sem medição |
| Ravelin | $16.90 | 480 GB NVMe | ~150 GB | Nada — sem medição |
| Bulwark | $32.90 | 960 GB NVMe | ~300 GB | Nada — sem medição |
| Armazenamento de objetos classe S3 | ~$0.023/GB | Elástico | Qualquer um | Saí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.
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.
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?
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
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.
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.
O diretório de dados, config/config.php, e um dump do banco de dados. Ative o modo de manutenção para o dump, e desative depois — caso contrário o Nextcloud escreve nos dois ao mesmo tempo.
O diretório de dados inteiro: o db.sqlite3 obtido com .backup em vez de copiado, mais os arquivos rsa_key, attachments e sends.
A chave de assinatura, homeserver.yaml, o armazenamento de mídia e um dump do PostgreSQL. Perca a chave de assinatura e a identidade de federação se vai para sempre.
O próprio armazenamento de e-mails, as tabelas de usuários virtuais, e as chaves privadas DKIM — uma nova chave DKIM significa que toda mensagem fica sem assinatura até o DNS se atualizar.
Primeiro a N8N_ENCRYPTION_KEY, depois o dump do PostgreSQL. O banco de dados sem essa chave é uma lista de workflows cujas credenciais estão todas ilegíveis.
O diretório do serviço oculto. Esses poucos arquivos são o endereço .onion — sem eles o serviço volta com um nome diferente e todo link para ele fica morto.
O /etc/wireguard inteiro. Pequeno, tedioso, e a diferença entre uma reconstrução de cinco minutos e reemitir chaves para todos os seus dispositivos.
A seed e o estado dos canais, nos termos do próprio node. Restaurar dados de canal desatualizados pode custar seus fundos — siga o procedimento de backup da implementação, não uma cópia genérica de arquivos.
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.
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.
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.
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.
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.
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.
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.
Dez perguntas que surgem durante a configuração — e duas que só aparecem depois, uma única vez.
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ó.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
This guide is one spoke of a larger series. The pillar walks the three privacy layers end to end — the sibling spokes below dive into the specifics.
Three independent layers — signup, payment, network — explained, legal context included, common mistakes flagged.
SSH keys, ufw, fail2ban, kernel knobs, unattended-upgrades.
Deploy your own MCP server on a no-KYC VPS — TLS, streamable HTTP, OAuth.
Host an MCP server with no ID — the privacy stack, crypto-paid.
Tire o agente do portátil — dimensionamento, systemd, segredos, limites de gasto.