Criptografando nossos backups: chegando até a linha de chegada

Publicados: 2017-09-02

Nota: Este post de engenharia foi escrito por nossa administradora de banco de dados, Silvia Botros. Confira alguns de seus outros posts de DBA aqui.

Há um ano, o SendGrid estava trabalhando duro para obter a certificação SOC2. Todos estavam envolvidos. Havia histórias em quase todos os quadros de equipes de entrega com uma etiqueta SOC2, pois todos estávamos procurando ser certificados até o final do terceiro trimestre. Como você pode imaginar, sendo a pessoa responsável pelos bancos de dados, definitivamente havia algum trabalho a fazer para essa parte da pilha.

Na minha lista de tarefas para esse empreendimento em toda a empresa estava garantir que nossos backups fossem criptografados. Como minha área de familiaridade são ferramentas de DBA e sabendo que o xtrabackup da Percona já tem suporte para criptografia, era previsível que eu fosse para isso como a primeira tentativa nessa tarefa.

Algumas coisas importantes estavam na minha mira ao testar essa abordagem:

  • Obviamente, o backup precisava ser criptografado
  • A sobrecarga para criar o backup precisava ser conhecida e aceitável
  • A sobrecarga para descriptografar o backup no momento da recuperação precisava ser conhecida e aceitável

Isso significava que, primeiro, eu precisava rastrear quanto tempo meus backups demoram.

Acompanhamento do tempo de backup

O SendGrid usa o Graphite para suas métricas de infraestrutura e, embora a grande maioria seja enviada via Sensu, o Graphite é fácil o suficiente para enviar métricas diretamente por linhas bash – muito conveniente, pois os scripts de backup estão no bash. Observe que enviar métricas diretamente no Graphite não é super escalável, mas como esses backups são executados no máximo uma vez por hora, isso foi bom para minhas necessidades.

Essa parte acabou sendo relativamente fácil.

Para explicar o que aconteceu nessa última linha, envio ao Graphite o caminho da métrica que estou enviando (certifique-se de que é único), o valor da métrica e depois a hora atual no formato de época. Netcat é o que eu decidi usar por simplicidade, e dou um tempo limite de 1 segundo porque, caso contrário, ele nunca sairá. O `graphite url` é nosso endpoint DNS para Graphite no data center.

Agora que eu tinha uma linha de base para comparar, estávamos prontos para começar a testar os métodos de criptografia.

Seguindo a documentação detalhada da Percona sobre como fazer isso, comecei fazendo uma chave. Se você ler essa página de documentação com atenção, poderá perceber algo.

Essa chave deve ser passada diretamente para a ferramenta de backup e é a mesma chave que pode descriptografar o instantâneo. Isso é chamado de criptografia simétrica e é, por natureza dessa mesma chave em ambas as direções, menos segura do que a criptografia assimétrica. Decidi continuar testando para ver se a simplicidade ainda torna essa abordagem viável.

Testes com bancos de dados muito pequenos, algumas centenas de MBs, foram bem-sucedidos. A ferramenta funciona como esperado e documentado, mas isso foi mais um teste funcional e a verdadeira questão era “qual é o tamanho da penalidade de criptografia em nossos bancos de dados maiores?” As instâncias mais legadas no SendGrid cresceram para tamanhos de 1-2 TB para uma única besta de 18 TB. O que eu ia usar para as instâncias pequenas também tinha que ser operacionalmente aceitável nas maiores.

Foi aqui que os testes e benchmarks ficaram interessantes

Minha primeira cobaia de tamanho considerável é um banco de dados que temos com 1 TB em disco. Muito rapidamente, encontrei um problema inesperado. Com configurações mínimas de criptografia (1 thread, tamanhos de bloco padrão), vi os backups falharem com este erro:

