通过AWS KMS插件进行静态的MariaDB加密 - 密钥轮换不起作用?

时间:2018-06-11 08:48:03

标签: mysql encryption mariadb aws-kms key-management

我已通过MariaDB for encryption at rest设置了AWS Key Management Service (KMS) Plugin

除了关键骑行之外,一切似乎都有效。

我根据附加的配置文件配置了以下选项:

  

的/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

如您所见,我已使用aws_key_management_rotate_key = -1将所有键设置为轮播,并使用innodb_encryption_rotate_key_age = 1将关键年龄设置为1,但我可以从/var/lib/mysql/中的键中看到该版本尽管这些设置已经存在多天,但其中一个密钥仍在使用中:

/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

     

说明:在背景中重新加密任何密钥早于>这个的页面。设置加密时,必须将此变量设置为非零>值。否则,当您通过innodb_encrypt_tables启用加密> 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

1 个答案:

答案 0 :(得分:0)

基本旋转

作为一种解决方法,您可以通过全局变量触发旋转。正如您所描述的,MariaDB和/或插件似乎不根据配置值采取任何措施。这样做的好处是您不必重新启动数据库。

  1. 不要忘记从配置中删除aws_key_management_rotate_key,因为您将不需要它。
  2. 通过从控制台设置全局值来触发旋转。请注意,旋转后无需手动将其重置为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

Gotcha#1:允许版本老化

不幸的是,这还没有结束。现在,默认情况下将使用版本2来加密新页面,但是,与以前的版本一样,将不会在后台重新加密使用先前版本加密的页面。这是由于设置了innodb_encryption_rotate_key_age=0 禁用后台加密,而不是强制设置0密钥版本年龄。因此,我们可以设置的最小年龄间隔为1,这允许使用以前的版本(在我的情况下为版本1)对数据库进行加密。

  1. 检查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)
  1. 再次重复第2步的旋转,使MIN_KEY_VERSION至少为2。这也意味着,您将需要同时保留密钥的第2版和第3版。

参考:https://mariadb.com/kb/en/library/information-schema-innodb_tablespaces_encryption-table/

Gotcha#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