WL#12080: Add support for binary log encryption key rotation and cleanup
Affects: Server-8.0
—
Status: Complete
High-Level Description / Executive Summary EXECUTIVE SUMMARY ================= This worklog implements the ability to rotate the binlog master key used to encrypt file passwords of binary and relay log files. The binlog master key should be rotated periodically and whenever you suspect that the key may have been compromised. Rotating the binlog master key not only changes the key used to encrypt new file password, but also re-encrypts file passwords of previous existent encrypted binary or relay log file with the new generated key. It also cleanups the keyring, removing the binlog encryption keys generated by the server that are not needed for server operation anymore. User stories ============ - As a MySQL DBA/operator/instance owner, I want to rotate binlog encryption master key periodically without the need to restart the server in order to comply with security rules. - As a MySQL DBA/operator/instance owner, I suspect that the some of existing binlog encryption master keys were exposed. I want to rotate the binlog master key so, starting this point, all new encrypted binary and relay log files shall use the new generated key to encrypt their file passwords, and file passwords of existent encrypted binary or relay log files are re-encrypted with the new generated key.
Functional and Non-Functional Requirements
FUNCTIONAL REQUIREMENTS
=======================
F-1: MySQL server should introduce a new command to rotate the binlog master
key used to change the key used to encrypt new file password and
re-encrypt file passwords of previous existent encrypted binary or
relay log files with the new generated key with syntax:
ALTER INSTANCE ROTATE BINLOG MASTER KEY;
Executing the new command shall emit an error to the client side on
the session when binlog-encryption is off regardless of the value
of log_bin.
The new command shall not be replicated while executing it.
Interface Specification
=======================
I-1: No new files
I-2: No changes in existing syntax
I-3: No new tools
I-4: No impact on existing functionality
I-5: Introduce a new command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY'
to rotate the binlog encryption key. Executing the new command
requires the BINLOG_ENCRYPTION_ADMIN or SUPER privilege.
HIGH LEVEL SPECIFICATION
========================
1. MySQL server introduces a new command to rotate the binlog master
key used to change the key used to encrypt new file password and
re-encrypt file passwords of previous existent encrypted binary or
relay log files with the new generated key with syntax:
ALTER INSTANCE ROTATE BINLOG MASTER KEY;
Executing the new command shall emit an error to the client side on
the session when binlog-encryption is off regardless of the value
of log_bin. We still have a requirement to rotate binlog master key
for relay logs on binlogless slaves when binlog-encryption is on.
So rotating binlog master key shall result in an error when
binlog-encryption is off even in binlogless slaves.
The new command shall not be replicated while executing it.
2. Binlog master key rotation
Binlog master key rotation shall only be possible when 'binlog-encryption'
is on. Requests to rotate the binlog master key when 'binlog-encryption'
is off shall return an error.
2.1: Set that the binlog master key rotation has started
Store a key id "MySQLReplicationKey\_{UUID}\_old" with the
`master key SEQNO` as its key on keyring.
2.2: Determine the next SEQNO to be used by a new master key
Do: `master key SEQNO = master key SEQNO + 1` by P-4 in WL#10957. Then,
check if a binlog encryption key exists on keyring with the new
`master key SEQNO`. In order to be compliant with P-4 in WL#10957, the
server shall repeat this process until reaching a `master key SEQNO`
without a corresponding binlog encryption key on keyring.
Store a key id "MySQLReplicationKey\_{UUID}\_new" with the master key SEQNO
as its key on keyring.
2.3: Generate the new binlog master key
Request the keyring to generate a new key by key id
"MySQLReplicationKey\_{UUID}\_{SEQNO}" using `master key SEQNO` as SEQNO.
2.4: Remove master key "index" from keyring
Remove the "MySQLReplicationKey\_{UUID}" key from keyring (if it exists).
If unable to remove the key, the server shall throw an error (I-15 in
WL#10957).
2.5: Store master key "index" on keyring
Store key id "MySQLReplicationKey\_{UUID}" with the `new master key SEQNO`
as its key on keyring. This will allow that a server shall be able to
determine the binlog master key. If unable to store the key, the server
shall throw an error (I-14 in WL#10957).
2.6: Rotate and re-encrypt replication logs
2.6.1: Rotate and re-encrypt binary logs when binary logging is enabled
2.6.1.1: Rotate the binary log to create a new binary log file
encrypted with new master key.
2.6.1.2: Re-encrypt previous existent binary logs as below.
Starting from the next to last entry on the index file, iterating down
to the first one:
- If the file is encrypted, re-encrypt it. Otherwise, skip it.
- If failed to open the file, report an error.
2.6.2: Rotate and re-encrypt relay logs for each existing replication
channel
2.6.2.1: Rotate the relay log (except for GR applier) to create a new
relay log file encrypted with new master key.
Note: BUG#92526 MAKE GR REPLICATION CHANNELS ROTATE RELAY LOG
ON FLUSH LOGS as a way to remove GR exceptions from this WL.
2.6.2.2: Re-encrypt previous existent relay logs as below.
Starting from the next to last entry on the index file, iterating down
to the first one:
- If the file is encrypted, re-encrypt it. Otherwise, skip it.
- If failed to open the file, report an error.
2.7: Purge unused old binlog encryption keys from keyring
Retrieve the `last purged SEQNO` from keyring's
"MySQLReplicationKey\_{UUID}\_last\_purged" or 0 when the key
is not present on keyring.
Set `purge start = last purged SEQNO`. If `purge start` is 0, make
`purge start = 1`.
Set `purge end = `master key SEQNO - 1`.
Loop from `purge start` to `purge end`, remove all the keys like
"MySQLReplicationKey\_{UUID}\_{SEQNO}" from the keyring.
If `purge end > 0` and `purge end != last purged SEQNO`: make
`last purged SEQNO = purge end`, remove
"MySQLReplicationKey\_{UUID}\_last\_purged" key from keyring and store
"MySQLReplicationKey\_{UUID}\_last\_purged" key into keyring with the
new `last purged SEQNO`.
Remove "MySQLReplicationKey\_{UUID}\_old" key from keyring.
2.8: Finalize binlog master key rotation
Remove "MySQLReplicationKey\_{UUID}\_new" key from keyring.
3. Binlog master key rotation recovery
When starting the server, we should get the binlog master key and its
corresponding sequence number from keyring before opening any new
replication log, because they will be used to encrypt the new generated
replication logs when binlog encryption is ON. So before initializing
replication logs, we need to do binlog master key rotation recovery as
following:
Try to retrieve "MySQLReplicationKey\_{UUID}" from keyring. Store its
content into `master key SEQNO`.
Try to retrieve "MySQLReplicationKey\_{UUID}\_old" from keyring. Store
its content into `old master key SEQNO`.
Try to retrieve "MySQLReplicationKey\_{UUID}\_new" from keyring. Store
its content into `new master key SEQNO`.
```Take action according to the following table:
--------------------------------------------------------------------------------
-----------
| master key SEQNO | old master key SEQNO| new master key SEQNO | new master key
| Action |
--------------------------------------------------------------------------------
-----------
| doesn't exist | doesn't exist | doesn't exist | N/A
| Do binlog master key rotation from START. |
| n > 0 | doesn't exist | doesn't exist | N/A
| Ordinary server startup with known binlog master key. |
| n >= 0 | n | doesn't exist | N/A
| Continue binlog master key rotation from DETERMINE_NEXT_SEQNO. |
| n >= 0 | n | m > n | doesn't
exists | Continue binlog master key rotation from GENERATE_NEW_MASTER_KEY. |
| n > 0 | n | m > n | exists
| Continue binlog master key rotation from REMOVE_MASTER_KEY_INDEX. |
| doesn't exist | n >= 0 | m > n | exists
| Continue binlog master key rotation from STORE_MASTER_KEY_INDEX. |
| m > 0 | n >= 0 (exist) | m > n | exists
| Continue binlog master key rotation from ROTATE_LOGS. |
| m > 0 |doesn't exist | m | exists
| Continue binlog master key rotation from REMOVE_KEY_ROTATION_TAG. |```
All above actions need to skip log rotation (2.6) and unused encryption
keys cleanup (2.7), because binary/relay logs will be rotated later on
at the begin of the recovery.
Any other combination from the table shall abort the recovery with
an error if binlog encryption is ON.
4. Update the process of enabling binlog encryption as below
Do above binlog master key rotation recovery if binlog master key
rotation is not recovered.
5. Update the process of disabling binlog encryption as below
Make `master key SEQNO = 0`.
When binary logging is enabled, rotate the binary log to create a new binary
log file with plain binary log file format.
For each existing replication channel, rotate the relay log (except for GR
applier) to create a new relay log file with plain binary log file format.
UPGRADE/DOWNGRADE and CROSS-VERSION REPLICATION
===============================================
NEW->OLD: Suppose user issues ALTER INSTANCE ROTATE REPLICATION MASTER KEY on
a new master. Even if there is an error when the statement is
executed in a client to the OLD slave, it does not cause replication
to break, because the statement is not logged and replicated when
executing it.
OLD->NEW: Suppose user issues ALTER INSTANCE ROTATE BINLOG MASTER KEY on an
old master. The statement is not executed on the old master,
because it is out wih an error. So this does not cause replication
to break.
On upgrade, there is one new limitation:
-- No binlog master key rotation shall be possible when the
'binlog-encryption' is off.
NEW master, NEW slave - master or slave server is patched with the WL#12080
OLD master, OLD slave - master or slave server is not patched with the WL#12080
OBSERVABILITY
=============
Introduce several errors and emit them. See below.
ER_RPL_ENCRYPTION_CANNOT_ROTATE_BINLOG_MASTER_KEY
eng "Cannot rotate binary log master key when 'binlog-encryption' is off."
Emit the above error to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if
'binlog-encryption' is off.
ER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_OPERATE_KEY
eng "Failed to operate binary log master key on keyring, please check if
keyring plugin is loaded. The statement had no effect: the old binary log master
key is still in use, the keyring, binary and relay log files are unchanged, and
the server could not start using a new binary log master key for encrypting new
binary and relay log files."
Emit the above error to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if there is an
error when operating binary log master key on keyring before rotating and
re-encrypting binary and relay log files.
ER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_ROTATE_LOGS
eng "Failed to rotate one or more binary or relay log files. A new binary log
master key was generated and will be used to encrypt new binary and relay log
files. There may still exist binary or relay log files using the previous binary
log master key."
Emit the above error to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if there is an
error when retating binary or relay log files.
ER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_REENCRYPT_LOG
eng "%s. A new binary log master key was generated and will be used to encrypt
new binary and relay log files. There may still exist binary or relay log files
using the previous binary log master key."
Emit the above error to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if there is an
error when re-encrypting binary or relay log files.
ER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_CLEANUP_UNUSED_KEYS
eng "Failed to remove unused binary log encryption keys from the keyring,
please check if keyring plugin is loaded. The unused binary log encryption keys
may still exist in the keyring, and they will be removed upon server restart or
next 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' execution."
Emit the above warning to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if there is an
error when cleaning up unused keys.
ER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_CLEANUP_AUX_KEY
eng "Failed to remove auxiliary binary log encryption key from keyring, please
check if keyring plugin is loaded. The cleanup of the binary log master key
rotation process did not finish as expected and the cleanup will take place upon
server restart or next 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' execution."
Emit the above warning to the client side on the session when executing
the command 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' if there is an
error when cleaning up auxiliary keys.
ER_BINLOG_MASTER_KEY_RECOVERY_OUT_OF_COMBINATION
eng "Unable to recover binary log master key, the combination of
new_master_key_seqno=%u, master_key_seqno=%u and old_master_key_seqno=%u are
wrong."
Emit the above error to the client side on the session when executing
the command 'SET @@GLOBAL.binlog_encryption=ON' if there is an error
when recovering binary log master key rotation.
ER_SERVER_BINLOG_MASTER_KEY_RECOVERY_OUT_OF_COMBINATION
eng "Unable to recover binary log master key, the combination of
new_master_key_seqno=%u, master_key_seqno=%u and old_master_key_seqno=%u are
wrong."
Write the above error to server error log while starting up the server
with binlog_encryption enabled if there is an error while recovering
binary log master key rotation.
ER_SERVER_BINLOG_MASTER_KEY_ROTATION_FAIL_TO_CLEANUP_AUX_KEY
eng "Failed to remove auxiliary binary log encryption key from keyring, please
check if keyring plugin is loaded. The cleanup of the binary log master key
rotation process did not finish as expected and the cleanup will take place upon
server restart or next 'ALTER INSTANCE ROTATE BINLOG MASTER KEY' execution."
Write the above warning to server error log while starting up the server
with binlog_encryption enabled if there is an error on cleaning up auxiliary
keys while recovering binary log master key rotation.
Low-Level Design ================ The 1 and 2 in high level specification will be implemented in step 1, and 3, 4 and 5 in high level specification will be implemented in step 2.
Copyright (c) 2000, 2025, Oracle Corporation and/or its affiliates. All rights reserved.