São muitos os scripts de backup existentes hoje na Internet para o fim de agilizar e automatizar esse importante e muitas vezes esquecido item de Segurança da Informação. Mas poucos se preocupam em como esses dados serão enviados, e acabam usando métodos sem proteção contra interceptação, podendo criar mais problemas do que solução. Antes de entrar em detalhes, primeiramente vamos conhecer sobre o SSH, SCP e SFTP.
O SSH como todos devem conhecer, é um conjunto de comandos que nos permite estabelecer uma conexão a uma determinada máquina distante fisicamente de forma segura, usando criptografia, evitando que os dados sejam revelados, mesmo perante uma interceptação. Os principais comandos do pacote SSH são:
- sshd: O daemon (processo em segundo plano), ou servidor SSH que permite que usuários conectem a máquina.
- ssh: O cliente usado para conectar a uma máquina rodando o daemon servidor, ou seja, o sshd.
- ssh-keygen: O gerador de chaves para estabelecer conexões com hosts confiáveis, sem a necessidade de especificar uma senha.
- scp: Comando usado pra enviar e receber arquivos de um servidor rodando o daemon sshd, é o comando “cp” mas usando criptografia.
- sftp: Assim como seu primo ftp, mas também usando criptografia e precisa de um servidor ssh habilitado para tal.
O método mais comum é usar o próprio servidor de e-mail configurado no servidor para enviar os arquivos de backup para um determinado endereço. Esse método apesar de simples, pouco se preocupa com a segurança, a não ser que você esteja se conectando a um servidor que aceite criptografia de dados durante a transmissão, mas poucos são esses. Creio que um deles é o Gmail.
Mas surge um outro problema, pois nem todo mundo tem um servidor de e-mail rodando para usar os comandos “mail” ou “mutt” para enviar a partir da própria máquina para um endereço qualquer. E mesmo que tenha, as vezes não é permitido fazer tais operações, isso normalmente ocorre quando você aluga um host e o pessoal não permite que seja enviado e-mails dessa forma, até afim de evitar o uso indiscriminado por Spammers e Phishings.
Se você percebeu as falhas e possíveis problemas que esse método, podemos então começar a listar também alguns problemas que enfrentaremos ao tentar usar SSH e SCP para realizar os nossos backup. Mas ué!? Já serão listados os problemas? Sim!
O primeiro deles é que para usar o comando SCP ou mesmo o SFTP você precisa criar um usuário válido e que tenha acesso shell ao seu Sistema, ou seja, não é algo muito interessante pra se fazer, afinal, mesmo um usuário comum pode vir a lhe causar problemas.
Outro ponto é com relação a senha, pois esses comandos só podem trabalhar se forem fornecidas as senhas de acesso para o usuário efetuar login pelo SSH, mas se o script deve funcionar de forma automatizada, não faz sentido termos que digitar a senha toda vez que o backup for efetuado.
Mas tenham calma, apesar dos problemas, essa é uma forma segura de realizar o backup e nós vamos aprender como superar todas essas dificuldades no decorrer da leitura.
Vale ressaltar que estou usando Slackware 11.0, instalação full, kernel 2.6.17.13 cujo fonte vem disponível no DVD do Slackware, ou em um dos CD’s sources.
Vamos agora configurar o nosso servidor SSH afim de obter uma melhor segurança e entender como funciona alguns dos principais parâmetros que definimos no arquivo de configuração.
Edite o arquivo /etc/ssh/sshd_config e defina o seu conteúdo conforme abaixo:
# Define a porta que será usada na conexão
Port 2222
# Altera o intervalo em segundos para gerar uma nova chave criptográfica
# afim de manter a segurança caso a chave seja revelada durante
# uma conexão ssh, e muito importante manter essa opção
KeyRegenerationInterval 1800
# Valor em bits da criptografia
ServerKeyBits 768
# Sistema de logs que são gerados
SyslogFacility AUTH
LogLevel INFO
# Usuários permitidos a usar o ssh e claro, bloqueando acesso root
AllowUsers mestre pequenogrilo
PermitRootLogin no
# Ignora conexões do tipo rhosts, afim de melhorar a segurança
RhostsRSAAuthentication no
IgnoreRhosts yes
# Exige autenticação
PasswordAuthentication yes
PermitEmptyPasswords no
# Define o sistema de ftp criptografado, sftp
Subsystem sftp /usr/libexec/sftp-server
Agora reinicie o serviço SSHD, caso não esteja iniciado, faça o seguinte:
# chmod 700 /etc/rc.d/rc.sshd
# /etc/rc.d/rc.sshd restart
Com isso iniciamos o nosso servidor SSH e vale lembrar que ele não está rodando na porta 22 e sim na 2222, afim de melhorar um pouco a segurança, e embora seja uma porta boba no exemplo, seria interessante depois alterar pra uma porta ainda mais alta.
O principal motivo para isso é evitar PostScan e levantamento de informações, pois são poucos os que se preocupam em passar scan em portas altas, e mesmo que o façam, se não pensarem direitinho, vão passar 200 dias em um PortScan inútil até chegar em uma porta qualquer sem a menor idéia do que está ou não rodando ali.
Mas ainda não terminamos, vamos criar 2 usuários para conectar ao SSH, 1 deles terá acesso shell, já o outro não, pois esse será usado apenas para gerar os nossos backup, ou você gosta de sair distribuindo acesso shell à sua máquina assim sem mais nem menos? Afinal, esse foi um dos problemas que listamos no início da leitura não foi? Vamos então começar a solucioná-lo.
Para criar os usuários, basta:
# mkdir -p /home/mestre/.ssh
# mkdir -p /home/pequenogrilo/.ssh
Com isso criamos os diretórios e já um subdiretório que no futuro vamos usar.
Agora criemos os grupos e usuários:
# groupadd mestre
# useradd mestre -s /bin/bash -d /home/mestre -g mestre
# groupadd pequenogrilo
# useradd pequenogrilo -s /bin/bash -d /home/pequenogrilo -g pequenogrilo
Damos agora as permissões corretas para cada um deles:
# chmod -R 700 /home/mestre
# chmod -R 700 /home/pequenogrilo
# chown -R mestre.mestre /home/mestre
# chown -R pequenogrilo.pequenogrilo /home/pequenogrilo
Defina uma senha para cada usuário:
# passwd mestre
# passwd pequenogrilo
Mas espera aí!? Você disse que não iria permitir acesso shell a um dos usuários, então porque você deixou o shell padrão dele como sendo “/bin/bash”?
E eu lhe digo, calma pequeno grilo, tudo a seu tempo.
Existe um shell especial que nos será muito útil, é o rssh! Com ele permitimos apenas que os usuários usem os comandos scp ou sftp, mas não tenham acesso shell diretamente pelo ssh. E se preferir, pode definir apenas que eles usem apenas o scp ou apenas o sftp.
Vale lembrar que com o rssh é permitido outros tipos de conexões como rhosts e rsync, mas não será abordado por aqui, pois não vamos utilizá-los.
Baixe o rssh no link abaixo:
Depois de fazer o download, vamos instalá-lo. Copie o arquivo para o seguinte diretório e execute os passos para instalação:
# cp rssh-2.3.2.tar.gz /usr/local/src
# cd /usr/local/src
# tar -zxvf rssh-2.3.2.tar.gz
# cd rssh-2.3.2
# ./configure
# make
# make install
Pronto! Temos agora a solução para parte dos nossos problemas, com isso não vamos mais permitir que certos usuários tenham acesso shell ao nosso sistema. Vale lembrar que o acesso shell que me refiro é o bash!
Vamos agora fazer algumas configurações e por tudo em ordem, comece logo alterando o seu shell pequeno grilo. Edite o arquivo /etc/passwd e altere a linha do seu usuário, removendo o shell de “/bin/bash” para “/usr/local/bin/rssh”, deve ficar parecido com isso:
pequenogrilo:x:1001:104::/home/pequenogrilo:/usr/local/bin/rssh
Vamos então alterar algumas configurações no arquivo “/usr/local/etc/rssh.conf”:
logfacility = LOG_USER
allowscp
umask = 022
Descomente ou adicione essas linhas, com isso iremos permitir apenas acesso ao comando scp e não permitiremos o sftp muito menos ssh.
Reinicie o daemon sshd com o seguinte comando:
# /etc/rc.d/rc.sshd restart
E faça um pequeno teste, tente conectar usando o cliente ssh ou sftp e veja o que acontece. Primeiro tente com o usuário mestre e depois com o seu usuário, o pequenogrilo. Lembre-se que alteramos a porta do daemon sshd para 2222 e levando em conta que o IP dessa máquina é 192.168.0.1, testemos:
Caso ele pergunte sobre a chave, digite “yes” e depois entre com a senha normalmente:
# ssh 192.168.0.1 -p 2222 -l mestre
Depois tente usando o sftp:
# sftp -oPort=2222 mestre@192.168.0.1
Agora com o pequenogrilo:
# ssh 192.168.0.1 -p 2222 -l pequenogrilo
E depois:
# sftp -oPort=2222 pequenogrilo@192.168.0.1
Veja os resultados, com o mestre você consegue acesso normalmente, mas com o pequenogrilo, ou a conexão falha, ou exibe uma mensagem do rssh dizendo que esse usuário não está autorizado a estabelecer esse tipo de conexão.
Com isso resolvemos o nosso problema de não permitir acesso ao shell pelo nosso usuário de backup, mas ainda nos deparamos com outro problema. Veremos…
Apesar dele ter acesso de usar apenas o comando “scp” para enviar os arquivos de backup, isso também permite que ele use tal comando pega baixar arquivos do servidor, incluindo arquivos inocentes como “/etc/passwd” e por aí vai.
Devemos criar uma jaula para esse infeliz e não permitir que ele passe dos limites que lhe são necessários para executar o backup, garantindo assim a integridade do nosso sistema.
Para tal, vamos ter que fazer algumas chatices, mas essenciais, vamos começar alterando novamente o arquivo /usr/local/etc/rssh.conf e adicionar a seguinte linha:
chrootpath=”/home/pequenogrilo”
Com isso estamos definindo um confinamento, uma jaula ao qual o usuário ficará preso. Em modos mais técnicos, pra quem já usou o comando “chroot”, tenho certeza que já sabe o que vai acontecer, nós vamos definir um “mini-sistema” ao qual o usuário irá trabalhar. Esse comando permite transformar um diretório normal em um diretório raiz “/”.
Para entender de maneira prática, comente a linha que foi adicionada agora pouco do chrootpath, reinicie o servidor sshd, e faça o seguinte:
# scp -P 2222 pequenogrilo@192.168.0.1:/etc/passwd password_do_serv
# cat password_do_serv
E você terá o “/etc/passwd” do servidor sem problemas, sabendo quais usuários ele possui, quais tem acesso root e tudo mais. Que chato não é?
Agora continuemos, descomente a linha do chrootpath do arquivo rssh.conf e deixe como descrevi agora pouco.
Depois crie um arquivo com o seguinte conteúdo e vamos executá-lo, ele é um shell script que fará uma configuração básica, copiando alguns arquivos essenciais para o diretório do pequenogrilo, para que possamos travá-lo. Dê o nome de gerar.sh:
#!/bin/bash
cd /home/pequenogrilo
mkdir -p usr/bin
cp /usr/bin/scp usr/bin
cp /usr/local/bin/rssh usr/bin
mkdir -p usr/libexec
mkdir -p usr/lib/misc
mkdir -p usr/libexec
mkdir -p usr/local/libexec
cp /usr/local/libexec/rssh_chroot_helper usr/lib/misc
cp /usr/libexec/sftp-server usr/lib/misc
cp /usr/local/libexec/rssh_chroot_helper usr/local/libexec
cp /usr/libexec/sftp-server usr/libexec
cd /home/pequenogrilo
mkdir -p lib/tls
cp /lib/libsafe.so.2 lib
cp /lib/tls/libresolv.so.2 lib/tls
cp /usr/lib/libcrypto.so.0 usr/lib
cp /lib/tls/libutil.so.1 lib/tls
cp /usr/lib/libz.so.1 usr/lib
cp /lib/tls/libnsl.so.1 usr/lib
cp /lib/tls/libcrypt.so.1 lib/tls
cp /lib/tls/libc.so.6 lib/tls
cp /lib/tls/libdl.so.2 lib/tls
cp /lib/ld-linux.so.2 lib
cp /lib/ld-linux.so.2 lib
cp /lib/libcrypt.so.1 lib
cp /lib/libnss_* lib
mkdir etc
cp /etc/passwd etc
cp /etc/ld.so* etc
mkdir dev
mknod -m 666 dev/null c 1 3
Caso não lembre, dê a permissão para execução no script que acabou de criar com o seguinte comando:
# chmod 700 gerar.sh
E execute o script:
# ./gerar.sh
Bem simples e nada engenhoso, é só pra você não ter o trabalho de mandar comando por comando. Esse arquivos são as dependências de alguns comandos que mandamos para o diretório do pequenogrilo, você pode visualizar essas dependências usando:
# ldd /usr/bin/scp
Mas teria que copiar também as dependências dos outros comandos, rssh e companhia, além de copiar o arquivo “/etc/passwd” e criar um dispositivo “/dev/null”, então esse scriptzinho vai ajudá-lo e muito!
Então mais uma vez o pequeno grilo pergunta. Você falou tanto do “/etc/passwd” e agora você acabou de copiar ele pra dentro do diretório jaula? Sim! Mas vamos fazer o seguinte com ele, vamos remover todos os usuários, exceto o pequenogrilo, então o conteúdo passwd do diretório /home/pequenogrilo/etc deve ficar assim:
pequenogrilo:x:1001:104::/backup:/usr/local/bin/rssh
ATENÇÃO! Reparem que eu alterei o diretório de /home/pequenogrilo para apenas /backup, pois agora a raiz será o diretório do pequeno grilo e devemos até criar esse diretório.
Criemos então:
# cd /home/pequenogrilo
# mkdir backup
# chmod 700 backup
# chown pequenogrilo.pequenogrilo backup
Entenderam? Não!? Então vamos praticar. Primeiro reinicie o serviço sshd com o famoso comando:
# /etc/rc.d/rc.sshd restart
Agora tentem usar o scp novamente para baixar o passwd e vejam o seu conteúdo, que surpresa!
# scp -P 2222 pequenogrilo@192.168.0.1:/etc/passwd password_denovo
# cat password_denovo
Opa, mostrou apenas o usuário “pequenogrilo”, justamente o arquivo que está no diretório jaula que criamos, assim ele ficará restrito apenas ao bendito.
Finalmente vamos ao famoso backup, para tal criei um script em shell, já mais elaborado que o primeiro, que fará essa tarefa pra gente. Segue o código, defina o nome de backup_geral.sh:
#!/bin/bash
###########################
# BACKUP GERAL COM SSH/SCP #
# Carlos Vinícius Braga dos Santos #
# msn: slaypher.code@hotmail.com #
# email: slaypher.code@gmail.com #
#########################
USUARIO=”pequenogrilo”
SERVIDOR=”192.168.0.1″
PORTA=”2222″
DIRETORIO=”/backup”
if [ $# -eq 0 ]; then
echo
echo “Nenhum diretório especificado.”
echo “Usar: $0 DIR1 [DIR2] [DIR3] …”
echo
exit 1
fi
echo
for i in $*; do
if [ -d $i ]; then
echo -n “Compactando o diretório: \”$i\” … ”
tar -czf BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz $i
echo “Concluido!”
else
echo “O parâmetro \”$i\” não e um diretório ou não foi encontrado.”
fi
done
sleep 1
echo
for i in $*; do
if [ $(du BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz | cut -f1) -gt 10000 ]; then
echo -n “Quebrando BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz em pedacos de 10MB … ”
split -b 10m BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz.
echo “Concluido!”
fi
done
sleep 1
echo
for i in $*; do
if [ $(du BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz | cut -f1) -le 10000 ]; then
echo -n “Enviando o anexo: BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz … ”
scp -P $PORTA BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz $USUARIO@$SERVIDOR:$DIRETORIO
echo “Concluido!”
rm BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz
else
for j in `ls BKP_$(basename $i)_$(date +%Y_D%d_M%m).tar.gz.*` ; do
rm BKP_`basename $i`_`date +%Y_D%d_M%m`.tar.gz 2>/dev/null >/dev/null
echo -n “Enviando o anexo: $j … ”
scp -P $PORTA $j $USUARIO@$SERVIDOR:$DIRETORIO
echo “Concluido!”
rm $j
done
fi
done
echo
echo “BACKUP CONCLUIDO!”
echo
Como essa belezura funciona? Simples, devem ser especificados quais diretórios deverão ser “backupeados”, lembre-se diretórios somente.
A partir daí ele irá compactar usando o comando tar e gzip como parâmetro, depois verificará se o tamanho do backup gerado é maior que 10MB, se for ele quebra em partes de 10MB usando o split que poderá ser montado facilmente com o comando cat.
Após quebrar o arquivo, se necessário claro, ele começa a enviar usando o scp direto para o servidor e diretório que foram especificados nas variáveis do script logo no inicio. Depois de tudo pronto, apaga os arquivos criados e finaliza o script.
Vale lembrar que os valores do tamanho a ser rateado o arquivo pode ser alterado se for essa a sua vontade, de 10MB para o valor que achar melhor.
Mas lembrando do início, ele não pode enviar sem especificar uma senha, por isso, devemos usar o comando ssh-keygen para gerar uma chave pública que possamos enviar ao servidor e dizer que o nosso host é confiável. Para tal, use o comando:
Ele vai criar as chaves no diretório ~/.ssh:
# ssh-keygen -t rsa
# cd ~/.ssh
# scp -P 2222 id_rsa.pub pequenogrilo@192.168.0.1:/backup
Informe a senha dessa vez, e ele enviará a chave para o servidor. Agora no servidor faça o seguinte:
Lembra que criamos o diretório .ssh não foi em vão:
# cd /home/pequenogrilo/.ssh
# mv /home/pequenogrilo/backup/id_rsa.pub .
# cat id_rsa.pub >> authorized_keys
# cp -R . /home/pequenogrilo/backup
Pronto, teoricamente… Basta agora reiniciar o servidor sshd com o comando:
# /etc/rc.d/rc.sshd restart
E vamos aos testes, com o script de backup já no servidor, execute-o e passe os diretórios que queira efetuar backup.
Com isso damos as permissões caso já não tenha feito e iniciamos o processo de backup dos diretórios “faculdade”, “site” e “confidencial”.
# chmod 700 backup_geral.sh
# ./backup_geral.sh faculdade/ site/ confidencial/
Após alguns instantes, tudo deverá estar lá em “/home/pequenogrilo/backup”. Dê uma checada após o final do script e seja feliz!
Backup completo!
Com isso termina, até o momento, nossa jornada ao caminho da salvação… dos nossos dados.
Espero que tenham sucesso em todo o processo que foi listado, pois tentei detalhar e facilitar o máximo possível, afim de que evitassem problemas.
Não esqueçam que o backup é um item importante para a segurança e não deve ser deixado de lado, e para finalizar, vamos adicionar o nosso script ao /etc/crontab e deixa-lo rodando diariamente às 0:01 horas!
Primeiramente vamos copiar o script para um local mais apropriado:
# cp backup_geral.sh /usr/bin
# crontab -e
E adicione a linha:
# Run daily cron jobs at 4:40 every day:
01 0 * * * /usr/bin/backup_geral.sh /diretório/a/fazer/backup
Caso queira fazer algum refinamento ou mudar algum esquema de permissão no script ou algo assim, agora fica por sua conta.
Também irei postar na sessão de scripts o backup_geral.sh para quem quiser uma forma mais fácil de pegá-lo.
Espero que seja proveitoso para vocês lerem esse artigo, assim como foi escrevê-lo.
Dedicado a turma do SuporteLivre.org / PCForum
Deixe um comentário