MariaDB's data-at-rest encryption requires the use of a key management and encryption plugin. These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.
MariaDB supports the use of multiple encryption keys. Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports key rotation, then encryption keys can also be rotated, which creates a new version of the encryption key.
How MariaDB manages encryption keys depends on which encryption key management solution you choose. Currently, MariaDB has three options:
The File Key Management plugin that ships with MariaDB is a basic key management and encryption plugin that reads keys from a plain-text file. It can also serve as an example and as a starting point when developing a key management plugin.
For more information, see .
Integrates MariaDB encryption with Vault for secure key management.
For more information, refer to the .
The AWS Key Management plugin is a key management and encryption plugin that uses the Amazon Web Services (AWS) Key Management Service (KMS). The AWS Key Management plugin depends on the , which uses the . The license is not compatible with MariaDB Server's , so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from the source.
For more information, see .
Key management and encryption plugins support using multiple encryption keys. Each encryption key can be defined with a different 32-bit integer as a key identifier.
The support for multiple keys opens up some potential use cases. For example, let's say that a hypothetical key management and encryption plugin is configured to provide two encryption keys. One encryption key might be intended for "low security" tables. It could use short keys, which might not be rotated, and data could be encrypted with a fast encryption algorithm. Another encryption key might be intended for "high security" tables. It could use long keys, which are rotated often, and data could be encrypted with a slower but more secure encryption algorithm. The user would specify the identifier of the key that they want to use for different tables, only using high-level security where it's needed.
There are two encryption key identifiers that have special meanings in MariaDB. An encryption key 1 is intended for encrypting system data, such as InnoDB redo logs, binary logs, and so on. It must always exist when is enabled. An encryption key 2 is intended for encrypting temporary data, such as temporary files and temporary tables. It is optional. If it doesn't exist, then MariaDB uses an encryption key 1 for these purposes instead.
When , the key that is used to encrypt tables .
When , the key that is used to encrypt tables .
Encryption key rotation is optional in MariaDB Server. Key rotation is only supported if the backend key management service (KMS) supports key rotation and if the corresponding key management and encryption plugin for MariaDB also supports key rotation. When a key management and encryption plugin supports key rotation, users can opt to rotate one or more encryption keys, which creates a new version of each rotated encryption key.
Key rotation allows users to improve data security in the following ways:
If the server is configured to automatically re-encrypt table data with the newer version of the encryption key after the key is rotated, then that prevents an encryption key from being used for long periods of time.
If the server is configured to simultaneously encrypt table data with multiple versions of the encryption key after the key is rotated, then that prevents all data from being leaked if a single encryption key version is compromised.
The has that can .
The does .
The supports encryption key rotation, and the corresponding also supports encryption key rotation.
HashiCorp Key Management Plugin: The HashiCorp Key Management Plugin integrates MariaDB with for centralized encryption key storage and lifecycle management. environments.
The does not support encryption key rotation because it does not use a backend key management service (KMS).
New key management and encryption plugins can be developed using the .
This page is licensed: CC BY-SA / Gnu FDL
File-based key management
Supported
Supported from MariaDB Enterprise Server 11.8
Simple but lacks rotation
HashiCorp Vault plugin
Supported, Recommended
Yes
Best for secure, scalable deployments
The Hashicorp Key Management Pugin is used to implement encryption using keys stored in the Hashicorp Vault KMS. For more information, see Hashicorp Vault and MariaDB, and for how to install Vault, see Install Vault, as well as MySQL/MariaDB Database Secrets Engine.
The current version of this plugin implements the following features:
Authentication is done using the Hashicorp Vault's token authentication method.
If additional client authentication is required, then the path to the CA authentication bundle file may be passed as a plugin parameter;
The creation of the keys and their management is carried out using the Hashicorp Vault KMS and their tools.
The plugin uses libcurl (https) as an interface to the HashiCorp Vault server;
JSON parsing is performed through the JSON service (through the include/mysql/service_json.h);
HashiCorp Vault 1.2.4 was used for development and testing.
As of MariaDB 10.6.24, the plugin is configured to use cached keys for all communication errors, not just for timeouts. This ensures continuous operation when the Vault server is temporarily unreachable.
As of MariaDB 10.6.24, the default setting for cache usage on error is ON.
Since we require support for key versioning, the key-value storage must be configured in Hashicorp Vault as a key-value storage that uses the interface of the second version. For example, you can create it as follows:
Key names must correspond to their numerical identifiers. Key identifiers itself, their possible values and rules of use are described in more detail in the MariaDB main documentation.
From the point of view of the key-value storage (in terms of Hashicorp Vault), the key is a secret containing one key-value pair with the name "data" and a value representing a binary string containing the key value, for example:
Keys values are strings containing binary data. MariaDB currently uses the AES algorithm with 256-bit keys as the default encryption method. In this case, the keys that will be stored in the Hashicorp Vault should be 32-byte strings. Most likely you will use some utilities for creating and administering keys designed to work with Hashicorp Vault. But in the simplest case, keys can be created from the command line through the vault utility, for example, as follows:
If you use default encryption (AES), you should ensure that the key length is 32 bytes, otherwise it may fail to use InnoDB as a data storage.
The plugin currently does not unseal Hashicorp Vault on its own, you must do this in advance and on your own.
To use Hashicorp Vault KMS, the plugin must be preloaded and activated on the server. Most of its parameters should not be changed during plugin operation and therefore must be preconfigured as part of the server configuration through configuration file or command line options:
The plugin supports the following parameters, which must be set in advance and cannot be changed during server operation:
hashicorp-key-management-vault-urlDescription: HTTP[s] URL that is used to connect to the Hashicorp Vault server. It must include the name of the scheme (https:// for a secure connection) and, according to the API rules for storages of the key-value type in Hashicorp Vault, after the server address, the path must begin with the "/v1/" string (as prefix), for example: https://127.0.0.1:8200/v1/my_secrets. By default, the path is not set, therefore you must replace with the correct path to your secrets.
Command line: --[loose-]hashicorp-key-management-vault-url="<url>"
hashicorp-key-management-tokenDescription: Authentication token that passed to the Hashicorp Vault in the request header. By default, this parameter contains an empty string, so you must specify the correct value for it, otherwise the Hashicorp Vault server will refuse authorization. Alternatively, you can define an environment variable VAULT_TOKEN and store the token there.
Command line: --[loose-]hashicorp-key-management-token="<token>"
hashicorp-key-management-vault-caDescription: Path to the Certificate Authority (CA) bundle (is a file that contains root and intermediate certificates). By default, this parameter contains an empty string, which means no CA bundle.
Command line: --[loose-]hashicorp-key-management-vault-ca="<path>"
hashicorp-key-management-timeoutDescription: Set the duration (in seconds) for the Hashicorp Vault server connection timeout. The default value is 15 seconds. The allowed range is from 1 to 86400 seconds. The user can also specify a zero value, which means the default timeout value set by the libcurl library (currently 300 seconds).
Command line: --[loose-]hashicorp-key-management-timeout=<timeout>
hashicorp-key-management-max-retriesDescription: Number of server request retries in case of timeout. Default is three retries.
Command line: ----[loose-]hashicorp-key-management-max-retries=<retries>
hashicorp-key-management-caching-enabledDescription: Enable key caching (storing key values received from the Hashicorp Vault server in the local memory). By default caching is enabled.
Command line: --[loose-]hashicorp-key-management-caching-enabled="on"|"off"
hashicorp-key-management-use-cache-on-timeoutDescription: This parameter instructs the plugin to use the key values or version numbers taken from the cache in the event of a timeout when accessing the vault server. By default this option is disabled. Please note that key values or version numbers will be read from the cache when the timeout expires only after the number of attempts to read them from the storage server that specified by the parameter has been exhausted.
Command line: --[loose-]hashicorp-key-management-use-cache-on-timeout="on"|"off"
hashicorp-key-management-cache-timeoutDescription: The time (in milliseconds) after which the value of the key stored in the cache becomes invalid and an attempt to read this data causes a new request send to the vault server. By default, cache entries become invalid after 60,000 milliseconds (after one minute). If the value of this parameter is zero, then the keys will always be considered invalid, but they still can be used if the vault server is unavailable and the corresponding cache operating mode (--[loose-]hashicorp-key-management-use-cache-on-timeout="on") is enabled.
As of MariaDB 10.6.24, the default value is 1 year (specified in milliseconds).
Command line: --[loose-]hashicorp-key-management-cache-timeout=<timeout>
hashicorp-key-management-cache-version-timeoutDescription: The time (in milliseconds) after which the information about latest version number of the key (which stored in the cache) becomes invalid and an attempt to read this information causes a new request send to the vault server. If the value of this parameter is zero, then information about latest key version numbers always considered invalid, unless there is no communication with the vault server and use of the cache is allowed when the server is unavailable. By default, this parameter is zero, that is, the latest version numbers for the keys stored in the cache are considered always invalid, except when the vault server is unavailable and use of the cache is allowed on server failures.
Command line: --[loose-]hashicorp-key-management-cache-version-timeout=<timeout>
hashicorp-key-management-check-kv-versionDescription: This parameter enables ("on", this is the default value) or disables ("off") checking the kv storage version during plugin initialization. The plugin requires storage to be version 2 or older in order for it to work properly.
Command line: --[loose-]hashicorp-key-management-check-kv-version="on"|"off"
Available as of MariaDB 12.3
The HashiCorp Key Management plugin supports key versioning provided by the HashiCorp Vault Server. In previous versions, rotating keys required a server restart to clear the internal cache. As of MariaDB 12.3, you can flush the plugin cache manually while the server is running.
To rotate keys, you must flush the cached keys using the FLUSH command. This clears the local cache, forcing the server to re-fetch the latest key versions from the HashiCorp Vault server upon the next access.
Executing this command requires the RELOAD privilege.
To view the current Key IDs and Key Versions stored in the latest version cache, you can query the Information Schema table or use the SHOW command.
See for table details.
Using the SHOW command:
This page is licensed: CC BY-SA / Gnu FDL
Explore key management and encryption plugins for MariaDB Server. This section details how to manage encryption keys and leverage plugins for robust data-at-rest protection.
~$ vault secrets enable -path /test -version=2 kv~$ vault kv get /test/1
====== Metadata ======
Key Value
--- -----
created_time 2019-12-14T14:19:19.42432951Z
deletion_time n/a
destroyed false
version 1
==== Data ====
Key Value
--- -----
data 0123456789ABCDEF0123456789ABCDEF~$ vault kv put /test/1 data="0123456789ABCDEF0123456789ABCDEF"--plugin-load-add=hashicorp_key_management.so
--loose-hashicorp-key-management
--loose-hashicorp-key-management-vault-url="$VAULT_ADDR/v1/test"
--loose-hashicorp-key-management-token="$VAULT_TOKEN"FLUSH HASHICORP_KEY_MANAGEMENT_CACHE;SHOW HASHICORP_KEY_MANAGEMENT_CACHE;MariaDB contains a robust, full instance, at-rest encryption. This feature uses a flexible plugin interface to allow actual encryption to be done using a key management approach that meets the customer's needs. MariaDB Server includes a plugin that uses the Amazon Web Services (AWS) Key Management Service (KMS) to facilitate separation of responsibilities and remote logging & auditing of key access requests.
Rather than storing the encryption key in a local file, this plugin keeps the master key in AWS KMS. When you first start MariaDB, the AWS KMS plugin will connect to the AWS Key Management Service and ask it to generate a new key. MariaDB will store that key on-disk in an encrypted form. The key stored on-disk cannot be used to decrypt the data; rather, on each startup, MariaDB connects to AWS KMS and has the service decrypt the locally-stored key(s). The decrypted key is stored in-memory as long as the MariaDB server process is running, and that in-memory decrypted key is used to encrypt the local data.
This guide is based on CentOS 7, using systemd with SELinux enabled. Some steps will differ if you use other operating systems or configurations.
The AWS Key Management plugin depends on the , which uses the . This license is not compatible with MariaDB Server's , so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from source.
When , the AWS Key Management plugin is built by default on systems that support it.
Compilation is controlled by the -DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC -DAWS_SDK_EXTERNAL_PROJECT=1 arguments.
The plugin uses , which introduces the following restrictions:
The plugin can only be built on Windows, Linux, and macOS.
The plugin requires that one of the following compilers is used: gcc 4.8 or later, clang 3.3 or later, or Visual Studio 2013 or later.
On Unix, the libcurl development package (e.g., libcurl3-dev on Debian Jessie), the uuid
Even after the package that contains the plugin's shared library is installed on the operating system, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.
The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing or . For example:
The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the or the options. This can be specified as a command-line argument to , or it can be specified in a relevant server in an . For example:
If you already have an AWS account, you can skip this section.
Load.
Click "Create a Free Account" and complete the steps.
You'll need to enter credit card information. Charges related only to your use of the AWS KMS service should be limited to about $1/month for the single master key we will create. If you use other services, additional charges may apply. Consult AWS Cloud Pricing Principles for more information about the pricing of AWS services.
You'll need to complete the AWS identity verification process.
After creating an account or logging in to an existing account, follow these steps to create an IAM User or Role with restricted privileges that will use (but not administer) your master encryption key.
If you intend to run MariaDB Server on an EC2 instance, you should create a Role (or modify an existing Role already attached to your instance). If you intend to run MariaDB Server outside of AWS, you may want to create a User.
Load the Identity and Access Management Console at.
Click "Roles" in the left-hand sidebar
Click "Create new role"
Select "AWS Service Role"
Load the Identity and Access Management Console at.
Click "Users" in the left-hand sidebar.
Click the "Create New Users" button
Enter a single User Name of your choosing. We'll use "MDBEnc" for this demonstration. Keep the "Generate an access key for each user" box checked.
Click "Close". If prompted because you did not Download Credentials, ensure that you've saved them somewhere, and click "Close".
Now, we'll create a master encryption key. This key can never be retrieved by any application or user. This key is used remotely to encrypt (and decrypt) the actual encryption keys that will be used by MariaDB. If this key is deleted or you lose access to it, you will be unable to use the contents of your MariaDB data directory.
Click "Encryption Keys" in the left-hand sidebar.
Click the "Get Started Now" button.
Use the "Filter" dropdown to choose the region where you'd like to create your master key.
Click the "Create Key" button.
You should now see your key listed in the console:
You'll use the "Alias" you provided when you configure MariaDB later.
We now have a Customer Master Key and an IAM user that has privileges to access it using access credentials. This is enough to begin using the AWS KMS plugin.
There are a number of ways to give the IAM credentials to the AWS KMS plugin. The plugin supports reading credentials from all standard locations used across the various AWS API clients.
The easiest approach is to run MariaDB Server in an EC2 instance that has an IAM Role with User access to the CMK you wish to use. You can give key access privileges to a Role already attached to your EC2 instance, or you can create a new IAM Role and attach it to an already-running EC2 instance. If you've done that, no further credentials management is required, and you do not need to create a credentials file.
If you're not running MariaDB Server on an EC2 instance, you can also place the credentials in the MariaDB data directory. The AWS API client looks for a credentials file in the .aws subdirectory of the home directory of the user running the client process. In the case of MariaDB, its home directory is its datadir.
Create a credentials file that MariaDB can read. Use the region you selected when creating the key. Master keys cannot be used across regions. For example:
Change the permissions of the file so that it is owned by, and can only be read by, the mysql user:
Create a new option file to tell MariaDB to enable encryption functionality and to use the AWS KMS plugin. Create a new file under /etc/my.cnf.d/ (or wherever your OS may have you create such files) with contents like this:
Append the "Alias" value you copied above to alias/ to use as the value for the aws-key-management-master-key-id option.
Note that you must include aws-key-management-region in your .cnf file if you are not using the us-east-1 region.
Now, you have told MariaDB to use the AWS KMS plugin, and you've put credentials for the plugin in a location where the plugin will find them. The /etc/my.cnf.d/enable_encryption.preset file contains a set of options that enable all available encryption functionality.
When you start MariaDB, the AWS KMS plugin will connect to the AWS Key Management Service and ask it to generate a new key. MariaDB will store that key on-disk in an encrypted form. The key stored on-disk cannot be used to decrypt the data; rather, on each startup, MariaDB must connect to AWS KMS and have the service decrypt the locally-stored key. The decrypted version is stored in-memory as long as the MariaDB server process is running, and that in-memory decrypted key is used to encrypt the local data.
Because MariaDB needs to connect to the AWS KMS service, you must ensure that the host has outbound network connectivity over port 443 to AWS, and you must ensure that local policies allow the MariaDB server process to make those outbound connections. By default, SELinux restricts MariaDB from making such connections.
The most simple way to cause SELinux to allow outbound HTTPS connections from MariaDB is to enable to mysql_connect_any boolean, like this:
There are more complex alternatives that have a more granular effect, but those are beyond the scope of this document.
Start MariaDB using the systemctl tool:
If you do not use systemd, you may have to start MariaDB using some other mechanism.
You should see journal output similar to this:
Note the several lines of output that refer explicitly to the "AWS KMS plugin". You can see that the plugin generates a "datakey", loads that data key, and then later generates and loads a second data key. The 2nd data key is used to encrypt temporary files and temporary tables.
You can see the encrypted keys stored on-disk in the datadir:
Note that those keys are not useful alone. They are encrypted. When MariaDB starts up, the AWS KMS plugin decrypts those keys by interacting with AWS KMS.
For maximum security, you should start from an empty datadir and run after configuring encryption. Then you should re-import your data so that it is fully encrypted. Use sudo to run mariadb-install-db so that it finds your credentials file:
With innodb-encrypt-tables=ON, new InnoDB tables will be encrypted by default, using the key ID set in innodb_default_encryption_key_id (default 1). With innodb-encrypt-tables=FORCE enabled, it is not possible to manually bypass encryption when creating a table.
You can cause the AWS KMS plugin to create new encryption keys at-will by specifying a new ENCRYPTION_KEY_ID when creating a table:
Read more about encrypting data in the section of the MariaDB Documentation.
aws_key_management_master_key_id: AWS KMS Customer Master Key ID (ARN or alias prefixed by alias/) for master encryption key. Used to create new data keys. If not set, no new data keys will be created.
aws_key_management_rotate_key: Set this variable to a data key ID to perform rotation of the key to the master key given in aws_key_management_master_key_id. Specify -1 to rotate all keys.
aws_key_management_key_spec
For more information about advanced usage, including strategies to manage credentials, enforce separation of responsibilities, and even require 2-factor authentication to start your MariaDB server, please review .
This page is licensed: CC BY-SA / Gnu FDL
opensslYou may need to use a newer version of cmake than is provided by default in your OS.
Do not select any policies on the "Attach Policy" screen. Click "Next Step"
Click "Next Step"
Give your Role a "Role name"
Click "Create role"
Click "Create".
Click "Show User Security Credentials".
Copy the Access Key ID and Secret Access Key. Optionally, you can click "Download Credentials". We will need these in order for local programs to interact with AWS using its API.
Create a file on your computer to hold the credentials for this user. We'll use this file later. It should have this structure:
Click "Next Step".
Do not check the box to make your IAM Role or IAM User a Key Administrator.
Click "Next Step" again.
Check the boxes to give your IAM Role and/or IAM User permissions to use this key.
Click "Next Step".
Click "Finish".
aws_key_management_log_level: Logging for AWS API. Allowed values, in increasing verbosity, are "Off" (default), "Fatal", "Error", "Warn", "Info", "Debug", and "Trace".
INSTALL SONAME 'aws_key_management';[mariadb]
...
plugin_load_add = aws_key_management[default]
aws_access_key_id = AKIAIG6IZ6TKF52FVV5A
aws_secret_access_key = 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$ cat /var/lib/mysql/.aws/credentials
[default]
aws_access_key_id = AKIAIG6IZ6TKF52FVV5A
aws_secret_access_key = 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
region = us-east-1chown mysql /var/lib/mysql/.aws/credentials
chmod 600 /var/lib/mysql/.aws/credentials[mariadb]
plugin_load_add = aws_key_management
aws-key-management = FORCE_PLUS_PERMANENT
aws-key-management-master-key-id = alias/mariadb-encryption
aws-key-management-region = us-east-1
!include /etc/my.cnf.d/enable_encryption.presetsetsebool -P mysql_connect_any 1systemctl start mariadb# journalctl --no-pager -o cat -u mariadb.service
[Note] /usr/sbin/mysqld (mysqld 10.1.9-MariaDB-enterprise-log) starting as process 19831 ...
[Note] AWS KMS plugin: generated encrypted datakey for key id=1, version=1
[Note] AWS KMS plugin: loaded key 1, version 1, key length 128 bit
[Note] InnoDB: Using mutexes to ref count buffer pool pages
[Note] InnoDB: The InnoDB memory heap is disabled
[Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
[Note] InnoDB: Memory barrier is not used
[Note] InnoDB: Compressed tables use zlib 1.2.7
[Note] InnoDB: Using CPU crc32 instructions
[Note] InnoDB: Initializing buffer pool, size = 2.0G
[Note] InnoDB: Completed initialization of buffer pool
[Note] InnoDB: Highest supported file format is Barracuda.
[Note] InnoDB: 128 rollback segment(s) are active.
[Note] InnoDB: Waiting for purge to start
[Note] InnoDB: Percona XtraDB (http://www.percona.com) 5.6.26-74.0 started; log sequence number 1616819
[Note] InnoDB: Dumping buffer pool(s) not yet started
[Note] Plugin 'FEEDBACK' is disabled.
[Note] AWS KMS plugin: generated encrypted datakey for key id=2, version=1
[Note] AWS KMS plugin: loaded key 2, version 1, key length 128 bit
[Note] Using encryption key id 2 for temporary files
[Note] Server socket created on IP: '::'.
[Note] Reading of all Master_info entries succeded
[Note] Added new Master_info '' to hash table
[Note] /usr/sbin/mysqld: ready for connections.# ls -l /var/lib/mysql/aws*
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.1.1
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.2.1# sudo -u mysql mariadb-install-db
Installing MariaDB/MySQL system tables in '/var/lib/mysql' ...
2016-02-25 23:16:06 139731553998976 [Note] /usr/sbin/mysqld (mysqld 10.1.11-MariaDB-enterprise-log) starting as process 39551 ...
2016-02-25 23:16:07 139731553998976 [Note] AWS KMS plugin: generated encrypted datakey for key id=1, version=1
2016-02-25 23:16:07 139731553998976 [Note] AWS KMS plugin: loaded key 1, version 1, key length 128 bit
...MariaDB [test]> CREATE TABLE t1 (id serial, v VARCHAR(32)) ENCRYPTION_KEY_ID=3;
Query OK, 0 rows affected (0.91 sec)[Note] AWS KMS plugin: generated encrypted datakey for key id=3, version=1
[Note] AWS KMS plugin: loaded key 3, version 1, key length 128 bit# ls -l /var/lib/mysql/aws*
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.1.1
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.2.1
-rw-rw----. 1 mysql mysql 188 Feb 25 19:10 /var/lib/mysql/aws-kms-key.3.1Due to license incompatibilities between the MariaDB server source code and the Amazon AWS C++ SDK, we can only distribute the plugin in source code form, and not as ready-to-use binaries. See Installing the Plugin's Package for details.
MariaDB's data-at-rest encryption requires the use of a key management and encryption plugin. These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.
MariaDB supports the use of multiple encryption keys. Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports key rotation, then encryption keys can also be rotated, which creates a new version of the encryption key.
The AWS Key Management plugin is a key management and encryption plugin that uses the Amazon Web Services (AWS) Key Management Service (KMS).
The AWS Key Management plugin uses the to generate and store AES keys on disk, in encrypted form, using the Customer Master Key (CMK) kept in AWS KMS. When MariaDB Server starts, the plugin will decrypt the encrypted keys, using the AWS KMS "Decrypt" API function. MariaDB data will then be encrypted and decrypted using the AES key. It supports multiple encryption keys. It supports key rotation.
Tutorials related to the AWS Key Management plugin can be found at the following pages:
Before you use the plugin, you need to create a Customer Master Key (CMK). Create a key using the AWS Console as described in the .
The easiest way to give the AWS key management plugin access to the key is to create an IAM Role with access to the key, and to apply that IAM Role to an EC2 instance where MariaDB Server runs.
Make sure that MariaDB Server runs under the correct AWS identity that has access to the above key. For example, you can store the AWS credentials in an AWS credentials file for the user who runs mysqld. More information about the credentials file can be found in .
The AWS Key Management plugin depends on the , which uses the . This license is not compatible with MariaDB Server's , so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from source.
When , the AWS Key Management plugin is built by default, on systems that support it.
Compilation is controlled by the following arguments:
-DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC to build a loadable plugin library
-DAWS_SDK_EXTERNAL_PROJECT=ON to download the AWS C++ SDK code
-DNOT_FOR_DISTRIBUTION=ON to confirm that you know to not distribute the resulting binaries
The plugin uses , which introduces the following restrictions:
The plugin can only be built on Windows, Linux, and macOS.
The plugin requires that one of the following compilers is used: gcc 4.8 or later, clang 3.3 or later, Visual Studio 2013 or later.
On Unix, the libcurl development package (e.g. libcurl3-dev on Debian Jessie), uuid
You do not need to download/install the AWS C++ SDK yourself; the correct version of the SDK GitHub repository will be cloned into the build directory at build time, and only the libraries for AWS components actually needed by the key management plugin will be built, which takes much less time than building the full AWS C++ SDK.
With all prerequisites installed, the actual build process pretty much comes down to:
Cmake will print the following warning as part of its output. Please take it seriously and do not distribute the aws_key_management.so file to any third parties: You have linked MariaDB with Apache 2.0 libraries! You may not distribute the resulting binary. If you do, you will put yourself into a legal problem with the Free Software Foundation.
After make succeeded you can copy the created aws_key_management.so plugin library file to the plugin directory of your actual MariaDB Server machines installation, e.g. /usr/lib64/mysql/plugin on RedHat/Fedora based systems or /usr/lib/mysql/plugin on Debian-based systems.
Even after the package that contains the plugin's shared library is installed on the operating system, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.
The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing or . For example:
The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the or the options. This can be specified as a command-line argument to or it can be specified in a relevant server in an . For example:
Before you uninstall the plugin, you should ensure that is completely disabled, and that MariaDB no longer needs the plugin to decrypt tables or other files.
You can uninstall the plugin dynamically by executing or . For example:
If you installed the plugin by providing the or the options in a relevant server in an , then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.
To enable the AWS Key Management plugin, you also need to set the plugin's system variables. The system variable is the primary one to set. These system variables can be specified as command-line arguments to or they can be specified in a relevant server in an . For example:
Once you've updated the configuration file, restart the MariaDB server to apply the changes and make the key management and encryption plugin available for use.
Once the AWS Key Management Plugin is enabled, you can use it by creating an encrypted table:
Now, table t will be encrypted using the encryption key generated by AWS.
For more information on how to use encryption, see .
The AWS Key Management Plugin supports . Each encryption key can be defined with a different 32-bit integer as a key identifier. If a previously unused identifier is used, then the plugin will automatically generate a new key.
When , the key that is used to encrypt tables .
When , the key that is used to encrypt tables .
The AWS Key Management plugin does support . To rotate a key, set the system variable. For example, to rotate key with ID 2:
Or to rotate all keys, set the value to -1:
aws_key_management_key_specDescription: Encryption algorithm used to create new keys
Commandline: --aws-key-management-key-spec=value
Scope: Global
Dynamic: No
aws_key_management_log_levelDescription: Dump log of the AWS SDK to MariaDB error log. Permitted values, in increasing verbosity, are Off (default), Fatal, Error, Warn, Info, Debug, and Trace.
Commandline: --aws-key-management-log-level=value
Scope: Global
Dynamic: No
aws_key_management_master_key_idDescription: AWS KMS Customer Master Key ID (ARN or alias prefixed by alias/) for the master encryption key. Used to create new data keys. If not set, no new data keys will be created.
Commandline: --aws-key-management-master-key-id=value
Scope: Global
Dynamic: No
aws_key_management_mockDescription: Mock AWS KMS calls (for testing). Must be enabled at compile-time.
Commandline: --aws-key-management-mock
Scope: Global
Dynamic: No
aws_key_management_regionDescription: AWS region name, e.g us-east-1 . Default is SDK default, which is us-east-1.
Commandline: --aws-key-management-region=value
Scope: Global
Dynamic: No
aws_key_management_request_timeoutDescription: Timeout in milliseconds for create HTTPS connection or execute AWS request. Specify 0 to use SDK default.
Commandline: --aws-key-management-request-timeout=value
Scope: Global
Dynamic: No
aws_key_management_rotate_keyDescription: Set this variable to a data key ID to perform rotation of the key to the master key given in aws_key_management_master_key_id. Specify -1 to rotate all keys.
Commandline: --aws-key-management-rotate-key=value
Scope: Global
aws_key_managementDescription: Controls how the server should treat the plugin when the server starts up.
Valid values are:
OFF - Disables the plugin without removing it from the table.
This page is licensed: CC BY-SA / Gnu FDL
opensslYou may need to use a newer version of cmake than is provided by default in your OS.
Data Type: enumerated
Default Value: AES_128
Valid Values: AES_128, AES_256
Data Type: enumerated
Default Value: Off
Valid Values: Off, Fatal, Warn, Info, Debug and Trace
Data Type: string
Default Value:
Data Type: boolean
Default Value: OFF
Valid Values: OFF, ON
Data Type: string
Default Value: 'us-east-1'
Data Type: integer
Default Value: 0
Data Type: integer
Default Value:
ON - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.FORCE - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
FORCE_PLUS_PERMANENT - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with UNINSTALL SONAME or UNINSTALL PLUGIN while the server is running.
See Plugin Overview: Configuring Plugin Activation at Server Startup for more information.
Commandline: --aws-key-management=value
Data Type: enumerated
Default Value: ON
Valid Values: OFF, ON, FORCE, FORCE_PLUS_PERMANENT
1.0
Stable
,
1.0
Beta
1.0
Experimental
# clone the MariaDB Server source code repository
git clone https://github.com/MariaDB/server.git
cd server
# prepare the build
mkdir _build
cd _build
cmake .. -DNOT_FOR_DISTRIBUTION=ON \
-DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC \
-DAWS_SDK_EXTERNAL_PROJECT=1
# build the plugin only
cd plugin/aws_key_management
makeINSTALL SONAME 'aws_key_management';[mariadb]
...
plugin_load_add = aws_key_managementUNINSTALL SONAME 'aws_key_management';[mariadb]
...
aws_key_management_master_key_id=alias/<your key's alias>CREATE TABLE t (i INT) ENGINE=InnoDB ENCRYPTED=YESSET GLOBAL aws_key_management_rotate_key=2;SET GLOBAL aws_key_management_rotate_key=-1;This document assumes you've already set up an Amazon Web Services (AWS) account, created a master key in the Key Management Service (KMS), and have done the basic work to set up the MariaDB AWS KMS plugin. These steps are all described in Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide.
Ultimately, keeping all the credentials required to read the key on a single host means that a user who has gained access to the host has enough information to read the encrypted files in the datadir, read the encrypted keys from the datadir, interact with AWS KMS to decrypt the encrypted keys, and then used the decrypted keys to decrypt the encrypted data.
Theoretically, a superuser can read the memory of the MariaDB server process to read the decrypted keys or restart MariaDB with password authentication disabled in order to dump data, or add new users to MariaDB in order to allow a user to connect and dump the data. Resolving these issues is beyond the scope of this document. A user who gains root access to your operating system or root access to your MariaDB server will have the ability to decrypt your data. Plan accordingly.
Putting the AWS credentials in a file inside the MariaDB home directory is not ideal. By default, any user with the FILE privilege can read any files that the MariaDB server has permission to read, which would include the credentials file. To protect against this, you should set secure_file_priv to restrict the location the server will allow a user to read from when executing LOAD DATA INFILE or the LOAD_FILE() function.
But putting them in other locations requires passing additional data to the server, which in the case of CentOS 7 requires customizing the systemd startup procedure. This is most easily done by creating a "drop-in" file in /etc/systemd/system/mariadb.service.d/. The file should end in ".conf" but can otherwise be named whatever you like. After making any changes to systemd files, execute systemctl daemon-reload and then start (or restart) the service as usual.
You can place the credentials file in a location of your choosing and then refer to that file by setting the AWS_CREDENTIAL_PROFILES_FILE environment variable in the drop-in file:
The credentials file will need to be readable by the "mysql" user, but it does not need to be readable by any other user.
AWS credentials can also be put directly into a "drop-in" systemd file that will be read when starting the MariaDB service:
However, any OS user can read this information from systemd, which could be considered a security risk. Another solution is to put the credentials in a separate file that is only readable by root and then refer to that file using an EnvironmentFile directive in a drop-in systemd file.
That has the advantage the credentials can only be read directly by root. systemd adds those variables to the environment of the MariaDB server when starting it, and MariaDB can use the credentials to interact with AWS. Note, though, that any process running as the "mysql" user can still read the credentials from the proc filesystem on Linux.
AWS KMS allows flexible, user-editable key policy. This offers fine-grained control over which users can operate on keys. The possibilities range from simply restricting which IP addresses are allowed to perform operations on the key, to requiring a MFA (Multi-Factor Authentication) device to use the key, to enforcing separation of responsibilities by creating an additional user with limited privileges to enable and disable the key. All 3 of these options will be outlined in this section.
For more details about customizing the Key Policy for your master keys, please consult the documentation.
A simple, common-sense restriction to put in place is to restrict the range of IP addresses that are allowed to use your master key. This way, even if someone obtains API credentials, they'll be unable to use them to decrypt your encryptions keys from a different host.
To restrict API access from only a specific IP address or range of IP addresses, you'll need to manually edit the key policy.
Load the IAM console at.
Click "Encryption Keys" in the left-hand sidebar.
Click the name of your encryption key to view its details.
Click the link labeled "Switch to policy view", to the right of the heading of the "Key Policy" section.
... replacing 10.1.2.3/32 above with an IP address or range of IP addresses in CIDR format. For example, a single address would be 192.168.12.34/32, while a range of addresses might be 192.168.0.0/24.
Click "Save Changes".
Click "Proceed" if prompted with a warning about using the default view in the future.
Access to the API will now be restricted to requests coming from the IP address or range of IP addresses specified in the policy.
One approach is to modify the key policy for the master key so that MFA (Multi-Factor Authentication) is required in order to use the key. This is achieved with a wrapper that handles prompting the user for an MFA token, acquires temporary, limited-privilege credentials from the AWS Security Token Service (STS), and puts those credentials into the environment of the MariaDB server process. The credentials can expire after as little as 15 minutes.
To require an MFA token for users of the key, you'll need to manually edit the key policy.
Load the IAM console at.
Click "Encryption Keys" in the left-hand sidebar.
Click the name of your encryption key to view its details.
Click the link labeled "Switch to policy view", to the right of the heading of the "Key Policy" section.
Click "Save Changes".
Click "Proceed" if prompted with a warning about using the default view in the future.
Now, add an MFA device for your user. You'll need to have a hardware MFA device or an application such as Google Authenticator installed on your smartphone.
Click "Users" in the left-hand sidebar.
Click the name of your user.
Click the "Security Credentials" tab.
In the "Sign-In Credentials" section, click the "Manage MFA Device" button.
Now, set up the wrapper program.
Copy the iam-kms-wrapper file to /usr/local/bin/, and ensure that it is executable.
Create a drop-in systemd config file in /etc/systemd/system/mariadb.service.d/:
Execute systemctl daemon-reload.
Create a file at /etc/my.cnf.d/iam-kms-wrapper.config with these contents, using the ARN for your MFA device as the value for kms_mfa_id:
When you start the MariaDB service now, the wrapper will temporarily create a socket file at the location given by the kms_mfa_socket option. The wrapper will read the MFA code from the socket and will use it to authenticate to KMS. To give the MFA code, simply write the digits to the socket file using echo: echo 111676 > /tmp/kms_mfa_socket.
The systemctl command will block until MariaDB starts, so you will need to write the code to the socket file via a separate terminal.
Note that the temporary credentials put into the environment of the MariaDB process will expire after a period of time defined by the request to the AWS Security Token Service (STS). In the example below, they will expire after 900 seconds. After that time, MariaDB may be unable to generate new encrypted data keys, which means that, for example, an attempt to create a table with a previously-unused key ID would fail.
Here's an example wrapper program written in go. Build this into an executable named iam-kms-wrapper and use it as instructed above. This could of course be written in any language for which an appropriate AWS SDK exists, but go has the benefit of compiling to a static binary, which means you do not have to worry about interpreter versions or installing complex dependencies on the host that runs your MariaDB server.
Another possibility is to use the API to disable access to the master key and enable it only when a trusted administrator knows that the MariaDB service needs to be started. A specialized tool on a separate host could be used to enable the key for a very short period of time while the service starts and then quickly disable the key.
To do this, you can create an extra IAM User that can only use the kms:EnableKey and kms:DisableKey API endpoints for your key. This user will not be able to encrypt or decrypt any data using the key.
First, create a new user.
Load the IAM console at.
Click "Users" in the left-hand sidebar.
Click "Create New Users".
Enter a new user name. (The examples will use "MDBEncAdmin".)
Click "Close".
Click "Close" again if prompted.
Click the name of your new user to open the details view.
Copy the "User ARN" value for your user (for example "arn:aws:iam::551888181234:user/MDBEncAdmin"). You will need this for the next step.
Now, give the new user permission to perform API operations on your key.
Click "Encryption Keys" in the left-hand sidebar.
Click the name of your key to open the details view.
Click "Switch to policy view" if it is not already open. (The "policy view" is a large text field that contains JSON describing the key policy.)
Create a new item in the Statement array with this structure:
...so that your Key Policy looks like this:
Click "Save Changes".
You've now added a new IAM user and you've given that user privileges to enable and disable your key. This user will be able to perform those operations using the AWS CLI or via a script of your own design using the AWS API. For example, using the :
In order for MariaDB to start, this new user will have to enable the master key, then the DBA can start MariaDB, and this user can once again disable the master key after the service has started. Note that in this workflow, MariaDB will be unable to create new encryption keys, such as would be done when a user creates a table that refers to a non-existent key ID. The AWS KMS plugin will encounter an error if it tries to generate a new encryption key while the master key is disabled. In that scenario, the key administrator would have to enable the key before the operation could succeed. Here's what you should expect to see in the journal if MariaDB tries to interact with a disabled master key:
It's also possible to add MFA to this technique so that the user that enables & disables the master key has to authenticate using an MFA device. Adapt the instructions in the MFA section above to add MFA to the policy section for the user with EnableKey and DisableKeys privileges, add an MFA device for that user, use Security Token Service (STS) to get temporary security credentials, and then use those credentials to make the API calls. Here's an example Python script that follows that workflow:
Amazon's CloudTrail service creates JSON-formatted text log files for every API interaction. Enabling CloudTrail requires S3, which incurs additional fees.
First, enable CloudTrail and add a trail.
Load the CloudTrail console at.
If you've never used CloudTrail before, click "Get Started Now".
Enter a value for "trail name". This example uses "mariadb-encryption-key".
Create a new S3 bucket, using a globally unique name, or use an existing S3 bucket, according to your needs.
If you navigate to the S3 bucket you created, you should find log files that contain JSON-formatted descriptions of your API interactions.
Amazon's CloudWatch service allows you to create alarms and event rules that monitor log information.
First, send your CloudTrail logs to CloudWatch.
Load the CloudTrail console at.
Click "Trails" in the left-hand navigation sidebar.
Click the name of your trail to open the Configuration view.
In the "CloudWatch Logs" section, click "Configure".
Now, set up an SNS topic to facilitate email notifications.
Open.
Make sure the region in the console (look in the upper-right corner) is the same as the region where you created your key!
Click "Get Started" is prompted.
Click "Events" in the left-hand sidebar.
Now, configure CloudWatch and create an Event Rule.
Open.
Make sure the region in the console (look in the upper-right corner) is the same as the region where you created your key and your SNS topic!
Click "Events" in the left-hand sidebar.
Click "Create rule".
You should now get emails any time someone executes API calls on the KMS service in the region where you've created the CloudWatch Event rule. That means you should get email any time the key is enabled or disabled, and any time the AWS KMS plugin generates new keys or decrypts the keys stored on disk on the MariaDB server.
You may also wish to create an event rule (or an additional event) that matches only when an unauthorized user tries to access the key. You might accomplish that by manually editing the Event selector of the rule to look something like this:
The emails are formatted as JSON. Further customization of the CloudWatch email workflow is beyond the scope of this document.
There are many other workflows available using CloudWatch, including workflows with alarms and dashboards. Those are beyond the scope of this document.
This page is licensed: CC BY-SA / Gnu FDL
"Sid": "Allow use of the key".Add this text below the "Sid" line:
"Sid": "Allow use of the key".Add this text below the "Sid" line:
Copy the ARN for your MFA device. You will need to use this when configuring the wrapper program.
Copy the credentials and put them in a credentials file with this structure:
Click "Turn On".
Click "Allow".
Enter a Topic name of your choosing.
Enter a Display name of your choosing.
Click "Create topic".
Click the ARN of your new SNS topic.
Click "Create Subscription".
Select "Email" from the Protocol dropdown.
Enter the desired notification email address in the Endpoint field.
Wait for the confirmation email to show up and follow the instructions.
Choose "KMS" from the "Service name" dropdown.
Decide which operations should trigger the event. (You can eep "Any operation" selected for simplicity.)
Click "Add target".
Select "SNS target" from the dropdown.
Select the SNS topic you created in the previous steps.
Click "Configure details".
Enter a Name and Description of your choosing.
Click "Create rule".
[Service]
Environment=AWS_CREDENTIAL_PROFILES_FILE=/etc/aws-kms-credentials# cat /etc/systemd/system/mariadb.service.d/aws-kms.conf
[Service]
Environment=AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
Environment=AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV# cat /etc/systemd/system/mariadb.service.d/aws-kms.env
AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV
# chown root /etc/systemd/system/mariadb.service.d/aws-kms.env
# chmod 600 /etc/systemd/system/mariadb.service.d/aws-kms.env
# cat /etc/systemd/system/mariadb.service.d/aws-kms.conf
[Service]
EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env$ whoami
mysql
$ cat /proc/$(pgrep mysqld)/environ | tr '\0' '\n' | grep AWS
AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV"Condition": {
"IpAddress": {
"aws:SourceIp": [
"10.1.2.3/32"
]
}
},"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "True"
}
},[Service]
EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env
ExecStart=
ExecStart=/usr/local/bin/iam-kms-wrapper --config=/etc/my.cnf.d/iam-kms-wrapper.config /usr/sbin/mysqld $MYSQLD_OPTS[kms]
kms_mfa_id = arn:aws:iam::551888187628:mfa/MDBEnc
kms_mfa_socket = /tmp/kms_mfa_socketpackage main
import (
"syscall"
"os"
"log"
"flag"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/robfig/config"
)
func main() {
config_file_p := flag.String("config", "", "location of the config file")
flag.Parse()
if flag.NArg() < 1 {
log.Fatal("Command to wrap must be given as first command-line argument")
}
cmd := flag.Arg(0)
args := flag.Args()[0:]
conf, err := config.ReadDefault(*config_file_p)
if err != nil {
log.Fatal(err)
}
kms_mfa_id, err := conf.String("kms","kms_mfa_id")
mfa_socket_file, err := conf.String("kms","kms_mfa_socket")
sess := session.New()
svc := sts.New(sess)
syscall.Umask(0044)
log.Printf("Reading MFA token from %s\n",mfa_socket_file)
if err := syscall.Mknod(mfa_socket_file, syscall.S_IFIFO|uint32(os.FileMode(0622)), 0); err != nil {
log.Fatal(err)
}
file, err := os.Open(mfa_socket_file)
if err != nil {
log.Fatal(err)
}
token := make([]byte, 6)
if _, err := file.Read(token); err != nil {
log.Fatal(err)
}
file.Close()
if err := syscall.Unlink(mfa_socket_file); err != nil {
log.Fatal(err)
}
mfa_token := string(token)
token_params := &sts.GetSessionTokenInput{
DurationSeconds: aws.Int64(900),
SerialNumber: aws.String(kms_mfa_id),
TokenCode: aws.String(mfa_token),
}
resp, err := svc.GetSessionToken(token_params)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
// Prints out full error message, including original error if there was one.
log.Fatal("Error:", awsErr.Error())
} else {
log.Fatal("Error:", err.Error())
}
}
creds := resp.Credentials
os.Setenv("AWS_ACCESS_KEY_ID",*creds.AccessKeyId)
os.Setenv("AWS_SECRET_ACCESS_KEY",*creds.SecretAccessKey)
os.Setenv("AWS_SESSION_TOKEN",*creds.SessionToken)
execErr := syscall.Exec(cmd, args, os.Environ())
if execErr != nil {
panic(execErr)
}
}[MDBEncAdmin]
aws_access_key_id=AKIAJMPPNO7EBKABCDEF
aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef{
"Sid": "Allow Enable and Disable of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::551888181234:user/MDBEncAdmin"
},
"Action": [
"kms:EnableKey",
"kms:DisableKey"
]
},{
"Version": "2012-10-17",
"Id": "key-consolepolicy-2",
"Statement": [
{
"Sid": "Allow Enable and Disable of the key",
"Effect": "Allow",
"Principal": {
...$ cat ~/.aws/credentials
[MDBEncAdmin]
aws_access_key_id=AKIAJMPPNO7EBKABCDEF
aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef
$ AWS_PROFILE=MDBEncAdmin aws --region us-east-1 kms disable-key --key-id arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c[ERROR] AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : DisabledException - Unable to parse ExceptionName: DisabledException Message: arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c is disabled.#!/usr/bin/env python
import boto3
import sys
# Command-line argument processing should be more robust than this...
action= sys.argv[1]
mfa_token= sys.argv[2]
# These should perhaps go into a config file instead of here
mfa_serial= 'arn:aws:iam::551888181234:mfa/MDBEncAdmin'
key_id= 'arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c'
# Make the connection to the Security Token Service to get temporary credentials
token_client= boto3.client('sts')
token_response= token_client.get_session_token(
DurationSeconds= 900,
SerialNumber= mfa_serial,
TokenCode= mfa_token
)
cred= token_response['Credentials']
# Start new session using temporary, MFA-authenticated credentials
kms_session= boto3.session.Session(
aws_access_key_id= cred['AccessKeyId'],
aws_secret_access_key= cred['SecretAccessKey'],
aws_session_token= cred['SessionToken'],
region_name= key_id.split(':')[3]
)
# Start KMS client and execute operation against key
kms_client= kms_session.client('kms')
if action == 'enable' or action == 'e':
action_f= kms_client.enable_key
elif action == 'disable' or action == 'd':
action_f= kms_client.disable_key
else:
raise Exception('Action must be either "disable" or "enable"')
action_f(KeyId=key_id)$ AWS_PROFILE=MDBEncAdmin python kms-manage-key disable 575290
$ AWS_PROFILE=MDBEncAdmin python kms-manage-key enable 799870{
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"kms.amazonaws.com"
],
"errorCode": [
"AccessDenied",
"UnauthorizedOperation"
]
}
}MariaDB's data-at-rest encryption requires the use of a key management and encryption plugin. These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.
MariaDB supports the use of multiple encryption keys. Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports key rotation, then encryption keys can also be rotated, which creates a new version of the encryption key.
The File Key Management plugin that ships with MariaDB is a key management and encryption plugin that reads encryption keys from a plain-text file.
The File Key Management plugin is the key management and encryption plugin for users who want to use data-at-rest encryption. Some of the plugin's primary features are:
It reads encryption keys from a plain-text key file.
As an extra protection mechanism, the plain-text key file can be encrypted.
It supports multiple encryption keys.
It supports key rotation with MariaDB Enterprise Server from MariaDB Enterprise Server 11.8.
It can also serve as an example and as a starting point when developing a key management and encryption plugin with the .
The File Key Management plugin is included in MariaDB packages as the file_key_management.so or file_key_management.dll shared library. The shared library is in the main server package, so no additional package installations are necessary. The plug-in must be installed into MariaDB however as follows.
Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. The plugin can be installed by providing the or the options. This can be specified as a command-line argument to or it can be specified in a relevant server in an . For example:
Before you uninstall the plugin, you should ensure that is completely disabled, and that MariaDB no longer needs the plugin to decrypt tables or other files.
You can uninstall the plugin dynamically by executing or . For example:
If you installed the plugin by providing the or the options in a relevant server in an , then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.
In order to encrypt your tables with encryption keys using the File Key Management plugin, create the file containing the encryption keys. File name and location don't matter; see in the following what configuration is needed.
For each encryption key, the file contains these options, separated by a semicolon:
The key identifier (format: 32-bit integer)
The key version (optional, and only available as of Enterprise Server 11.8)
The key itself (format: hex-encoded)
Entries look like this:
You can also optionally encrypt the key file to make it less accessible from the file system. That is explained further in the section below.
The File Key Management plugin uses to encrypt data. It supports 128-bit, 192-bit, and 256-bit encryption keys, just like the plugin does.
Generate random encryption keys using the command. To create a random 256-bit (32-byte) encryption key, run the following command:
The key file needs to have a key identifier for each encryption key added to the beginning of each line. Key identifiers do not have to be contiguous. For example, to append three new encryption keys to a new key file, issue this command:
The resulting key file looks like this:
The key identifiers give you a way to reference the encryption keys from MariaDB. In the example above, you could reference these encryption keys using the key identifiers 1, 2 or 100 with the table option or with system variables such as . You do not necessarily need multiple encryption keys; an encryption key with the key identifier 1 is the only mandatory one.
If the key file is left unencrypted, the File Key Management plugin only requires the system variable to be configured.
This system variable can be specified as a command-line argument to mariadbd , or it can be specified in a server of an , like this:
If you use an unencrypted key file, keys are stored in plain text on your system, posing a security risk. It's recommended to encrypt the key file, with these hints in mind:
MariaDB only supports the mode of .
The encryption key size can be 128-bits, 192-bits, or 256-bits.
The encryption key is created from the hash of the encryption password.
The encryption password has a maximum length of 256 characters.
Generate a random encryption password using the command. To create a random 256 character encryption password, execute the following:
Encrypt the key file using the command. To encrypt the key file with the encryption password created in the previous step, execute, for example, one of the following commands:
The resulting keys.enc file is the encrypted version of keys.txt file. Delete the unencrypted key file.
Having the key file encrypted requires both the and the system variables to be configured.
The file_key_management_filekey variable can be provided in two forms:
As a plain-text encryption password. This is not recommended, since the plain-text encryption password would be visible in the output of the statement.
Prefixed with FILE:, it can be a path to a file that contains the plain-text encryption password.
These variables can be specified as command-line arguments to mariadbd, or they can be specified in a relevant server in an :
The File Key Management plugin currently supports two encryption algorithms for encrypting data: AES_CBC and AES_CTR. Both of these algorithms use in different modes. AES uses 128-bit blocks, and supports 128-bit, 192-bit, and 256-bit keys. The modes are:
The AES_CBC mode uses AES in the mode.
The AES_CTR mode uses AES in two slightly different modes in different contexts. When encrypting tablespace pages (such as pages in InnoDB, XtraDB, and Aria tables), it uses AES in the mode. When encrypting temporary files (where the cipher text is allowed to be larger than the plain text), it uses AES in the authenticated .
The recommended algorithm is AES_CTR, but this algorithm is only available when MariaDB is built with . If the server is built with then this algorithm is not available. See for more information about which libraries are used on which platforms.
The encryption algorithm can be configured by setting the system variable.
This system variable can be set to one of the following values:
This system variable can be specified as command-line arguments to mariadbd, or it can be specified in a relevant server in an . For example:
Note that the option prefix is specified. This option prefix is used in case the plugin hasn't been installed yet.
Note that this variable does not affect the algorithm that MariaDB uses to decrypt the key file. This variable only affects the encryption algorithm that MariaDB uses to encrypt and decrypt data. The only algorithm that MariaDB currently supports to encrypt the key file is mode of .
Once the File Key Management Plugin is enabled, you can use it by creating an encrypted table:
Now, table t will be encrypted using the encryption key from the key file. For more information on how to use encryption, see .
The File Key Management Plugin supports . Each encryption key can be defined with a different 32-bit integer as a key identifier.
When , the key that is used to encrypt tables . When , the key that is used to encrypt tables .
The plugin supports key rotation and allows an optional key version in the key file. The keys can be rotated using the FLUSH FILE_KEY_MANAGEMENT_KEYS statement, without needing to restart the server. The plugin remains compatible with old key file format, and when version is not specified, it defaults to version 1.
Generation of New Key Versions
How would new key versions be generated?
The plugin doesn't generate any encryption keys itself, and it doesn't have a backend KMS to generate encryption keys for it either.
Any encryption keys need to be generated by the user with external tools, such as OpenSSL. For example:
Keys need to be manually saved to the key file. See .
The format of the key file is simplistic. It stores encryption keys in a plain-text file.
file_key_management_encryption_algorithmThis system variable is used to determine which algorithm the plugin will use to encrypt data.
The recommended algorithm is AES_CTR, but this algorithm is only available when MariaDB is built with . If the server is built with then this algorithm is not available. See for more information about which libraries are used on which platforms.
Command line: --file-key-management-encryption-algorithm=value
file_key_management_digestSpecifies the digest function to use in key derivation of the key used for decrypting the key file.
Command line: --file-key-management-digest=value
Scope: Global
Dynamic: No
file_key_management_filekeyUsed to determine the encryption password that is used to decrypt the key file defined by .
If this system variable's value is prefixed with FILE:, then it is interpreted as a path to a file that contains the plain-text encryption password.
If this system variable's value is not prefixed with FILE:, then it is interpreted as the plain-text encryption password. However, this is not recommended.
file_key_management_filenameUsed to determine the path to the file that contains the encryption keys. If is set, this file can be encrypted with mode of .
Command line: --file-key-management-filename=value
Scope: Global
file_key_management_use_pbkdf2Specifies whether pbkdf2 is used in key derivation, and if so, how many iterations.
Command line: --file-key-management-use-pbkdf2=number
Scope: Global
Dynamic: No
file_key_managementControls how the server should treat the plugin when the server starts up.
Valid values are:
OFF - Disables the plugin without removing it from the table.
This page is licensed: CC BY-SA / Gnu FDL
The File Key Management plugin does not support key rotation.
Scope: Global
Dynamic: No
Data Type: enumerated
Default Value: AES_CBC
Valid Values: AES_CBC, AES_CTR
Data type: enumerated
Default value: sha1
Valid values: sha1, sha224, sha256, sha384, sha512
Available from MariaDB 12.0
The encryption password has a max length of 256 characters.
The only algorithm that MariaDB currently supports when decrypting the key file is Cipher Block Chaining (CBC) mode of Advanced Encryption Standard (AES). The encryption key size can be 128-bits, 192-bits, or 256-bits. The encryption key is calculated by taking a SHA-1 hash of the encryption password. Instead of SHA-1, SHA-2 can be used as well.
Command line: --file-key-management-filekey=value
Scope: Global
Dynamic: No
Data type: string
Default value: (empty)
Data type: string
Default value: (empty)
Data type: numeric
Default value: 0
Valid values: integers ≥ 0 (reasonable value: 600000 for sha256, less for sha512)
Available from MariaDB 12.0
ON - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.FORCE - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
FORCE_PLUS_PERMANENT - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with UNINSTALL SONAME or UNINSTALL PLUGIN while the server is running.
See Plugin Overview: Configuring Plugin Activation at Server Startup for more information.
Command line: --file-key-management=value
Data type: enumerated
Default value: ON
Valid values: OFF, ON, FORCE, FORCE_PLUS_PERMANENT
AES_CBC
Data is encrypted using AES in the Cipher Block Chaining (CBC) mode. This is the default value.
AES_CTR
Data is encrypted using AES either in the Counter (CTR) mode or in the authenticated Galois/Counter Mode (GCM) mode, depending on context. This is only supported in some builds. See the previous section for more information.
1.0
Stable
From MariaDB 10.1.18
[mariadb]
...
plugin_load_add = file_key_managementUNINSTALL SONAME 'file_key_management';<encryption_key_id>;<encryption_key_version>;<hex-encoded_encryption_key><encryption_key_id>;<hex-encoded_encryption_key>$ openssl rand -hex 32
a7addd9adea9978fda19f21e6be987880e68ac92632ca052e5bb42b1a506939amkdir -p /etc/mysql/encryption
echo $(echo -n "1;" ; openssl rand -hex 32) | sudo tee -a /etc/mysql/encryption/keyfile
echo $(echo -n "2;" ; openssl rand -hex 32) | sudo tee -a /etc/mysql/encryption/keyfile
echo $(echo -n "100;" ; openssl rand -hex 32) | sudo tee -a /etc/mysql/encryption/keyfile1;1;a7addd9adea9978fda19f21e6be987880e68ac92632ca052e5bb42b1a506939a
2;1;49c16acc2dffe616710c9ba9a10b94944a737de1beccb52dc1560abfdd67388b
100;2;8db1ee74580e7e93ab8cf157f02656d356c2f437d548d5bf16bf2a56932954a31;a7addd9adea9978fda19f21e6be987880e68ac92632ca052e5bb42b1a506939a
2;49c16acc2dffe616710c9ba9a10b94944a737de1beccb52dc1560abfdd67388b
100;8db1ee74580e7e93ab8cf157f02656d356c2f437d548d5bf16bf2a56932954a3[mariadb]
...
loose_file_key_management_filename = /etc/mysql/encryption/keyfile$ sudo openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key$ sudo openssl enc -aes-256-cbc -md sha256 -pbkdf2 -pass pass:secret -in /tmp/keys.txt -out /tmp/keys.enc
$ sudo openssl enc -aes-256-cbc -md sha256 -iter 20000 -pass pass:secret -in /tmp/keys.txt -out /tmp/keys.enc[mariadb]
...
loose_file_key_management_filename = /etc/mysql/encryption/keyfile.enc
loose_file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key[mariadb]
...
loose_file_key_management_encryption_algorithm = AES_CTRCREATE TABLE t (i INT) ENGINE=InnoDB ENCRYPTED=YES-- Generate a new 256-bit key
openssl rand -hex 32