Criptografia no MySQL: Keystore

Antecipando o início de uma nova inscrição para o curso "Base de dados" preparou uma tradução de um artigo útil para você.

Criptografia no MySQL: Keystore

Criptografia transparente de dados (TDE) apareceu em Servidor Percona para MySQL e MySQL há algum tempo. Mas você já pensou em como ele funciona internamente e qual o impacto que o TDE pode ter em seu servidor? Nesta série de artigos, veremos como o TDE funciona internamente. Vamos começar com o armazenamento de chaves, pois é necessário para que qualquer criptografia funcione. Em seguida, examinaremos mais de perto como a criptografia funciona no Percona Server para MySQL/MySQL e quais recursos adicionais estão disponíveis no Percona Server para MySQL.

Chaveiro do MySQL

Os chaveiros são plug-ins que permitem ao servidor consultar, criar e excluir chaves em um arquivo local (keyring_file) ou em um servidor remoto (por exemplo, no HashiCorp Vault). As chaves são sempre armazenadas em cache localmente para acelerar a recuperação.

Os plugins podem ser divididos em duas categorias:

  • Armazenamento local. Por exemplo, um arquivo local (chamamos isso de chaveiro baseado em arquivo).
  • armazenamento remoto. Por exemplo Vault Server (nós o chamamos de chaveiro baseado em servidor).

Essa separação é importante porque diferentes tipos de armazenamento se comportam de maneira ligeiramente diferente, não apenas ao armazenar e recuperar chaves, mas também ao inicializar.

Ao usar o armazenamento de arquivos, todo o conteúdo do armazenamento é carregado no cache na inicialização: ID da chave, usuário da chave, tipo de chave e a própria chave.

No caso de um armazenamento de back-end (por exemplo, o servidor Vault), apenas o ID da chave e o usuário da chave são carregados na inicialização, portanto, obter todas as chaves não retarda a inicialização. As chaves são carregadas lentamente. Ou seja, a própria chave é carregada do Vault apenas quando é realmente necessária. Após o download, a chave é armazenada em cache na memória para que no futuro não haja necessidade de acessá-la por meio de conexões TLS ao Vault Server. Em seguida, considere quais informações estão presentes no keystore.

As informações principais contêm o seguinte:

  • ID da chave - identificador de chave, por exemplo:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • Tipo de chave - tipo de chave com base no algoritmo de criptografia usado, valores possíveis: "AES", "RSA" ou "DSA".
  • comprimento da chave - comprimento da chave em bytes, AES: 16, 24 ou 32, RSA 128, 256, 512 e DSA 128, 256 ou 384.
  • usuário é o dono da chave. Se a chave for uma chave do sistema, como Chave mestra, esse campo estará vazio. Se a chave for criada usando keyring_udf, esse campo indicará o proprietário da chave.
  • a própria chave

A chave é identificada exclusivamente pelo par: key_id, user.

Também existem diferenças no armazenamento e exclusão de chaves.

O armazenamento de arquivos é mais rápido. Você pode pensar que o keystore é apenas uma gravação única da chave para um arquivo, mas não é - há mais coisas acontecendo aqui. Sempre que um armazenamento de arquivo é modificado, todo o conteúdo é primeiro copiado. Digamos que o arquivo se chame my_biggest_secrets, então o backup será my_biggest_secrets.backup. Em seguida, o cache é alterado (as chaves são adicionadas ou removidas) e, se tudo der certo, o cache é despejado em um arquivo. Em casos raros, como uma falha no servidor, você pode ver esse arquivo de backup. O arquivo de backup é excluído na próxima vez que as chaves forem carregadas (geralmente após a reinicialização do servidor).

Ao salvar ou excluir uma chave no armazenamento do servidor, o armazenamento deve se conectar ao servidor MySQL com os comandos "enviar a chave" / "solicitar exclusão da chave".

Vamos voltar à velocidade de inicialização do servidor. Além do fato de o próprio cofre afetar a velocidade de inicialização, também existe a questão de quantas chaves do cofre precisam ser obtidas na inicialização. Claro, isso é especialmente importante para armazenamentos de servidores. Na inicialização, o servidor verifica qual chave é necessária para as tabelas/espaços de tabela criptografados e solicita a chave do armazenamento. Em um servidor "limpo" com uma chave mestra - deve haver uma chave mestra para criptografia, que deve ser recuperada do armazenamento. No entanto, mais chaves podem ser necessárias, por exemplo, quando um backup do servidor principal é restaurado para um servidor em espera. Nesses casos, a rotação da Chave Mestra deve ser fornecida. Isso será discutido com mais detalhes em artigos futuros, embora aqui eu gostaria de observar que um servidor que usa várias chaves mestras pode demorar um pouco mais para iniciar, especialmente ao usar um armazenamento de chaves do servidor.

