Cifrado en MySQL: Keystore

En previsión do inicio dunha nova matrícula para o curso "Base de datos" Preparamos unha tradución dun artigo útil para ti.

Cifrado en MySQL: Keystore

Apareceu o cifrado de datos transparente (TDE). Servidor Percona para MySQL e MySQL durante bastante tempo. Pero xa pensaches en como funciona baixo o capó e que impacto pode ter TDE no teu servidor? Nesta serie de artigos veremos como funciona TDE internamente. Comecemos co almacenamento de claves, xa que é necesario para que funcione calquera cifrado. A continuación, analizaremos máis de cerca como funciona o cifrado en Percona Server para MySQL/MySQL e que funcións adicionais ten Percona Server para MySQL.

Chaveiro MySQL

Os keyring son complementos que permiten ao servidor consultar, crear e eliminar claves nun ficheiro local (keyring_file) ou nun servidor remoto (como HashiCorp Vault). As claves sempre se almacenan na caché local para acelerar a súa recuperación.

Os complementos pódense dividir en dúas categorías:

  • Almacenamento local. Por exemplo, un ficheiro local (chamámoslle un anel de chaves baseado en ficheiros).
  • Almacenamento remoto. Por exemplo, Vault Server (chamámoslle a este un anel de chaves baseado no servidor).

Esta separación é importante porque os distintos tipos de almacenamento se comportan de forma lixeiramente diferente, non só ao almacenar e recuperar claves, senón tamén ao executalas.

Cando se utiliza un almacenamento de ficheiros, ao iniciarse, todo o contido do almacenamento cárgase na caché: identificador de clave, usuario de clave, tipo de clave e a propia chave.

No caso dunha tenda no servidor (como Vault Server), só se cargan o identificador de chave e o usuario clave ao iniciarse, polo que conseguir todas as claves non ralentiza o inicio. As chaves cárganse con preguiza. É dicir, a chave en si cárgase desde Vault só cando realmente é necesaria. Unha vez descargada, a chave almacénase na memoria caché para que non teña que acceder a ela a través de conexións TLS ao servidor de Vault no futuro. A continuación, vexamos que información está presente no almacén de claves.

A información clave contén o seguinte:

  • ID clave — identificador de chave, por exemplo:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • tipo de chave — tipo de clave baseado no algoritmo de cifrado utilizado, valores posibles: “AES”, “RSA” ou “DSA”.
  • lonxitude da chave — lonxitude da clave en bytes, AES: 16, 24 ou 32, RSA 128, 256, 512 e DSA 128, 256 ou 384.
  • usuario - propietario da chave. Se a clave é do sistema, por exemplo, a chave mestra, entón este campo está baleiro. Se se crea unha chave usando keyring_udf, este campo identifica o propietario da chave.
  • a chave en si

A chave identifícase de forma única polo par: key_id, user.

Tamén hai diferenzas no almacenamento e na eliminación de claves.

O almacenamento de ficheiros é máis rápido. Podes pensar que un almacén de claves está simplemente escribindo a chave nun ficheiro unha vez, pero non, aquí hai máis cousas. Sempre que se fai unha modificación do almacenamento de ficheiros, primeiro créase unha copia de seguridade de todo o contido. Digamos que o ficheiro chámase my_biggest_secrets, entón a copia de seguranza será my_biggest_secrets.backup. A continuación, cámbiase a caché (as chaves engádense ou elimínanse) e, se todo ten éxito, a caché restablecerase nun ficheiro. En casos raros, como un fallo do servidor, é posible que vexa este ficheiro de copia de seguranza. O ficheiro de copia de seguridade elimínase a próxima vez que se carguen as chaves (normalmente despois de que se reinicie o servidor).

Ao gardar ou eliminar unha clave nun almacenamento do servidor, o almacenamento debe conectarse ao servidor MySQL cos comandos "enviar a chave" / "solicitar a eliminación da clave".

Volvamos á velocidade de inicio do servidor. Ademais do feito de que a velocidade de lanzamento está afectada pola propia bóveda, tamén está a cuestión de cantas claves da bóveda hai que recuperar no inicio. Por suposto, isto é especialmente importante para o almacenamento do servidor. No inicio, o servidor comproba que chave é necesaria para as táboas/espazos de táboa cifrados e solicita a chave do almacenamento. Nun servidor "limpo" con cifrado de chave mestra, debe haber unha chave mestra, que debe ser recuperada do almacenamento. Non obstante, pode ser necesario un maior número de claves, por exemplo, cando o servidor de copia de seguranza está a restaurar unha copia de seguranza do servidor principal. Nestes casos, debería proporcionarse a rotación da chave mestra. Isto tratarase con máis detalle en artigos futuros, aínda que aquí gustaríame sinalar que un servidor que usa varias chaves mestras pode tardar un pouco máis en iniciarse, especialmente cando se utiliza un almacén de claves no servidor.

