Cifrado MySQL: almacén de claves

En vísperas del inicio de un nuevo reclutamiento para el curso "Bases de datos", hemos preparado una traducción de un artículo útil para usted.






El cifrado transparente de datos (TDE) ha existido durante mucho tiempo en Percona Server para MySQL y MySQL. Pero, ¿se ha preguntado alguna vez cómo funciona bajo el capó y qué impacto puede tener TDE en su servidor? En esta serie de artículos, veremos cómo funciona TDE internamente. Comencemos con el almacenamiento de claves, ya que esto es necesario para que funcione cualquier cifrado. Luego, veremos más de cerca cómo funciona el cifrado en Percona Server para MySQL / MySQL y qué características adicionales están disponibles en Percona Server para MySQL.



Llavero MySQL



Los llaveros son complementos que permiten al servidor consultar, crear y eliminar claves en un archivo local (keyring_file) o en un servidor remoto (como en HashiCorp Vault). Las claves siempre se almacenan en caché localmente para acelerar la recuperación.



Los complementos se pueden dividir en dos categorías:



  • Almacenamiento local. Por ejemplo, un archivo local (lo llamamos llavero basado en archivos).
  • Almacenamiento remoto. Por ejemplo, Vault Server (a esto lo llamamos llavero basado en servidor).


Esta separación es importante porque los diferentes tipos de almacenamiento se comportan de manera ligeramente diferente, no solo al almacenar y recuperar claves, sino también al iniciar.



Cuando se usa un almacenamiento de archivos, al inicio, todo el contenido del almacenamiento se carga en la caché: ID de clave, usuario de clave, tipo de clave y la clave en sí.



En el caso de una bóveda de back-end (como un servidor de Vault), solo la identificación de la clave y el usuario de la clave se cargan al inicio, por lo que obtener todas las claves no ralentiza el inicio. Las claves se cargan con pereza. Es decir, la clave en sí se carga desde Vault solo cuando realmente se necesita. Una vez cargada, la clave se almacena en la memoria caché para que en el futuro no sea necesario acceder a ella a través de conexiones TLS al servidor Vault. A continuación, veamos qué información está presente en el almacén de claves.



La información clave contiene lo siguiente:



  • key id — , :

    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • key type — , , : «AES», «RSA» «DSA».
  • key length — , AES: 16, 24 32, RSA 128, 256, 512 DSA 128, 256 384.
  • user — . , , Master Key, . keyring_udf, .


La clave está identificada de forma única por el par: key_id, usuario.



También existen diferencias en el almacenamiento y eliminación de llaves.



El almacenamiento de archivos es más rápido. Podemos suponer que el almacén de claves es una simple escritura única de la clave en el archivo, pero no, aquí se están realizando más operaciones. Cualquier modificación en el almacenamiento de archivos creará primero una copia de seguridad de todo el contenido. Digamos que el archivo se llama my_biggest_secrets, luego la copia de seguridad será my_biggest_secrets.backup. A continuación, se cambia la caché (se agregan o eliminan claves) y, si todo se realiza correctamente, la caché se vacía en un archivo. En casos excepcionales, como una falla del servidor, es posible que vea este archivo de respaldo. El archivo de respaldo se elimina la próxima vez que se cargan las claves (generalmente después de reiniciar el servidor).



Al guardar o eliminar una clave en el repositorio del servidor, el repositorio debe conectarse al servidor MySQL con los comandos "enviar la clave" / "solicitar eliminación de clave".



Volvamos a la velocidad de inicio del servidor. Además del hecho de que el almacenamiento en sí afecta la velocidad de inicio, también existe la cuestión de cuántas claves del almacenamiento necesita obtener al inicio. Por supuesto, esto es especialmente importante para el almacenamiento de fondo. Al inicio, el servidor verifica qué clave se requiere para las tablas / espacios de tabla encriptados y solicita la clave del almacenamiento. En un servidor "limpio" con clave maestra: cifrado, debe haber una clave maestra, que debe recuperarse del almacenamiento. Sin embargo, es posible que se necesiten más claves, por ejemplo, al restaurar una copia de seguridad del servidor principal a un servidor de copia de seguridad. En tales casos, se debe proporcionar una rotación de clave maestra. Esto se discutirá con más detalle en artículos futuros, aunque aquí me gustaría señalar que el servidor,El uso de múltiples claves maestras puede tardar un poco más en comenzar, especialmente cuando se usa un almacén de claves del lado del servidor.



