Com a proximidade do início de um novo ciclo de inscrições para o curso preparamos para você a tradução de um artigo útil.

A criptografia transparente de dados (Transparent Data Encryption, TDE) surgiu no e MySQL há bastante tempo. Mas você já se perguntou como isso funciona por trás das cenas e qual é o impacto que o TDE pode ter no seu servidor? Nesta série de artigos, vamos examinar como o TDE funciona internamente. Começaremos pelo armazenamento de chaves, que é necessário para a operação de qualquer criptografia. Depois, iremos detalhar como a criptografia funciona no Percona Server for MySQL/MySQL e quais recursos adicionais existem no Percona Server for MySQL.
MySQL Keyring
Keyring — são plugins que permitem ao servidor solicitar, criar e excluir chaves em um arquivo local (keyring_file) ou em um servidor remoto (como o HashiCorp Vault). As chaves são sempre armazenadas em cache localmente para acelerar sua recuperação.
Os plugins podem ser divididos em duas categorias:
- Armazenamento local. Por exemplo, um arquivo local (chamamos isso de armazenamento de chaves baseado em arquivos, file-based keyring).
- Armazenamento remoto. Por exemplo, um Vault Server (chamamos isso de armazenamento de chaves baseado em servidor, server-based keyring).
Essa divisão é importante, pois diferentes tipos de armazenamento se comportam um pouco de maneira diferente tanto ao armazenar e recuperar chaves quanto durante a inicialização.
Quando se utiliza um armazenamento baseado em arquivos, ao iniciar, todo o conteúdo do armazenamento é carregado em cache: key id, key user, key type e a própria chave.
No caso de armazenamento baseado em servidores (como um servidor Vault), ao iniciar, apenas key id e key user são carregados, portanto, a recuperação de todas as chaves não desacelera a inicialização. As chaves são carregadas de forma preguiçosa. Ou seja, a chave em si é carregada do Vault somente quando realmente necessário. Após o carregamento, a chave é armazenada em cache na memória, para que no futuro não seja necessário acessá-la através de conexões TLS com o Vault Server. A seguir, vamos ver quais informações estão presentes no armazenamento de chaves.
As informações da chave contêm o seguinte:
- key id — identificador da chave, por exemplo:
INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1 - key type — tipo da chave, baseado no algoritmo de criptografia utilizado, os valores possíveis são: «AES», «RSA» ou «DSA».
- key length — comprimento da chave em bytes, AES: 16, 24 ou 32, RSA 128, 256, 512 e DSA 128, 256 ou 384.
- user — proprietário da chave. Se a chave for uma chave de sistema, como a Master Key, este campo ficará vazio. Se a chave for criada usando keyring_udf, este campo indica o proprietário da chave.
- a chave
A chave é identificada de forma única pelo par: key_id, user.
Também existem diferenças no armazenamento e na exclusão de chaves.
O armazenamento em arquivo funciona mais rápido. Pode-se supor que o armazenamento de chaves é uma simples gravação única da chave em um arquivo, mas não — aqui ocorrem mais operações. Ao modificar o armazenamento em arquivo, uma cópia de segurança de todo o conteúdo é criada primeiro. Suponha que o arquivo se chama my_biggest_secrets, então a cópia de segurança será my_biggest_secrets.backup. Depois, o cache é modificado (chaves são adicionadas ou removidas) e, se tudo for bem-sucedido, o cache é gravado no arquivo. Em casos raros, como falha do servidor, você pode ver este arquivo de cópia de segurança. O arquivo de cópia de segurança é excluído na próxima carga das chaves (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 chave’ / ‘solicitar exclusão de chave’ (‘send the key’ / ‘request key deletion’).
Vamos voltar à velocidade de inicialização do servidor. Além do fato de que a própria armazenagem afeta a velocidade de inicialização, há também a questão de quantas chaves do armazenamento precisam ser obtidas na inicialização. Claro, isso é especialmente importante para armazenamentos de servidor. Na inicialização, o servidor verifica qual chave é necessária para as tabelas criptografadas / espaços de tabela e solicita a chave do armazenamento. Em um servidor ‘limpo’ com Master Key — a criptografia deve ter uma única Master Key, que deve ser extraída do armazenamento. No entanto, pode ser necessária uma quantidade maior de chaves, por exemplo, quando um servidor de backup está restaurando uma cópia de segurança de um servidor principal. Nesses casos, deve-se considerar a rotação da Master Key. Mais detalhes serão discutidos em futuros artigos, embora eu queira ressaltar aqui que um servidor que utiliza várias Master Keys pode iniciar um pouco mais devagar, especialmente ao usar armazenamento de chaves do servidor.
Agora vamos falar um pouco mais sobre o keyring_file. Quando desenvolvi o keyring_file, eu também me preocupava com como checar a alteração do keyring_file durante a operação do servidor. Na versão 5.7, a verificação era feita com base nas estatísticas do arquivo, o que não era uma solução ideal, e na 8.0 foi substituída por um hash SHA256.
Na primeira execução, as estatísticas do arquivo e o hash são calculados e armazenados pelo servidor, e as alterações são aplicadas apenas se coincidirem. Ao alterar o arquivo, o hash é atualizado.
Já discutimos várias questões sobre repositórios de chaves. No entanto, há um outro tópico importante, frequentemente esquecido ou mal interpretado — a separação de chaves entre servidores.
O que quero dizer? Cada servidor (por exemplo, Percona Server) em um cluster deve ter um local separado no servidor Vault, onde o Percona Server deve armazenar suas chaves. Em cada Master Key armazenada, contém-se o GUID do servidor Percona Server dentro de seu identificador. Por que isso é importante? Imagine que você tem apenas um servidor Vault e todos os Percona Servers no cluster usam esse único servidor Vault. O problema parece óbvio. Se todos os Percona Servers usassem uma Master Key sem identificadores únicos, por exemplo, id = 1, id = 2, etc., todos os servidores no cluster usariam a mesma Master Key. O que o GUID fornece — é uma delimitação entre servidores. Então, por que falar sobre a separação de chaves entre servidores, se já existe um GUID único? Há um outro plugin — keyring_udf. Com este plugin, um usuário do seu servidor pode armazenar suas chaves no servidor Vault. O problema surge quando o usuário cria uma chave, por exemplo, no servidor server1, e depois tenta criar uma chave com o mesmo identificador no server2, por exemplo:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 significa que foi bem-sucedido
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1Espere. Ambos os servidores usam o mesmo servidor Vault, a função keyring_key_store não deveria resultar em erro no servidor server2? Curiosamente, se você tentar fazer a mesma coisa em um único servidor, receberá um erro:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0Correto, ROB_1 já existe.
Vamos primeiro discutir o segundo exemplo. Como mencionamos anteriormente, o keyring_vault ou qualquer outro plugin de armazenamento (keyring) armazena em cache todos os identificadores de chave na memória. Assim, após a criação de uma nova chave, o ROB_1 é adicionado ao server1 e, além de enviar essa chave para o Vault, a chave também é adicionada ao cache. Agora, quando tentamos adicionar a mesma chave pela segunda vez, o keyring_vault verifica se essa chave já existe no cache e gera um erro.
No primeiro caso, a situação é diferente. Nos servidores server1 e server2, há caches separados. Após adicionar o ROB_1 ao cache de chaves no servidor server1 e no servidor Vault, o cache de chaves no server2 não está sincronizado. 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 efetivamente sobrescreve (!) o valor anterior. Agora a chave ROB_1 no servidor Vault é igual a 543210987654321. Curiosamente, o servidor Vault não bloqueia tais ações e simplesmente sobrescreve o valor antigo.
Agora vemos por que a divisão por servidores no Vault pode ser importante — quando você usa o keyring_udf e deseja armazenar chaves no Vault. Como assegurar essa divisão no servidor Vault?
Existem duas maneiras de dividir no Vault. Você pode criar diferentes pontos de montagem para cada servidor ou usar diferentes caminhos dentro de um único ponto de montagem. Vamos mostrar isso com exemplos. Então, vamos primeiro olhar para os pontos de montagem separados:
--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 = server2_mount
token = (...)
vault_ca = (...)Aqui vemos que server1 e server2 usam pontos de montagem diferentes. Ao dividir caminhos, a configuração será a seguinte:
--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/server2
token = (...)
vault_ca = (...)Neste caso, ambos os servidores usam o mesmo ponto de montagem "mount_point", mas caminhos diferentes. Ao criar o primeiro segredo no servidor server1 nesse caminho, o servidor Vault cria automaticamente o diretório "server1". O mesmo acontece para server2. Quando você exclui o último segredo em mount_point/server1 ou mount_point/server2, o servidor Vault também remove esses diretórios. Se você estiver usando a separação de caminhos, deve criar apenas um ponto de montagem e alterar os arquivos de configuração para que os servidores usem caminhos separados. O ponto de montagem pode ser criado com uma solicitação HTTP. Com CURL, isso pode ser feito da seguinte forma:
curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINTTodos os campos (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) correspondem aos parâmetros do arquivo de configuração. Claro, você pode usar as utilidades Vault para fazer o mesmo. Mas assim é mais fácil automatizar a criação do ponto de montagem. Espero que esta informação seja útil para você, e nos vemos nos próximos artigos desta série.
Leia mais:
Fonte: habr.com
