mysql - MariaDB 通过 AWS KMS 插件进行静态加密 - 密钥轮换不起作用?
问题描述
我已通过AWS Key Management Service (KMS) Plugin设置MariaDB 进行静态加密。
除了关键的循环之外,一切似乎都有效。
我根据附加的配置文件配置了以下选项:
/etc/my.cnf
[mysqld]
# InnoDB/XtraDB Encryption
innodb_encrypt_tables = On
innodb_encrypt_log = On
innodb_encryption_threads = 8
innodb_encryption_rotate_key_age = 1
innodb_encryption_rotation_iops = 100
/etc/my.cnf.d/aws_key_management.cnf
[mariadb]
# Load the AWs plugin and enable it for use
plugin-load-add=aws_key_management.so
# Link to the AWS KMS 'Customer Master Key' used to decrypt MariaDB
encryption keys on disk
# during MariaDB start up and save the decrypted keys into memory
aws_key_management_master_key_id = alias/MariaDB-Encryption-Key
# Specify the AWS region our KMS key is stored in
aws_key_management_region = eu-west-2
# Specify the key specification
aws_key_management_key_spec = AES_256
# Rotate all keys
aws_key_management_rotate_key = -1
# Change the plugins log level
# Options: "Off" (default), "Fatal", "Error", "Warn", "Info",
"Debug", and "Trace".
aws_key_management_log_level = Warn
!include /etc/my.cnf.d/enable_encryption.preset
如您所见,我已将所有密钥设置为轮换 usingaws_key_management_rotate_key = -1
并将密钥年龄设置为 1 using innodb_encryption_rotate_key_age = 1
,但我可以从密钥/var/lib/mysql/
版本 1 中的密钥中看到,尽管这些设置已经实施了多天,但仍在使用:
/var/lib/mysql/aws-kms-key.1.1
/var/lib/mysql/aws-kms-key.2.1
(注:文件名最后的.n后缀代表密钥版本)
我唯一能想到的是,我对innodb_encryption_rotate_key_age
以天为单位的理解不正确?这个选项的文档可以在下面看到,并且根本没有提到这个数值使用的度量单位是什么?
innodb_encryption_rotate_key_age
描述:在后台重新加密密钥早于 >this 的任何页面。设置加密时,此变量必须设置为非零 > 值。否则,当您通过 innodb_encrypt_tables >MariaDB 启用加密时,MariaDB 将无法自动加密任何未加密的表。
谁能解释为什么会这样以及为什么我的钥匙不旋转?
MariaDB 版本
mysql --version
mysql Ver 15.1 Distrib 10.2.15-MariaDB, for Linux (x86_64) using readline 5.1`
AWS KMS 插件版本
yum list installed | grep mariadb
MariaDB-aws-key-management.x86_64 10.2.15-1.el7.centos @mariadb-main
解决方案
基本轮换
作为一种解决方法,您可以通过全局变量触发旋转。正如您所描述的,MariaDB 和/或插件似乎没有根据配置值采取任何行动。这样做的好处是您不必重新启动数据库。
- 不要忘记
aws_key_management_rotate_key
从配置中删除,因为您不需要它。 - 通过从控制台设置全局值来触发旋转。请注意,您不需要在旋转后手动将其重置为 0。该插件将报告生成一组新的数据键(版本)。
MariaDB [(none)]> SET @@GLOBAL.aws_key_management_rotate_key=-1;
Query OK, 0 rows affected, 4 warnings (0.875 sec)
MariaDB [(none)]> SELECT @@GLOBAL.aws_key_management_rotate_key;
+----------------------------------------+
| @@GLOBAL.aws_key_management_rotate_key |
+----------------------------------------+
| 0 |
+----------------------------------------+
1 row in set (0.000 sec)
MariaDB [(none)]> SHOW WARNINGS;
+-------+------+---------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------------------------+
| Note | 1105 | AWS KMS plugin: generated encrypted datakey for key id=1, version=2 |
| Note | 1105 | AWS KMS plugin: loaded key 1, version 2, key length 256 bit |
| Note | 1105 | AWS KMS plugin: generated encrypted datakey for key id=2, version=2 |
| Note | 1105 | AWS KMS plugin: loaded key 2, version 2, key length 256 bit |
+-------+------+---------------------------------------------------------------------+
4 rows in set (0.000 sec)
参考:https ://mariadb.com/kb/en/library/aws-key-management-encryption-plugin/#rotating-keys
问题 #1:允许版本老化
不幸的是,这还没有结束。版本 2 现在将默认用于加密新页面,但是使用之前版本加密的页面不会在后台重新加密,正如人们所期望的那样。这是由于设置innodb_encryption_rotate_key_age=0
禁用后台加密,而不是强制0
密钥版本年龄。因此,我们可以设置的最小年龄差距是1
,它允许使用以前的版本(在我的例子中是版本 1)进行 db 加密。
- 检查 innodb 表空间加密。MIN_KEY_VERSION 表示:
用于加密表空间中的页面的最小密钥版本。不同的页面可以使用不同的密钥版本进行加密。
MariaDB [test]> SELECT NAME, MIN_KEY_VERSION, CURRENT_KEY_VERSION, ROTATING_OR_FLUSHING FROM information_schema.INNODB_TABLESPACES_ENCRYPTION;
+----------------------------+-----------------+---------------------+----------------------+
| NAME | MIN_KEY_VERSION | CURRENT_KEY_VERSION | ROTATING_OR_FLUSHING |
+----------------------------+-----------------+---------------------+----------------------+
| innodb_system | 1 | 2 | 0 |
| mysql/gtid_slave_pos | 1 | 2 | 0 |
| mysql/innodb_index_stats | 1 | 2 | 0 |
| mysql/innodb_table_stats | 1 | 2 | 0 |
| mysql/transaction_registry | 1 | 2 | 0 |
| test/tbl | 1 | 2 | 0 |
+----------------------------+-----------------+---------------------+----------------------+
6 rows in set (0.000 sec)
- 再次重复第 2 步的轮换,至少有 MIN_KEY_VERSION
2
。这也意味着,您需要保留版本 2 和版本 3 的密钥。
参考:https ://mariadb.com/kb/en/library/information-schema-innodb_tablespaces_encryption-table/
问题 #2:重做日志
重做日志仍然使用以前的密钥版本加密,如果旧密钥丢失,MariaDB 将无法启动。
0 [ERROR] mysqld: can't open file aws-kms-key.1.1
0 [Warning] mysqld: AWS KMS plugin: key 1, version 1 could not be decrypted
0 [ERROR] InnoDB: Obtaining redo log encryption key version 1 failed (2385237688). Maybe the key or the required encryption key management plugin was not found.
...
0 [ERROR] InnoDB: No valid checkpoint found (corrupted redo log). You can try --innodb-force-recovery=6 as a last resort.
...
0 [ERROR] Unknown/unsupported storage engine: InnoDB
0 [ERROR] Aborting
仅 MariaDB 10.4.0 及更高版本支持 InnoDB 重做日志的密钥轮换。请参阅 MDEV-12041。
参考:https ://mariadb.com/kb/en/library/encrypting-data-for-innodb-xtradb/#key-rotation
推荐阅读
- jquery - 在 ASP.NET Core MVC 中访问从视图到控制器的隐藏值
- visual-studio - Visual Basic 2017 (WFA) 即时更改对象热键
- java - 如何在 IntelliJ 项目中使用 Jar 文件中的类?
- android - Android Appium 测试切换到 Web 上下文失败
- java - 将 Kotlin 方法传递给 `javax.script.ScriptEngine`
- javascript - Javascript类静态方法与函数
- ios - 如果表格视图单元格是自定义数据类型,如何实现 UISearchBar
- java - 具有多个包含的 XML 模式;在java中验证
- memory - 带有大文件的“文本文件输入”中的 Pentaho GC 开销
- javascript - Instagram 克隆错误:对象作为 React 子项无效