Ahora hablemos un poco más sobre keyring_file. Cuando estaba desarrollando keyring_file, también me preocupaba cómo verificar los cambios de keyring_file mientras el servidor se estaba ejecutando. En 5.7, la verificación se realizó en base a estadísticas de archivos, que no era una solución ideal, y en 8.0 se reemplazó con una suma de verificación SHA256.



La primera vez que ejecuta keyring_file, el servidor calcula y recuerda las estadísticas del archivo y la suma de comprobación, y los cambios se aplican solo si coinciden. La suma de comprobación se actualiza cuando se cambia el archivo.



Ya hemos cubierto muchas preguntas sobre los almacenes de claves. Sin embargo, hay otro tema importante que a menudo se olvida o se malinterpreta: el intercambio de claves entre servidores.



¿Lo que quiero decir? Cada servidor (por ejemplo, Percona Server) en el clúster debe tener una ubicación separada en el servidor de Vault donde Percona Server debe almacenar sus claves. Cada clave maestra almacenada en el repositorio contiene el GUID del servidor Percona dentro de su identificador. ¿Por qué es importante? Imagine que solo tiene un servidor Vault y todos los servidores Percona del clúster están utilizando ese único servidor Vault. El problema parece obvio. Si todos los servidores Percona estuvieran usando la clave maestra sin identificadores únicos, por ejemplo, id = 1, id = 2, etc., entonces todos los servidores del clúster usarían la misma clave maestra. Esto es lo que proporciona el GUID: la distinción entre servidores. Entonces, ¿por qué hablar de compartir claves entre servidores cuando ya existe un GUID único? Hay un complemento más: keyring_udf.Con este complemento, el usuario de su servidor puede almacenar sus claves en el servidor de Vault. El problema ocurre cuando el usuario crea una clave, por ejemplo, en el servidor1, y luego intenta crear una clave con el mismo ID en el servidor2, por ejemplo:



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


Espere. Ambos servidores están usando el mismo Vault Server, ¿no debería fallar la función keyring_key_store en server2? Curiosamente, si intenta hacer lo mismo en el mismo servidor, obtendrá un error:



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


Así es, ROB_1 ya existe.



Analicemos el segundo ejemplo primero. Como dijimos anteriormente, keyring_vault o cualquier otro complemento de keyring almacenará en caché todos los ID de clave en la memoria. Por lo tanto, después de crear una nueva clave, ROB_1 se agrega al servidor1 y, además de enviar esta clave a Vault, la clave también se agrega a la caché. Ahora, cuando intentamos agregar la misma clave por segunda vez, keyring_vault verifica si esta clave existe en el caché y arroja un error.



En el primer caso, la situación es diferente. Server1 y server2 tienen cachés separados. Después de agregar ROB_1 a los cachés de claves en el servidor1 y Vault, los cachés de claves en el servidor2 no están sincronizados. No hay una clave ROB_1 en la caché del servidor2. Por lo tanto, la clave ROB_1 se escribe en keyring_key_store y en el servidor de Vault, que en realidad sobrescribe (!) El valor anterior. Ahora, la clave ROB_1 en el servidor de Vault es 543210987654321. Curiosamente, el servidor de Vault no bloquea tales acciones y sobrescribe fácilmente el valor anterior.



Ahora podemos ver por qué puede ser importante dividir por servidor por bóveda, cuando está usando keyring_udf y desea almacenar claves en un bóveda. ¿Cómo proporciona esta separación en el servidor de Vault?



Hay dos formas de dividirse en Vault. Puede crear diferentes puntos de montaje para cada servidor o utilizar diferentes rutas dentro del mismo punto de montaje. Esto se ilustra mejor con ejemplos. Así que primero echemos un vistazo a los puntos de montaje individuales:



--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í puede ver que server1 y server2 están usando diferentes puntos de montaje. Al dividir rutas, la configuración se verá 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 = (...)


En este caso, ambos servidores usan el mismo mount_point, pero diferentes rutas. Cuando se crea el primer secreto en server1 a lo largo de esta ruta, Vault crea automáticamente el directorio "server1". Para server2, todo es igual. Cuando elimina el último secreto en mount_point / server1 o mount_point / server2, el servidor de Vault también elimina esos directorios. En caso de que esté usando la división de rutas, solo tiene que crear un punto de montaje y cambiar los archivos de configuración para que los servidores usen rutas separadas. Se puede crear un punto de montaje mediante una solicitud HTTP. Con CURL, se puede hacer 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 los campos (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) corresponden a los parámetros del archivo de configuración. Por supuesto, puede utilizar las utilidades de Vault para hacer lo mismo. Pero esto facilita la automatización de la creación del punto de montaje. Espero que encuentre útil esta información y nos vemos en los próximos artículos de esta serie.





Lee mas:






All Articles