Agora vamos falar um pouco mais sobre keyring_file. Quando eu estava projetando o keyring_file, também estava preocupado em como verificar as alterações do keyring_file enquanto o servidor estava em execução. No 5.7, a verificação era realizada com base nas estatísticas do arquivo, o que não era o ideal, e no 8.0 foi substituída por uma soma de verificação SHA256.

Na primeira vez que keyring_file é executado, as estatísticas e a soma de verificação do arquivo são calculadas e lembradas pelo servidor, e as alterações são aplicadas apenas se forem correspondentes. Quando o arquivo é alterado, a soma de verificação é atualizada.

Já abordamos muitas questões sobre keystores. No entanto, há outro tópico importante que costuma ser esquecido ou mal compreendido - o compartilhamento de chaves entre os servidores.

O que eu quero dizer? Cada servidor (por exemplo, Percona Server) no cluster deve ter um local separado no Vault Server no qual o Percona Server deve armazenar suas chaves. Cada chave mestra armazenada no cofre contém o GUID do Percona Server em seu ID. Por que isso é importante? Imagine que você tenha apenas um Vault Server e todos os Percona Servers no cluster usem esse único Vault Server. O problema parece óbvio. Se todos os servidores Percona usassem uma chave mestra sem identificadores exclusivos, como id = 1, id = 2 etc., todos os servidores no cluster usariam a mesma chave mestra. Isso é o que o GUID fornece - a distinção entre servidores. Por que então falar sobre o compartilhamento de chaves entre servidores se já existe um GUID exclusivo? Existe outro plugin - keyring_udf. Com este plug-in, um usuário do seu servidor pode armazenar suas chaves no servidor Vault. O problema ocorre quando um usuário cria uma chave, por exemplo, no server1, e depois tenta criar uma chave com o mesmo ID no server2, por exemplo:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 значит успешное завершение
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

Espere. Ambos os servidores usam o mesmo Vault Server, a função keyring_key_store não deveria falhar no server2? Curiosamente, se você tentar fazer o mesmo no mesmo servidor, receberá um erro:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0

Isso mesmo, ROB_1 já existe.

Vamos discutir primeiro o segundo exemplo. Como dissemos anteriormente, keyring_vault ou qualquer outro plug-in de cofre (keyring) armazena em cache todos os IDs de chave na memória. Assim, após criar uma nova chave, o ROB_1 é adicionado ao servidor1 e, além de enviar essa chave para o Vault, a chave também é adicionada ao cache. Agora, quando tentamos adicionar a mesma chave uma segunda vez, keyring_vault verifica se a chave existe no cache e gera um erro.

No primeiro caso, a situação é diferente. Server1 e server2 possuem caches separados. Depois de adicionar ROB_1 ao cache de chaves no servidor1 e no servidor Vault, o cache de chaves no servidor2 está fora de sincronia. O cache no server2 não contém a chave ROB_1. Assim, a chave ROB_1 é gravada no keyring_key_store e no servidor Vault, que na verdade substitui (!) o valor anterior. Agora, a chave ROB_1 no servidor Vault é 543210987654321. Curiosamente, o servidor Vault não bloqueia essas ações e substitui facilmente o valor antigo.

Agora vemos porque a segregação por servidor no Vault pode ser importante quando você usa keyring_udf e deseja armazenar chaves no Vault. Como fornecer essa separação no servidor Vault?

Existem duas maneiras de particionar no Vault. Você pode criar pontos de montagem diferentes para cada servidor ou usar caminhos diferentes dentro do mesmo ponto de montagem. A melhor maneira de mostrar isso é com exemplos. Então, vamos olhar para os pontos de montagem individuais primeiro:

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = server1_mount
token = (...)
vault_ca = (...)

--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = sever2_mount
token = (...)
vault_ca = (...)

Aqui você pode ver que server1 e server2 usam diferentes pontos de montagem. Com separação de caminho, a configuração ficará assim:

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/server1
token = (...)
vault_ca = (...)
--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/sever2
token = (...)
vault_ca = (...)

Nesse caso, ambos os servidores usam o mesmo ponto de montagem "mount_point", mas caminhos diferentes. Quando você cria o primeiro segredo no server1 usando esse caminho, o servidor Vault cria automaticamente um diretório "server1". Para server2, tudo é o mesmo. Quando você exclui o último segredo em mount_point/server1 ou mount_point/server2, o servidor Vault também exclui esses diretórios. Caso você esteja usando caminhos divididos, você deve criar apenas um ponto de montagem e alterar os arquivos de configuração para que os servidores usem caminhos separados. Um ponto de montagem pode ser criado com uma solicitação HTTP. Com CURL isso pode ser feito assim:

curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINT

Todos os campos (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) correspondem aos parâmetros do arquivo de configuração. Claro, você pode usar os utilitários do Vault para fazer o mesmo. Mas é mais fácil automatizar a criação de um ponto de montagem. Espero que você ache essas informações úteis e nos vemos nos próximos artigos desta série.

Criptografia no MySQL: Keystore

Consulte Mais informação:

Fonte: habr.com

Adicionar um comentário