Na época, esses bancos de dados usavam 512 MB como tamanho do arquivo de log de transações, e esse é um cluster bastante ocupado, de modo que esses arquivos estavam girando quase a cada minuto. Normalmente, isso seria perceptível no desempenho do banco de dados, mas foi mascarado principalmente pela maravilha das unidades de estado sólido. Parece que não definir nenhum thread de criptografia paralelo (leia-se: use um) significa que gastamos tanto tempo criptografando arquivos `.ibd` que os redo logs do innodb estavam fazendo o backup quebrar.

Então, vamos tentar isso novamente com vários threads de criptografia. Como primeira tentativa, tentei com 50 threads. O truque aqui é encontrar o ponto ideal de criptografia rápida sem competir pela CPU. Também aumentei o tamanho dos `ib_logfiles` para 1 GB cada.

Este foi um teste mais bem-sucedido que fiquei feliz em deixar fermentar durante a noite. Nas primeiras noites, as coisas pareciam boas. Era hora de fazer um backup que não crescesse muito, mas a média de carregamento de caixa durante o processo de backup estava definitivamente mostrando as etapas adicionadas.

No entanto, quando passei a testar as restaurações, descobri que o processo de restauração dos mesmos backups, após a adição de criptografia, aumentou de 60 para 280 minutos, o que significa uma penalidade severa para nosso tempo de recuperação prometido em caso de desastre.

Precisávamos trazer isso de volta para um prazo mais razoável.

Foi aqui que o trabalho em equipe e as soluções mais simples para os problemas brilharam. Um dos membros da nossa equipe InfoSec decidiu ver se esta solução pode ser simplificada. Então ele fez mais alguns testes e voltou com algo mais simples e mais seguro. Eu ainda não tinha aprendido sobre gpg2 e isso se tornou um exercício de aprendizado para mim também.

O bom do gpg2 é que ele suporta criptografia assimétrica. Criamos um par de chaves onde existem partes privadas e públicas. A parte pública é usada para criptografar qualquer fluxo ou arquivo que você decida alimentar gpg2 e o segredo privado pode ser usado para descriptografar.

A mudança em nossos scripts de backup para adicionar criptografia destilada a isso. Alguns argumentos foram removidos para facilitar a leitura:

Por outro lado, ao restaurar um backup, basta verificar se uma chave secreta aceitável está no chaveiro do host e usar este comando:

Como eu também era novo no gpg2, isso se tornou uma oportunidade de aprendizado para mim. Colin, nosso incrível membro da equipe InfoSec, continuou testando backups e restaurações usando gpg2 até confirmar que usar gpg2 tinha várias vantagens em usar a compactação integrada do xtrabackup, incluindo:

  • era assimétrico
  • Seu gerenciamento secreto para descriptografia é girado com relativa facilidade (mais sobre isso abaixo)
  • É independente de ferramentas, o que significa que qualquer outro tipo de backup que não esteja usando o xtrabackup pode usar o mesmo método
  • Ele estava usando vários núcleos na descriptografia, o que nos deu melhores tempos de restauração

Sempre espaço para melhorias

Um lugar onde ainda vejo espaço para melhorias é como lidamos com o segredo que pode descriptografar esses arquivos. No momento, nós os temos em nossa solução de gerenciamento de senhas corporativas, mas obtê-los a partir daí e usá-los para testar backups é um processo manual. O próximo passo em nosso plano é implementar o Vault by Hashicorp e usá-lo para, nos hosts designados, extrair a chave secreta para descriptografia e removê-la do anel local para que fique facilmente disponível para testes automatizados e ainda protegida.

Por fim, conseguimos que todos os nossos backups de banco de dados estivessem em conformidade com nossas necessidades de SOC2 a tempo, sem sacrificar o desempenho do backup ou o SLA de recuperação de desastres. Eu me diverti muito trabalhando nesta tarefa com nossa equipe InfoSec e aprendi novas ferramentas. Além disso, é sempre bom quando a solução mais simples acaba sendo a mais adequada para a tarefa.