Discuta este tópico no fórum

Se este conteúdo te ajudou, deixe um presente!

quarta-feira, 11 de abril de 2018

OpenWrt/LEDE: fazendo seus backups no roteador (e distribuindo-os): parte 3

Mais um artigo da série sobre o OpenWrt/LEDE. 

No primeiro artigo deste tema, comentei o que uma solução de backup deveria ter. Passei pela solução que usava anteriormente (crashplan) e uma brevíssima introdução aos recursos do borg. Depois apresentei a configuração do backup em um HD externo no seu roteador. Neste artigo, iremos implementar a sincronia entre repositórios.

Só relembrando, esse é o esquema do backup:


O computador roda o borg e copia os arquivos (amarelo) para um repositório no roteador. Esse repositório é acessado por CIFS e aponta para um HD externo conectado na USB. Em um segundo momento, um rsync sincroniza esse repositório com um destino remoto utilizando o rsync. O destino remoto também é um roteador com um HD externo conectado, mas poderia ser qualquer destino com suporte a rsync. A comunicação do rsync é feita dentro de uma VPN, que interliga o roteador de origem e destino do repositório.

Este artigo aborda a parte verde do diagrama.

Sincronizando repositórios


Já ouvi a estória do "eu tinha backup, mas perdi junto". Incêndio, roubo, descarga elétrica durante o backup, não são se preocupar em "não queimar" o HD externo do seu backup. E o backup parece ter um certo magnetismo que o atrai para próximo da fonte original da informação, em especial antes de eventos catastróficos.

Como já havia comentado na parte 1 deste assunto, distribuir geograficamente o backup de forma automatizada era um requisito. A opção foi utilizando o rsync sobre uma VPN, onde o repositório do backup, conectado no roteador (que sempre está ligado), é enviado lentamente para um outro armazenamento remoto, também conectado em outro roteador (que sempre está ligado).

A parte da VPN é assunto antigo. O rsync pode ser feito pelo SSH, com autenticação por chaves. Porém, isso exige um certo grau de confiança da ponta remota pois as mesmas chaves podem abrir uma sessão no roteador remoto. Outra opção é um serviço rsyncd. Apesar de não ter autenticação, você pode controlar pelo firewall e pela restrição do próprio rsyncd quem pode acessar esse serviço. Se somente o teu roteador puder conectar no roteador remoto, só você poderá apagar algo indevidamente.

No roteador que receberá a cópia:

roteador-remoto# opkg update
roteador-remoto# opkg install rsyncd

A configuração não foi UCIficada e deve ser feita diretamente em /etc/rsyncd.conf. Só adicionar:

/etc/rsyncd.conf:
(...)
[fulano@gmail.com]
path = /mnt/HD-externo-XYZ/backup/borg/fulano@gmail.com
read only = no
fake super = yes

O identificador fulano@gmail.com é arbitrário. Eu gosto de usá-lo pois o repositório normalmente terá mais de um cliente. E nada melhor do que o email para lembrar o nome do repositório. 

Agora, basta ativar e disparar o serviço:

roteador-remoto# /etc/init.d/rsyncd enable
roteador-remoto# /etc/init.d/rsyncd start

Opcionalmente, se já estiver usando o xinetd (por exemplo, para o scanner na rede - SANE), pode também usar o xinetd ao invés do serviço rsyncd:

service rsync 
{
disable = no
socket_type = stream
port = 873
protocol = tcp
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
}

E falta, agora, somente a rotina que envia do meu roteador-local para o roteador-remoto.

rsync --bwlimit=30k --partial --archive --delete --delay-updates --delete-after  /mnt/HD-externo-abc/borg/ roteador-remoto::fulano@gmail.com/

E se usar por cima do SSH:

rsync --bwlimit=30k --partial --archive --delete --delay-updates --delete-after  /mnt/HD-externo-abc/borg/ roteador-remoto:/mnt/HD-externo-XYZ/backup/borg/fulano@gmail.com/

A primeira opção --bwlimit limita a taxa de transferência para o rsync. Ajuste para sua realidade. Como eventualmente teremos múltiplos gigabytes para serem enviados, o processo pode durar dias. A recomendação é sempre deixar um tanto para outros fins. O --partial permite continuar o envio quando a conexão foi perdida. Eu gosto de usar o --delay-updates --delete-after para manter o repositório íntegro durante a cópia. Se espaço for um problema do outro lado e ele não aguentar armazenar a mais a diferença a ser enviada, pode usar o --inplace e --delete-before. E sempre, man é seu amigo.