Agora imos falar un pouco máis sobre keyring_file. Cando estaba a desenvolver keyring_file, tamén me preocupaba como comprobar os cambios keyring_file mentres o servidor está en execución. Na versión 5.7, a comprobación realizouse en función das estatísticas de ficheiros, que non era unha solución ideal, e na versión 8.0 substituíuse por unha suma de verificación SHA256.

A primeira vez que executa keyring_file, calcúlanse as estatísticas do ficheiro e unha suma de verificación, que o servidor lembra, e os cambios só se aplican se coinciden. Cando o ficheiro cambia, a suma de verificación actualízase.

Xa cubrimos moitas preguntas sobre as bóvedas de chaves. Non obstante, hai outro tema importante que moitas veces se esquece ou se entende mal: compartir claves entre servidores.

O que quero dicir? Cada servidor (por exemplo, Percona Server) do clúster debe ter unha localización separada no Vault Server na que o Percona Server debe almacenar as súas claves. Cada chave mestra gardada no almacenamento contén o GUID do servidor Percona dentro do seu identificador. Por que é importante? Imaxina que só tes un servidor Vault e todos os servidores Percona do clúster usan ese único servidor Vault. O problema parece obvio. Se todos os servidores de Percona usasen unha chave mestra sen identificadores únicos, como id = 1, id = 2, etc., entón todos os servidores do clúster utilizarían a mesma chave mestra. O que proporciona o GUID é a distinción entre servidores. Por que falar entón de compartir claves entre servidores se xa existe un GUID único? Hai outro complemento - keyring_udf. Con este complemento, o usuario do teu servidor pode almacenar as súas claves no servidor de Vault. O problema ocorre cando un usuario crea unha chave no servidor1, por exemplo, e despois tenta crear unha chave co mesmo ID no servidor2, por exemplo:

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

Agarda. Ambos servidores están usando o mesmo servidor de Vault, non debería fallar a función keyring_key_store no server2? Curiosamente, se tentas facer o mesmo nun servidor, recibirás un erro:

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

É certo, ROB_1 xa existe.

Comentemos primeiro o segundo exemplo. Como dixemos anteriormente, keyring_vault ou calquera outro complemento de chaves almacena na memoria caché todos os ID de chaves. Así, despois de crear unha nova chave, engádese ROB_1 ao servidor1 e, ademais de enviar esta chave a Vault, a chave tamén se engade á caché. Agora, cando tentamos engadir a mesma chave unha segunda vez, keyring_vault comproba se a chave existe na caché e arroxa un erro.

No primeiro caso a situación é diferente. O servidor1 e o servidor2 teñen cachés separados. Despois de engadir ROB_1 á caché de claves do servidor1 e do servidor de Vault, a caché de claves do servidor2 non está sincronizada. Non hai ningunha chave ROB_2 na caché do servidor1. Así, a chave ROB_1 escríbese no keyring_key_store e no servidor Vault, que en realidade sobrescribe (!) o valor anterior. Agora a chave ROB_1 do servidor de Vault é 543210987654321. Curiosamente, o servidor de Vault non bloquea tales accións e sobrescribe facilmente o valor antigo.

Agora podemos ver por que pode ser importante a partición do servidor en Vault, cando estás a usar keyring_udf e queres almacenar chaves en Vault. Como conseguir esta separación nun servidor Vault?

Hai dúas formas de particionar en Vault. Podes crear diferentes puntos de montaxe para cada servidor ou usar diferentes camiños dentro do mesmo punto de montaxe. Isto é mellor ilustrado con exemplos. Entón, vexamos primeiro os puntos de montaxe individuais:

--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 = (...)

Aquí podes ver que o servidor1 e o servidor2 están a usar puntos de montaxe diferentes. Ao dividir os camiños, a configuración será así:

--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 = (...)

Neste caso, ambos os servidores usan o mesmo punto de montaxe "mount_point", pero camiños diferentes. Cando creas o primeiro segredo no servidor1 usando esta ruta, o servidor de Vault crea automaticamente un directorio "servidor1". Para server2 todo é semellante. Cando elimina o último segredo en mount_point/server1 ou mount_point/server2, o servidor de Vault tamén elimina eses directorios. No caso de que use a separación de camiños, debe crear só un punto de montaxe e cambiar os ficheiros de configuración para que os servidores utilicen camiños separados. Pódese crear un punto de montaxe mediante unha solicitude HTTP. Usando CURL pódese facer así:

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) corresponden aos parámetros do ficheiro de configuración. Por suposto, podes usar as utilidades de Vault para facer o mesmo. Pero é máis fácil automatizar a creación dun punto de montaxe. Espero que che resulte útil esta información e vémonos nos próximos artigos desta serie.

Cifrado en MySQL: Keystore

Le máis:

Fonte: www.habr.com

Engadir un comentario