MySQL加密:密钥库

在为“数据库”课程准备一套新书的前夕,我们为您准备了一篇有用的文章的翻译本。






Percona Server for MySQL和MySQL中的 透明数据加密(TDE)已经存在了很长时间。但是您是否曾经想过它在后台如何工作以及TDE对您的服务器有什么影响?在本系列文章中,我们将了解TDE在内部如何工作。让我们从密钥的存储开始,因为这是任何加密工作所必需的。然后,我们将仔细研究Perkena Server for MySQL / MySQL中加密的工作原理以及Percona Server for MySQL中可用的其他功能。



MySQL密钥环



密钥环是允许服务器查询,创建和删除本地文件(keyring_file)或远程服务器(例如HashiCorp Vault)中的密钥的插件。密钥始终在本地缓存,以加快检索速度。



插件可以分为两类:



  • 本地存储。例如,本地文件(我们称其为基于文件的密钥环)。
  • 远程存储。例如Vault服务器(我们称为此基于服务器的密钥环)。


这种分离很重要,因为不同类型的存储不仅在存储和检索密钥时而且在启动时的行为也略有不同。



使用文件存储时,在启动时,存储的全部内容都将加载到缓存中:密钥ID,密钥用户,密钥类型和密钥本身。



对于后端保管库(例如Vault服务器),在启动时仅加载密钥ID和密钥用户,因此获取所有密钥不会减慢启动速度。密钥延迟加载。也就是说,仅在实际需要时才从保险柜中加载密钥本身。密钥一旦加载,便会缓存在内存中,以便将来无需通过与Vault Server的TLS连接访问密钥。接下来,让我们看看密钥存储区中存在哪些信息。



关键信息包含以下内容:



  • 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, .


密钥由一对唯一标识:key_id,user。



密钥的存储和处置也有所不同。



文件存储速度更快。我们可以假设密钥存储是一次简单的一次将密钥写入文件的操作,但是没有-这里发生了更多的操作。对文件存储的任何修改将首先创建所有内容的备份。假设该文件名为my_biggest_secrets,则备份将为my_biggest_secrets.backup。接下来,更改缓存(添加或删除键),如果一切成功,则将缓存刷新到文件。在极少数情况下,例如服务器崩溃,您可能会看到此备份文件。下次加载密钥时(通常在服务器重启后),备份文件将被删除。



在服务器存储库中保存或删除密钥时,该存储库必须使用“发送密钥” /“请求密钥删除”命令连接到MySQL服务器。



让我们回到服务器的启动速度。除了存储本身会影响启动速度这一事实之外,还有一个问题,即在启动时需要从存储中获取多少个密钥。当然,这对于后端存储尤为重要。在启动时,服务器检查加密表/表空间需要哪个密钥,并从存储中请求密钥。在具有“主密钥-加密”的“干净”服务器上,必须有一个“主密钥”,必须从存储中检索该主密钥。但是,例如,在将备份从主服务器还原到备份服务器时,可能需要更多密钥。在这种情况下,应提供主密钥轮换。在以后的文章中将对此进行更详细的讨论,尽管在这里我想指出服务器,使用多个主密钥可能要花一点时间才能启动,尤其是在使用服务器端密钥存储时。



现在让我们更多地讨论keyring_file。在开发keyring_file时,我还担心如何在服务器运行时检查keyring_file的更改。在5.7中,该检查是基于文件统计信息执行的,这不是理想的解决方案,而在8.0中,它被SHA256校验和取代。



第一次运行keyring_file时,服务器将计算并记住文件统计信息和校验和,并且仅当它们匹配时才应用更改。更改文件后,校验和将更新。



我们已经讨论了有关密钥库的许多问题。但是,还有一个通常被忘记或误解的重要主题-跨服务器共享密钥。



我的意思是?群集中的每个服务器(例如,Percona服务器)必须在Vault服务器上具有一个单独的位置,Percona服务器必须在该位置存储其密钥。存储在库中的每个主密钥在其标识符中均包含Percona服务器的GUID。它为什么如此重要?假设您只有一个Vault服务器,并且群集中的所有Percona服务器都使用该单个Vault服务器。问题似乎很明显。如果所有Percona服务器都使用没有唯一标识符(例如,id = 1,id = 2等)的主密钥,则群集中的所有服务器都将使用相同的主密钥。这就是GUID提供的-服务器之间的区别。当唯一的GUID已经存在时,为什么还要谈论服务器之间的共享密钥呢?还有一个插件-keyring_udf。使用此插件,您的服务器用户可以将其密钥存储在Vault服务器上。当用户在例如server1上创建密钥,然后尝试在server2上创建具有相同ID的密钥时,就会发生此问题,例如:



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


等待。两台服务器都使用同一Vault服务器,在server2上keyring_key_store函数是否应该失败?有趣的是,如果尝试在同一台服务器上执行相同的操作,则会收到错误消息:



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


没错,ROB_1已经存在。



让我们首先讨论第二个例子。如前所述,keyring_vault或任何其他keyring插件将在内存中缓存所有密钥ID。因此,在创建新密钥之后,将ROB_1添加到server1,并且除了将该密钥发送到Vault之外,还将该密钥添加到缓存中。现在,当我们尝试第二次添加相同的密钥时,keyring_vault会检查此密钥在缓存中是否存在并引发错误。



在第一种情况下,情况有所不同。 Server1和server2具有单独的缓存。将ROB_1添加到server1和Vault上的密钥缓存后,server2上的密钥缓存不同步。 server2上的高速缓存中没有ROB_1密钥。因此,将ROB_1密钥写入keyring_key_store和Vault服务器,该服务器实际上会覆盖(!)先前的值。现在,保管库服务器上的密钥ROB_1为543210987654321。有趣的是,保管库服务器不会阻止此类操作,并且很容易覆盖旧值。



现在,我们可以看到为什么在Vault上的服务器之间进行拆分很重要的原因-当您使用keyring_udf并希望将密钥存储在Vault中时。您如何在Vault服务器上提供这种隔离?



有两种分割成保管库的方法。您可以为每个服务器创建不同的安装点,或在同一安装点内使用不同的路径。最好用示例说明。因此,让我们先看一下各个安装点:



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


在这里您可以看到server1和server2使用的挂载点不同。拆分路径时,配置如下所示:



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


在这种情况下,两个服务器都使用相同的mount_point,但是路径不同。当沿着此路径在server1上创建第一个机密时,Vault会自动创建“ server1”目录。对于server2,一切都相同。当您删除mount_point / server1或mount_point / server2中的最后一个机密时,Vault服务器还将删除这些目录。如果使用路径拆分,则只需创建一个安装点并更改配置文件,以便服务器使用单独的路径。可以使用HTTP请求创建安装点。使用CURL,可以这样完成:



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


所有字段(TOKEN,VAULT_CA,VAULT_URL,SECRET_MOUNT_POINT)都对应于配置文件中的参数。您当然可以使用Vault实用程序执行相同的操作。但这使自动创建挂载点变得更加容易。希望这些信息对您有所帮助,我们将在本系列的下一篇文章中与您联系。





阅读更多:






All Articles