Agora é só colocar na cron. Como o processo pode rodar "por dias", é importante que ele não volte a rodar se o rsync anterior ainda estiver em execução. Por isso, podemos melhorar o comando usando o comando "lock":

lock -n /tmp/rsync.lock && { bwlimit=30k --partial --archive --delete --delay-updates --delete-after  /mnt/HD-externo-abc/borg/ roteador-remoto::fulano@gmail.com/; lock -u /tmp/rsync.lock; }

Se rodar novamente este comando enquanto a execução anterior ainda estiver em curso, você vai receber um:

Can't lock /tmp/rsync.lock

E, como esperado, não teremos dois rsync em execução.

No OpenWrt, não temos os /etc/cron.* que usamos no Linux. Sendo assim, temos que usar o bom e velho 'crontab -e'. Para rodar todos os dias 1 AM:

0 1 * * * lock -n /tmp/rsync.lock && { bwlimit=30k --partial --archive --delete --delay-updates --delete-after  /mnt/HD-externo-abc/borg/ roteador-remoto::fulano@gmail.com/; lock -u /tmp/rsync.lock; }

Outra funcionalidade interessante é abortar o processo quando ele demorar muito tempo. Assim você pode manter a rotina apenas durante a madrugada. Todavia, isso só faz sentido se usar a opção "--partial". Bem, a partir deste ponto, a linha do comando vai ficar muito longa, mesmo por um costumas one-liner. É hora de fazer um script:

#!/bin/sh
# Sincroniza repositorio local com remoto
#
RSYNC_TIMEOUT=${1:?Informe o tempo maximo em segundos deste script}; shift
REPO_LOCAL=${1:?Informe o repositorio local}; shift
REPO_REMOTE=${1:?Informe o repositorio remoto}; shift
REPO_LOCK=/tmp/rsync-remote.lock

lock -n "$REPO_LOCK" || {
echo "Falha ao obter lock! Existe um rsync-backup rodando?" >&2
exit 1
}
trap "lock -u '$REPO_LOCK'" EXIT

rsync --archive --partial --delete --delay-updates --delete-after "$@" "$REPO_LOCAL" "$REPO_REMOTE" &
pid_rsync="$!"
(sleep $RSYNC_TIMEOUT; echo "Estouro de tempo ($RSYNC_TIMEOUT segundos)" >&2; kill -TERM $pid_rsync) &
pid_timeout="$!"
# Deveria ser kill -TERM -$pid_timeout... mas com o ash nao fuciona ainda
trap "lock -u '$REPO_LOCK'; kill -TERM $pid_timeout $pid_rsync 2>/dev/null" EXIT
wait $pid_rsync
err=$?
exit $err

Que ficaria na cron assim:

#  Roda todos os dias 1AM por 6 horas (21600 segundos)
0 1 * * * /caminho/para/rsync-backup.sh 21600 /mnt/HD-externo-abc/borg/ roteador-remoto::fulano@gmail.com/

E é isso. Agora você já tem um mecanismo de sincronia dos backups.

Recuperando dados

Primeiro, vamos imaginar o cenário onde você precisa recuperar os dados do repositório remoto. Você deve ter perdido os dados principais e também seu backup local. Nesta situação, é provável que você nem tenha mais o seu computador para recuperar os dados.

A primeira alternativa de recuperação é ir fisicamente onde o backup remoto está e copiar o repositório. O melhor seria primeiro reconstruir seu repositório local e depois recuperar o que você quiser com calma a partir dele.

Se o acesso físico for complicado, você pode simplesmente reconstruir seu repositório local fazendo um rsync inverso, como origem o repositório remoto e destino um caminho local. Vai demorar mas funciona.

Por fim, se precisar apenas de uma ou outra coisa, eu recomendaria testar a montagem remota em cima de rsync, como em fuse-rsync. Não testei mas deve funcionar perfeitamente.

Ah, e não se esqueça que você sempre precisa ter acesso a chave ou a senha usada na criação do repositório. E isso sem depender do próprio backup ;-)

Se pintar uma dúvida, tem sempre o fórum deste blog. Até a próxima.

Nenhum comentário:

Postar um comentário