Showing posts with label backup. Show all posts
Showing posts with label backup. Show all posts

Wednesday, September 16, 2026

Oracle 19c: Cloning Encrypted PDBs and Moving TDE Keys

Oracle TDE master key in a wallet or Oracle Key Vault protects keys for encrypted tablespaces and columns
Oracle TDE key hierarchy. This walkthrough uses file-based wallets in Oracle Database 19c.

When cloning or refreshing an encrypted pluggable database (PDB) in Oracle Database 19c, it is easy to focus on the datafiles. Restore the backup, recover the database, and plug the PDB into the destination container database (CDB).

But don't forget the keys. With Transparent Data Encryption (TDE), the destination also needs access to the master encryption keys stored in the source wallet.

In this post I will walk through two ways to bring the keys with an encrypted PDB, and then show where those steps fit when the PDB is restored from backup. I am using Oracle Database 19c, local file-based TDE wallets, and united mode. In united mode the PDBs use the CDB's wallet, while keeping their own master encryption keys.

This builds on my posts about encrypting an Oracle PDB with TDE and Oracle wallet files for TDE and authentication.

NOTE: These are command examples to adapt and validate on your 19c Release Update. Database names, paths, passwords, and the recovery SCN are placeholders. This is a walkthrough of the key handling, not output from a completed lab.

For unplug/plug, I can bring the keys with ENCRYPT USING and DECRYPT USING, or export and import them separately. A refresh from RMAN backups also needs the historical keys during recovery into the auxiliary CDB.

In this post: Check the wallet · Unplug/plug with keys · Export and import keys · Refresh from RMAN backups · Rekey and verify · Merge wallets

TDE wallet keys: what needs to move with a PDB?

TDE has two levels of keys. The tablespace key encrypts the data, and the TDE master encryption key protects that key. The master key is stored in the keystore. Copying encrypted datafiles does not, by itself, give a different CDB access to that master key. Oracle's TDE overview

Moving an encrypted PDB and its TDE wallet keysThe encrypted PDB datafiles move to the destination PDB. Master keys are transported or exported and imported into the destination wallet, retaining its existing PDB keys.An encrypted PDB has two things to carryOracle Database 19c • Local TDE wallet • United modeSource PDBEncrypted datafilesProtected tablespace keysDestination PDBCopied datafilesStill encryptedCopy / restore / plugSource CDB walletPDB master encryption keysCurrent + historical keysDestination CDB walletImported PDB keysRetain existing PDB keysTransport with the PDBOR export / importAfter import: rekey the new PDB, verify encrypted data, and back up the updated wallet.A new master key does not remove the need for keys used by older backups.Figure 1. Move both the encrypted PDB datafiles and the required master keys into the destination environment.

For these examples I am using the following names.

Name Purpose
PRODCDB / APPPDB Source CDB and encrypted PDB
AUXCDB / APPPDB Temporary CDB used for a restore from backup
TESTCDB / APP_REFRESH Existing destination CDB and the new refresh PDB
SourceWalletPassword Password for the source wallet
TargetWalletPassword Password for the destination wallet
TransportSecret Separate secret protecting keys during transport

The transport secret and the wallet passwords have different jobs. I do not need to make the source and destination wallet passwords match.

STEP #1 - Check the TDE wallet configuration

On each CDB, I first check the configuration and wallet status.

-- SQL*Plus, connected to the appropriate CDB root
SHOW CON_NAME
SHOW PARAMETER wallet_root
SHOW PARAMETER tde_configuration

SELECT con_id, status, wallet_type, keystore_mode,
       wrl_parameter
FROM   v$encryption_wallet
ORDER BY con_id;

The examples assume TDE_CONFIGURATION='KEYSTORE_CONFIGURATION=FILE', with the united wallet under WALLET_ROOT/tde. A PDB row should show UNITED; the root can show NONE. An OPEN wallet is a useful first check, but it does not prove that it contains every key needed for this refresh. Wallet status reference

For a password wallet that is closed, open it from the root. Use the password belonging to that CDB.

ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN
  IDENTIFIED BY "SourceWalletPassword"
  CONTAINER = ALL;

If auto-login already has the wallet open, check its state rather than blindly repeating the open. The key-management examples below use FORCE KEYSTORE where supported to allow access to the password wallet. Have the ewallet.p12 password available even when normal database startup uses cwallet.sso. Configuring TDE

I also record the source PDB's keys before the move.

ALTER SESSION SET CONTAINER = APPPDB;

SELECT key_id, creation_time, activation_time
FROM   v$encryption_keys
ORDER BY activation_time;

This gives me key identifiers to compare later. I am recording metadata here, not displaying the secret key material. Encryption key view

Run the key operations as an appropriately privileged key administrator (SYSKM or ADMINISTER KEY MANAGEMENT), and the PDB operations with the necessary database privileges. The examples assume both are available to the administrative session.

METHOD #1 - Unplug and plug an encrypted PDB with its TDE keys

For a planned unplug/plug, I can protect the PDB's keys with a transport secret as part of the unplug operation.

1) Unplug on the source

-- PRODCDB root; source wallet must be open
ALTER SESSION SET CONTAINER = CDB$ROOT;

ALTER PLUGGABLE DATABASE APPPDB CLOSE IMMEDIATE;

ALTER PLUGGABLE DATABASE APPPDB
  UNPLUG INTO '/secure_stage/apppdb.xml'
  ENCRYPT USING "TransportSecret";

ENCRYPT USING protects the transported keys. The XML file is a manifest; the PDB's datafiles still have to be made available on the destination host. A .pdb archive is an alternative packaging format. Unplugging PDBs

NOTE: Unplugging takes this source PDB out of service. For a refresh that must leave production running, use the backup/auxiliary workflow below and unplug the restored copy.

2) Check compatibility at the destination

For this example, the XML and datafiles are accessible at the paths recorded in the XML. If the files were staged at different paths, account for that with SOURCE_FILE_NAME_CONVERT; FILE_NAME_CONVERT controls the destination copies.

-- TESTCDB root
SET SERVEROUTPUT ON
DECLARE
  can_plug BOOLEAN;
BEGIN
  can_plug := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
    pdb_descr_file => '/secure_stage/apppdb.xml',
    pdb_name       => 'APP_REFRESH');
  IF can_plug THEN
    DBMS_OUTPUT.PUT_LINE('Compatible');
  ELSE
    RAISE_APPLICATION_ERROR(-20001,
      'Review PDB_PLUG_IN_VIOLATIONS before continuing');
  END IF;
END;
/

Resolve compatibility errors before creating the PDB, including applicable patch, component, and character-set issues. Plug compatibility check

3) Plug in the copy

The destination wallet must already exist and be open. APP_REFRESH must be a new PDB name in TESTCDB.

-- TESTCDB root; filesystem paths used for this example
CREATE PLUGGABLE DATABASE APP_REFRESH AS CLONE
  USING '/secure_stage/apppdb.xml'
  COPY
  FILE_NAME_CONVERT =
    ('/u02/oradata/PRODCDB/APPPDB/',
     '/u02/oradata/TESTCDB/APP_REFRESH/')
  KEYSTORE IDENTIFIED BY "TargetWalletPassword"
  DECRYPT USING "TransportSecret";

ALTER PLUGGABLE DATABASE APP_REFRESH OPEN;

Here, AS CLONE gives the plugged copy a new identity, and COPY creates its datafiles at the destination. DECRYPT USING supplies the transport secret, while KEYSTORE IDENTIFIED BY supplies the destination wallet password. Adapt file placement for OMF or ASM. CREATE PLUGGABLE DATABASE reference

Finish with the rekey and verification steps below. An initial restricted open is not the end of the process.

METHOD #2 - Export and import TDE keys for an Oracle 19c PDB

This is an alternative to Method #1. I use a separate export file when I want the key transfer to be an explicit step in the refresh process.

1) Export from inside the source PDB

-- PRODCDB, or AUXCDB after restoring the PDB
ALTER SESSION SET CONTAINER = APPPDB;

ADMINISTER KEY MANAGEMENT EXPORT ENCRYPTION KEYS
  WITH SECRET "TransportSecret"
  TO '/secure_stage/apppdb_keys.exp'
  FORCE KEYSTORE
  IDENTIFIED BY "SourceWalletPassword";

ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE APPPDB CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE APPPDB
  UNPLUG INTO '/secure_stage/apppdb.xml';

Export inside the PDB. Do not add a WITH IDENTIFIER IN filter: a PDB export carries its keys and the metadata identifying the active key. Protect the export file and deliver its secret separately. Exporting keys leaves the source keys in place. Key export syntax

2) Import into the destination root before plugging, when required

If SYSTEM, SYSAUX, UNDO, or TEMP is encrypted, first import into TESTCDB's root. Then import again inside the new PDB to associate the keys with it. For a PDB without those encrypted system tablespaces, the pre-plug root import can be skipped. Oracle's united-mode PDB procedure

-- TESTCDB root: conditional pre-plug import
ALTER SESSION SET CONTAINER = CDB$ROOT;

ADMINISTER KEY MANAGEMENT IMPORT ENCRYPTION KEYS
  WITH SECRET "TransportSecret"
  FROM '/secure_stage/apppdb_keys.exp'
  FORCE KEYSTORE
  IDENTIFIED BY "TargetWalletPassword"
  WITH BACKUP USING 'before_refresh_root_import';

3) Plug in, open the PDB wallet, and import inside the PDB

Run the compatibility check from Method #1 first. This manifest was created without ENCRYPT USING, so this branch does not use DECRYPT USING.

-- TESTCDB root
CREATE PLUGGABLE DATABASE APP_REFRESH AS CLONE
  USING '/secure_stage/apppdb.xml'
  COPY
  FILE_NAME_CONVERT =
    ('/u02/oradata/PRODCDB/APPPDB/',
     '/u02/oradata/TESTCDB/APP_REFRESH/')
  KEYSTORE IDENTIFIED BY "TargetWalletPassword";

ALTER SESSION SET CONTAINER = APP_REFRESH;

-- If the PDB's password wallet is not already open:
ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN
  FORCE KEYSTORE
  IDENTIFIED BY "TargetWalletPassword";

ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE APP_REFRESH OPEN;

ALTER SESSION SET CONTAINER = APP_REFRESH;

ADMINISTER KEY MANAGEMENT IMPORT ENCRYPTION KEYS
  WITH SECRET "TransportSecret"
  FROM '/secure_stage/apppdb_keys.exp'
  FORCE KEYSTORE
  IDENTIFIED BY "TargetWalletPassword"
  WITH BACKUP USING 'before_refresh_pdb_import';

The PDB may initially open restricted. Complete the PDB import, rekey, and reopen before releasing it to the application. The root import and PDB import serve different purposes; do not treat the root import as completion of both steps.

Refresh an encrypted PDB from RMAN backups

I separate this into two handoffs: backup to auxiliary CDB, followed by auxiliary PDB to the existing destination CDB.

Oracle 19c encrypted PDB refresh from RMAN backupsRestore the source backups into AUXCDB with the historical wallet keys. Then plug the restored PDB into TESTCDB and add its keys to the existing destination wallet.Refreshing from backup into an existing CDBRestore with the historical keys first. Then transfer the restored PDB and its keys.Source backup setRoot + seed + APPPDBControlfile + required redoChosen recovery SCNAUXCDB / APPPDBBackup-based duplicateRecover and openProduction keeps runningTESTCDBNew PDB: APP_REFRESHPlug in, rekey, and verifyCut over after validationSource wallet copyRequired root and PDB keysIncludes historical keysAuxiliary walletAvailable during recoveryUsed to export restored keysTESTCDB walletAdd APPPDB keysRetain other PDB keysRecoveryPlug-inTwo separate key handoffs1 Provision the recovery wallet to AUXCDB.2 Use ENCRYPT / DECRYPT, or a PDB key export / import, for TESTCDB.Figure 2. A backup refresh has two key handoffs: recovery into AUXCDB, then plug-in and key transfer into TESTCDB.

1) Make the historical keys available to the auxiliary

The auxiliary needs the keys required by the backup and recovery interval. Rotating the production master key does not eliminate the need for older keys. A wallet backup that predates a required rotation may be missing a key; a later wallet can contain the historical keys if they have been retained. TDE key history

For a newly prepared auxiliary, securely provision a copy of the source password wallet at its configured WALLET_ROOT/tde location. Use a wallet with the required CDB and PDB key history, not just a PDB key export. The duplicate also restores root and seed files. Keep the auxiliary's wallet separate from the live source and from TESTCDB's wallet. Preparing the auxiliary keystore

For example, the auxiliary initialization settings include:

db_name='AUXCDB'
db_unique_name='AUXCDB'
enable_pluggable_database=TRUE
wallet_root='/u01/app/oracle/admin/AUXCDB/wallet'
tde_configuration='KEYSTORE_CONFIGURATION=FILE'

This is only the relevant parameter excerpt. Prepare the auxiliary in NOMOUNT, with its own controlfile, datafile, redo, and recovery-area destinations, plus the password file and Oracle Net configuration required by your duplication method.

2) Restore the PDB into the temporary CDB

Here is a backup-based duplication example, with RMAN connected to PRODCDB as TARGET and AUXCDB as AUXILIARY. Both connections are to the root. The source backup pieces must be accessible to the auxiliary, including root, seed, PDB, controlfile, and the archived redo needed to reach the chosen SCN.

-- RMAN: connected to the two CDB roots
SET DECRYPTION WALLET OPEN
  IDENTIFIED BY 'SourceWalletPassword';

RUN {
  SET UNTIL SCN 123456789;
  SET NEWNAME FOR DATABASE TO '/u02/oradata/AUXCDB/%U';

  DUPLICATE TARGET DATABASE TO AUXCDB
    PLUGGABLE DATABASE APPPDB
    LOGFILE
      GROUP 1 ('/u02/oradata/AUXCDB/redo01.log') SIZE 200M,
      GROUP 2 ('/u02/oradata/AUXCDB/redo02.log') SIZE 200M,
      GROUP 3 ('/u02/oradata/AUXCDB/redo03.log') SIZE 200M;
}

Replace the SCN and file layout with values for your restore. This creates a new auxiliary CDB containing the selected PDB, not a PDB directly inside TESTCDB. Oracle 19c's DUPLICATE PLUGGABLE DATABASE ... TO existing_cdb form supports active duplication; it is not the backup-based command used here. RMAN DUPLICATE reference

SET DECRYPTION WALLET OPEN supplies the wallet password across auxiliary restarts during duplication. It does not transfer missing keys. If the backup pieces have a separate password-encryption layer, also supply the applicable backup password using SET DECRYPTION IDENTIFIED BY. That password does not replace the keys needed for the TDE-encrypted datafiles. RMAN SET reference

3) Transfer from AUXCDB into TESTCDB

After successful recovery and opening the restored PDB, use either Method #1 or Method #2, with AUXCDB as the source.

Create a fresh manifest from the restored PDB, and export its keys there if using Method #2. Update FILE_NAME_CONVERT to match the restored files' actual paths. In the RMAN example, %U generates filenames directly under /u02/oradata/AUXCDB/; inspect those filenames rather than assuming an APPPDB subdirectory exists.

I would create APP_REFRESH alongside the current test PDB, validate it, and then handle the application/service cutover. The destructive replacement of an existing PDB is a separate decision. This is a repeated refresh from backups, not a REFRESH MODE clone.

Rekey the cloned PDB, reopen, and verify

Once the imported keys are available, create and activate a destination master key inside APP_REFRESH.

-- TESTCDB, inside the new PDB only
ALTER SESSION SET CONTAINER = APP_REFRESH;

ADMINISTER KEY MANAGEMENT SET KEY
  FORCE KEYSTORE
  IDENTIFIED BY "TargetWalletPassword"
  WITH BACKUP USING 'app_refresh_rekey'
  CONTAINER = CURRENT;

ALTER SESSION SET CONTAINER = CDB$ROOT;
ALTER PLUGGABLE DATABASE APP_REFRESH CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE APP_REFRESH OPEN;

Use CONTAINER=CURRENT for this PDB; there is no reason for a refresh to rotate every PDB's key. Changing the wallet password is also a different operation from generating a new master key. Key-management operations

Rekeying gives the destination a new master key. It does not make historical backups independent of their original keys. Retain those keys for as long as the corresponding recovery requirements exist. TDE key architecture FAQ

Now I check the result.

-- TESTCDB root
SELECT name, open_mode, restricted
FROM   v$pdbs
WHERE  name = 'APP_REFRESH';

SELECT time, name, cause, type, message, status, action
FROM   pdb_plug_in_violations
WHERE  name = 'APP_REFRESH'
AND    status <> 'RESOLVED'
ORDER BY time;

ALTER SESSION SET CONTAINER = APP_REFRESH;

SELECT status, keystore_mode, fully_backed_up
FROM   v$encryption_wallet;

SELECT key_id, creation_time, activation_time
FROM   v$encryption_keys
ORDER BY activation_time;

SELECT tablespace_name, encrypted
FROM   dba_tablespaces
ORDER BY tablespace_name;

I want READ WRITE, RESTRICTED=NO, and all blocking plug-in violations resolved. I also read known application data from an encrypted tablespace and check the expected refresh timestamp or business totals. Opening the PDB alone is not my application validation. Completing a PDB plug-in

Finally, back up the updated destination wallet and the refreshed PDB. WITH BACKUP protects the wallet before a change; I also want a retained copy containing the newly created key.

-- TESTCDB root, after successful rekey
ALTER SESSION SET CONTAINER = CDB$ROOT;

ADMINISTER KEY MANAGEMENT BACKUP KEYSTORE
  USING 'after_app_refresh'
  FORCE KEYSTORE
  IDENTIFIED BY "TargetWalletPassword"
  TO '/secure_wallet_backups/TESTCDB';

Keep password-wallet backups and their passwords recoverable, with access controlled separately from the database backups. An auto-login wallet stored beside encrypted backups weakens that separation. RMAN encryption and wallet backup guidance

Migrate TDE wallet keys with MERGE KEYSTORE

For one PDB, I would normally use the PDB export/import above. A wallet merge has broader scope: it adds the source wallet's keys to another wallet.

Here is a merge example using staged wallet copies, outside the live wallet directories:

-- Optional wallet administration example; not a PDB refresh step
ADMINISTER KEY MANAGEMENT
  MERGE KEYSTORE '/secure_stage/source_wallet'
    IDENTIFIED BY "SourceWalletPassword"
  INTO EXISTING KEYSTORE '/secure_stage/target_wallet_copy'
    IDENTIFIED BY "TargetWalletPassword"
  WITH BACKUP USING 'before_wallet_merge';

This updates the staged destination password wallet and leaves the source unchanged. It does not switch the live database to that staged wallet. A planned wallet migration must also configure the final location, reopen the merged wallet, and update or recreate its auto-login companion as appropriate. Coordinate that change across all consumers of the wallet. Merging and relocating wallets

NOTE: Do not copy the source ewallet.p12 over the wallet of an existing destination CDB. That destination may need keys for other PDBs. Also, MOVE KEYS removes selected keys from the source keystore and is not a substitute for a clone's export/import. MIGRATE USING is for changing the keystore provider, such as migrating to Oracle Key Vault. Key-management SQL reference

The operational check I would add to every refresh job is simple: record which backup was restored, which keys were supplied, where the destination wallet was backed up, and whether encrypted application data was successfully read. Those four items make the next refresh, and the next recovery exercise, much easier to review.

Monday, October 6, 2025

ZDLRA best practices

 ZDLRA best practices (updated 2025)

I have seen a lot of changes with the ZDLRA over the last 10 years or so, and because of that I wanted to document the best practices to follow that changed up to now, and are also helpful for new existing. (2025).



Because of the changes that have occurred as the product has matured, I wanted to write a blog post on what existing customers should think about doing now, and what new customers should think about.

1. Channel Configuration

There are a few items to talk about with channel configuration. First let's break down the pieces of the channel configuration


a) Library

Version

Up until version 19.26, you could use a shared version of the library (libra.so) based on the OS.  Updates to the library could be downloaded directly from MOS.

Starting with version 19.27 on Linux, you must use the version that is stored in $ORACLE_HOME and patched using OPatch.  More information can be found in the MOS note below.

Location (channel setting)

In the previous section I mentioned that the library is tied to the version of Oracle starting with 19.26. Prior to this release, the default channel setting for the library with the ZDLRA  was
  • "PARMS  'SBT_LIBRARY=$ORACLE_HOME/lib/libra.so"
In order to always utilize the current library for the $ORACLE_HOME, the recommendation is to set the channel setting to
  • "SBT_LIBRARY=libra.so" - No path, and it will default to the current $ORACLE_HOME/lib"
    Or
  • "SBT_LIBRARY=oracle.zldlra" - This will default to the current $ORACLE_HOME/lib/libra.so

b) Environment

In the environment section, you specify the SEPS wallet location. Because there could be conflicts with other oracle products that use a wallet (like OUD), the default location for the SEPS wallet should be set to the WALLET_ROOT location, rather than within the $ORACLE_HOME location.

In the past,  the channel setting for ZDLRA  was
  • "RA_WALLET=location=file:${ORACLE_HOME}/dbs/ra_wallet credential_alias={SEPS entry in wallet}"
The recommendation is to set the WALLET_ROOT in the spfile, and store the SEPS wallet within the server_seps directory under this location. If WALLET_ROOT is set to $ORACLE_BASE/admin/{$DB_NAME}/wallet, the setting would be

  • "RA_WALLET=location=file:${ORACLE_BASE}/admin/${DB_NAME}/wallet/server_seps/ credential_alias={SEPS entry in wallet}"

c) TLS or non-TLS

If a customer has the ZDLRA configured to encrypt backups with TLS/SSL, the library, by default, will attempt to encrypt the backup using SSL/HTTPS.  If TLS/SSL is configured as optional, and if the client does not have the certificate information, backups will fail. To avoid this, it is recommended to add the following setting to the channel configuration.  This setting will allow you to send backups even if optional TSL/SSL is configured.

  • _RA_NO_SSL=TRUE

d) Space Efficient Encrypted Backups

In order to use Space Efficient Encrypted Backups, you must set the following in your channel configuration. This is only available on linux with DB version 19.18+. Keep in mind this setting will only compress datafile backup pieces.  
  • RA_FORMAT=TRUE

Example:

RMAN> CONFIGURE CHANNEL DEVICE TYPE 'SBT_TAPE' PARMS  'SBT_LIBRARY=oracle.zdlra,ENV=(_RA_NO_SSL=TRUE,RA_WALLET=location=file:/u01/app/oracle/admin/orcl/wallet/server_seps credential_alias="tcps://pmdra1-scan1.us.oracle.com:2484/ra1db", RA_FORMAT=true)';

  • oracle.zdlra - Use the libra.so from the $ORACLE_HOME for the database
  • _RA_NO_SSL=TRUE - Do not send backups encrypted if TLS is optionally enabled. 
  • /u01/app/oracle/admin/orcl/wallet/server_seps - Wallet location from WALLET_ROOT
  • RA_FORMAT=true - Use space efficient encrypted backups


2. RMAN encryption

One misconception with Space Efficient Encrypted Backups, is that by setting RA_FORMAT=TRUE you are both compressing and encrypting backups. This is not true. You are only compressing the backups. If the tablespace is encrypted with TDE, the backup will remain encrypted, but any non-TDE tablespace backups will be unencrypted.  In order to encrypt the backup pieces (Datafiles, controlfile,. archive logs and spfile) you need to both set an encryption key (if not already set), and set RMAN encryption on.  If you are backing up any tablespaces that are not TDE, you must also ensure you set RA_FORMAT=TRUE.
You should also set the default encryption algorithm to AES256, as most customers use this today rather than the default of AES128

NOTE: Use of RA_FORMAT=TRUE (RMAN Compression) and RMAN encryption is included in the license for ZDLRA and you do not need the ACO or ASO license for backups to the ZDLRA.

3. Real-time redo settings.

a) Default SEPS wallet location


Wallets are becoming more and more common with databases, and this increases the chances that there will be conflict with other Oracle features that also utilize a wallet. To avoid this there is a new default location for the SEPS wallet used by real-time redo. The database will first look in the {WALLET_ROOT}/server_seps location for the wallet.  It is recommended to set the WALLET_ROOT for all databases and use this default location for the SEPS wallet.  Of course you may use links to simplify management.

b) Encrypt Redo


If you have an encryption key set, and you wish to fully encrypt your backups, you also need to ensure that real-time redo is also encrypted. You need to set encryption on the destination for real-time redo
  • ENCRYPTION=ON

NOTE: As an additional note, I have a previous blog post on wallets you can find here.  I have worked with a few customers that have run into issues configuring real-time redo because they have other products that are affected by WALLET_OVERRIDE=TRUE.  What I tell customers is that  if they want to continue to use the SEPS wallet for RMAN scripts (i.e. rman target / catalog /@{wallet entry}), then they should create a separate/customer sqlnet.ora file in a different location, and set TNS_ADMIN in their RMAN backup script. 

4. Reserve Space

Reserve space has been difficult to explain, and it has become even more important when implementing a compliance window.  If there is no compliance set, then the reserve space is only interrogated when the ZDLRA runs out of space.  When a compliance window is set, the reserve space is interrogated when backing up to ensure that compliance locked backups fit within the reserved space. If they do not, backups are rejected.  Because of this, I always recommend setting the "auto-tune reserve space" for the policies, especially when setting a compliance window. This setting will automatically adjust the reserve space for you as databases grow.

5. When encrypting backups set "secure mode"

If you need to fully encrypt your backups with RMAN encryption, it is recommended to use "secure mode" on your protection policy. This setting checks all backup pieces (including real-time redo) to ensure that they are RMAN encrypted.  Any unencrypted backup pieces will be rejected.

6. Use racli commands

One of the biggest changes is the increase in the functionality available with racli command vs executing DBMS_RA PL/SQL packages. It is recommended to utilize RACLI commands when possible.  I know when trying to automate onboarding databases, it is much easier to utilize PL/SQL packages.

7. Pair ZDLRAs when using replication

Another change is the ability to pair ZDLRAs that have replication configured. This can be done with the "racli add ra_partner" command.  Using the ZDLRA pairing commands for replication greatly simplifies the configuration of replication. Existing configurations can be converting to using the pairing model.

8. Review types of DB users

There have been a few changes to DB users. There are now 4 types of DB users.
  • ADMIN -Used to administer ZDLRA configuration settings
  • MONITOR - Read-only account that can view metadata
  • REPLICATION - Used to replicate backups between ZDLRAs
  • VPC - Used by protected databases to send/received backups
    • Insecure=TRUE - VPC user's password will expire, but it can be reset to the same password. This type of user does not support password rollover. Alternately you can set the profile of the VPC user to "NO_EXPIRE". This is less secure, but avoids having the password expire.
    • insecure=false - VPC user's password will expire, but this user can leverage password rollover (STIG) to manage password rotation without having backups fail.
NOTE: If you need to rotate password for VPC users you should leverage the STIG/password rollover function that allows you have two passwords associated with the same VPC user as you update wallets.

Summary:

  1. Set WALLET_ROOT in the database and store the SEPS in the {WALLET_ROOT}/server_seps directory
  2. Ensure the library location in the channel configuration defaults to the current $ORACLE_HOME
  3. Set _RA_NO_SSL=TRUE to ensure that converting to TLS/SSL will not cause existing backups to fails
  4. Set RA_FORMAT=TRUE to leverage space efficient encrypted backups --> Linux only
  5. Enable RMAN encryption, and set algorithm to AES256 --> Linux only
  6. Encrypt Real-time redo if applicable
  7. If you require fully encrypted backups, set SECURE_MODE on the policy
  8. Enable auto-tune of reserved space for all databases, especially those using a compliance window.
  9. Use RACLI commands to manage the ZDLRA
  10. Pair ZDLRAs when configuring replication
  11. Leverage password rollover for VPC users if you require password rotation



Wednesday, September 17, 2025

Building a Cyber Vault ? Don't forget your keys

When building a cyber vault, one of the most important items to manage is encryption keys.  Encrypting your data is a fundamental pillar of ransomware protection, but encryption key management is often forgotten.  
Ensuring your Cyber Vault has a current copy of your encryption keys associated with your Oracle Databases is critically important for a successful restore and recover after an attack.

Starting with the Oracle Key Vault (OKV) 21.11 release, Oracle Key Vault includes a preview of the Key Transfer Across Oracle Key Vault Clusters Integration Accelerator. You can use this feature to transfer security objects from one OKV cluster to another.

You can find more detail on this feature here, and I will describe it's benefits in this post.

The diagram below shows a typical cyber vault architecture to protect Oracle Databases with the Zero Data Loss Recovery Appliance (ZDLRA) and OKV .

Transferring keys into a cyber vault with OKV

Encryption Key Architecture

Encryption key management is a critical piece of data protection, and it is important to properly manage your keys.  Good cyber protection begins with proper encryption key management.

Local Wallets

With Oracle databases, the default (and simplest) location for encryption keys is in a locally management wallet file.  The keys are often stored in an auto-login wallet, which is automatically opened by the database at startup making key management transparent and simple, but not very secure.

Why aren't wallets secure ?

  • They are often auto-login (cwallet.sso) which allows the database to open the wallet without requiring a password. This wallet file gives full access to the encryption keys.
  • The wallet file is stored with the database files.  A privileged administrator, such as a DBA has access to both the database and the keys to decrypt the data directly from the hosts.  They also have the ability to delete the wallet file.
  • Often the wallet file is backed up with the database, which includes an auto-login wallet.  This allows anyone who has access to backups, to also be able to decrypt the data.
  • Securely backing up the wallet file separate from the database is often forgotten, especially when ASM is used as the wallet location.  Not having the wallet file when restoring the database makes restoration and recovery impossible.

Steps you can take

  • Create both a passworded wallet (ewallet.p12) and local auto-login wallet (cwallet.sso). With a local auto-login wallet, the wallet can only be opened on the host where the wallet was created.
  • Backup the passworded wallet only (ewallet.p12).  The auto-login wallet can always be recreated from the passworded wallet.
  • Properly store the password for you passworded encryption wallet. You will need the password to rotate your encryption keys, and create the auto-login wallet.

Oracle Key Vault (OKV)

 The best way to securely manage encryption keys is with OKV.

Why ?

  • Keys are managed outside of the database and cannot be accessed locally outside of the database.
  • Access to keys is granted to a specific database instance.
  • OKV is clustered for High Availability, and the OKV cluster can be securely backed up.
  • Key access is audited to allow for early detection of access.

Encryption Keys in a cyber vault architecture

Below is a diagram of a typical cyber vault architecture using ZDLRA.  Because the backups are encrypted, either because the databases are using TDE and/or they are creating RMAN encrypted backups sent to the ZDLRA, the keys need to be available in the vault also.
Not only is the cyber vault a separate, independent database and backup architecture, the vault also contains a separate, independent OKV cluster.
This isolates the cyber vault from any attack to the primary datacenter, including any attack that could compromise encryption key availability.


Encryption Keys in an advanced cyber vault architecture

Below is a diagram of an advanced cyber vault architecture using ZDLRA.  Not only are the backups replicated to a separate ZDLRA in the vault, they are internally replicated to an Isolated Recovery Environment (IRE).  In this architecture, the recover area is further isolated, and the OKV cluster is even further isolated from the primary datacenter. This provides the highest level of protection.


OKV Encryption Key Transfer


This blog post highlights the benefit of the newly released (21.11) OKV feature to allow for the secure transfer of encryption keys.
Periodic rotation of encryption keys is a required practice to protect encryption keys, and ensuring you have the current key available in a cyber vault is challenging.
OKV solves this challenge by providing the ability to transfer any new or changed keys between clusters.

Implementing OKV in a cyber Vault

When building a cyber vault, it is recommend to build an independent OKV cluster.  The OKV cluster in the vault is isolated from the primary datacenter and protected by an airgap.  The nodes in this cluster are  not be able to communicate with the OKV cluster outside of the vault.
The OKV cluster in the vault can be created using a full, secure, backup from the OKV cluster in the primary datacenter. The backup can be transferred into the vault, and then restored to the new, independent OKV cluster providing a current copy of the encryption keys.

Keeping OKV managed keys updated in a cyber Vault

The challenge, once creating an isolated OKV cluster has been keeping the encryption keys within the cluster current when new keys are created.  This was typically accomplished by transferring a full backup of OKV into the vault, and rebuilding the cluster using this backup.

OKV 21.11 provides the solution with secure Encryption Key Transfer.  Leveraging this feature you can securely transfer just the keys that have recently changed allowing you to manage independent OKV clusters that are synchronized on a regular basis.

The diagram below shows the flow of the secure Encryption Key Transfer package from the primary OKV cluster into the vault when the air-gap is opened.

This new OKV feature provides a much better way to securely manage encryption keys in a Cyber Vault.



Summary

As ransomware attacks increase, it is critical to protect a backup copy of your critical database in a cyber vault.  It is also critical to protect a copy of your encryption keys to ensure you can recovery those databases.  OKV provides the architecture for key management in both your primary datacenter and in a cyber vault.  The new secure key transfer feature within OKV allows you to synchronize keys across independent OKV clusters.

Wednesday, December 11, 2024

Listing Databases on an Oracle DB node

 In this blog post I am sharing a script that I wrote that will give you the list of databases running on a DB node.  The information  provided by the script is

  • DB_UNIQUE_NAME
  • ORACLE_SID
  • DB_HOME

WHY


I have been working on a script to automatically configure OKV for all of the Oracle Databases running on a DB host.  In order to install OKV in a RAC cluster, I want to ensure the unique OKV software files are in the same location on every host when I set the WALLET_ROOT variable for my database.  The optimal location is to put the software under $ORACLE_BASE/admin/${DB_NAME} which should exist on single instance nodes, and RAC nodes.

Easy right?


I thought it would be easy to determine the name of all of the databases on a host so that I could make sure the install goes into $ORACLE_BASE/admin/{DB_NAME}/okv directory on each DB node.

The first item I realized is that the directory structure under $ORACLE_BASE/admin is actually the DB_UNIQUE_NAME rather than DB_NAME. This allows for 2 different instances of the same DB_NAME (primary and standby) to be running on the same DB node without any conflicts. 

Along with determining the DB_UNIQUE_NAME, I wanted to take the following items into account
  • A RAC environment with, or without srvctl properly configured
  • A non-RAC environment 
  • Exclude directories that are under $ORACLE_BASE/admin that are not a DB_UNQUE_NAME running on the host.
  • Don't match on ORACLE_SID.  The ORACLE_SID name on a DB node can be completely different from the DB_UNIQUE_NAME.

Answer:

After searching around Google and not finding a good answer I checked with my colleagues.  Still no good answer.. There were just suggestions like "srvctl config", which would only work on a RAC node where all databases are properly registered.  

The way I decided to this was to 
  • Identify the possible DB_UNIQUE_NAME entries by looking in $ORACLE_BASE/admin
  • Match the possible DB_UNIQUE_NAME with ORACLE_SIDs by looking in $ORACLE_BASE/diag/rdbms/${DB_UNIQUE_NAME} to find the ORACLE_SID name.  I would only include DB_UNIQUE_NAMEs that exist in this directory structure and have a subdirectory.
  • Find the possible ORACLE_HOME by matching the ORACLE_SID to the /etc/oratab.  If there is no entry in /etc/oratab still include it.

Script:


Below is the script I came up with, and it displays a report of the database on the host.  This can be changed to store the output in a temporary file and read it into a script that loops through the databases.




Output:

Below is the sample output from the script.. You can see that it doesn't require the DB to exist in the /etc/oratab file.



DB_UNIQUE_NAME : cdb1db1
ORACLE_SID     : cdb1db11
ORACLE_HOME    :  ******  NOT IN /etc/oratab **** Cannot determine ORACLE_HOME *****


DB_UNIQUE_NAME : daver
ORACLE_SID     : daver1
ORACLE_HOME    : /u01/app/oracle/product/19.0.0.0/dbhome_1


DB_UNIQUE_NAME : dbsgadat
ORACLE_SID     : dbsgadat1
ORACLE_HOME    : /u01/app/oracle/product/19.0.0.0/dbhome_1


DB_UNIQUE_NAME : dbsgprd
ORACLE_SID     : dbsgprd1
ORACLE_HOME    : /u01/app/oracle/product/19.0.0.0/dbhome_1



Finally:


If you are also trying to get a list of databases that are running on a DB node I hope this helps you.

Sunday, September 29, 2024

ZDLRA backups -- How do I know if they are Encrypted

 The ZDLRA introduced a new feature with release 23.1 that can both encrypt backups (if they are not already encrypted from TDE) and  compress the backups .  The combing of both encryption and compression with this feature is unique to the ZDLRA.



I talked about this new exciting feature in a blog post on Oracle.com you can find here.

What I am am going to cover in this blog post is how to audit the RMAN catalog on the ZDLRA to validate that your backups are completely RMAN encrypted.

There are two big advantages of ensuring your backups are fully encrypted

1) With the prevalence of data exfiltration, and the advent of new regulations in many industries,  full encryption of backups is mandatory

2) When sending a backup to the Oracle cloud (either in OCI or to object storage on ZFS) full encryption is required to protect the backup data.

The question I often get asked with this feature is..

 "How do you tell  if your backups are encrypted ?"

You can can determine that your backups are encrypted by looking at the RMAN catalog.

The RC_BACKUP_PIECE view contains a column identifying if the backup is encrypted.  This column is set to "YES" only when the backup piece is encrypted.

Keep in mind that there multiple types of backups pieces contained in the catalog

  • Controlfile backups
  • Spfile backups
  • Archive log sweeps
  • Archive log backups from real-time redo
  • Datafile backups
  • Virtual Full backups created from incremental backups.
All of these backups except for two are sent from RMAN with "encryption on" and the backup set will marked as encrypted based on the RMAN encryption setting.

The two that are not set by RMAN directly are
  • Real-time redo backups. Real-time redo backups are identified in the RMAN catalog as encrypted when the destination setting on the protected database has ENCRYPTION=ENABLE set.
  • Virtual Full backups.  Virtual full backups are identified, for each datafile backup set, as encrypted ONLY after a new L0 is taken with RMAN encryption on, and all subsequent L1 backups are encrypted.  I know that is a lot of stipulations on identifying the virtual full backup as encrypted.  Only when a new FULL encrypted backup is taken, and all future incremental backups are encrypted can the ZDLRA be sure the backup has remained completely encrypted.

Checking the catalog

  The script below takes 2 parameters (&db_name, and &days_to_compare) and it will check the RMAN catalog and display the status of the backups, by backup type making it easier to identify any backup pieces that may not be encrypted.



This provides a nicely formatted output as you can see below.


                                             Database backup summary for last 15 days database: DBSG23AI

Encrypted  Compressed Backup
 Yes or No  Yes or No pieces Backup piece type
========== ========== ====== ========================================
YES        YES            69  Full backup
YES        NO             39 Archive Log - log sweep
NO         YES             1 Incremental L1  backup
YES        NO           3958 Archive Log - real-time redo
YES        YES            67 Incremental L1  backup
NO         YES             3  Full backup
NO         NO              1 Controlfile/SPFILE backup
YES        NO             26 Controlfile/SPFILE backup
YES        NO            221 Incremental L1  backup


In the report you can see that there a  few backups that not encrypted, along with some controlfile/spfile backups.


NOTE: In order to run this report, I created a REPORT user in the database on the ZDLRA as an "monitor" user.. A report has enough permissions to create this report.

OKV and ZDLRA 

Previously when sending backups to Cloud (which included OCI object storage on ZFSSA), OKV was required. When using Space Efficient Encrypted backups, you can ensure that EVERY backup piece is fully encrypted and RMAN recognizes them as encrypted.

If you follow the information in the blog, and what I have posted in the past, you will no longer need to configure OKV when sending backups to the cloud. 

If all backup pieces are encrypted, and the RMAN catalog reports that all backup are encrypted, you can create backups using DBMS_RA.CREATE_ARCHIVAL_BACKUP setting the "encryption_algorithm" to "CLIENT" or "ENC_CLIENT". This will tell the ZDLRA not utilize OKV to encrypt backups, but if any backup pieces are NOT encrypted, the archival backups will fail.





Tuesday, August 27, 2024

Oracle Backup Compression and Encryption layers explained

 When working with customers who are applying compression and/or encryption to their Oracle DB backups, I found that it isn't always clear if backups are compressed or encrypted, or both. In this blog post I will break compression and encryption of Oracle backups down into the levels where these operations could occur.  Below is a high level view of these 3 levels.



Database

Compression

Data in the database can be compressed in any one of the following formats or all of the formats

HCC - Available only on Exadata, or ZFS storage, this compression is a columnar compression format with different options that allow you to choose the appropriate access speed and compression ratio for your data

Advanced Compression - A licensable option that will automatically compress data in the background to optimize storage without compromising performance.

Basic Compression - Requires a lock on object during insert and is typically used within a data warehouse.

 External Compression - In some cases the data stored in the database may already be compressed externally. An example of this is image files which are already stored in a compressed format.

 

Encryption

Data in the database can be encrypted in any one of the following formats or all of the formats

TDE - All data in the tablespace is encrypted by database.

Column Encryption - Specific data within a column is encrypted, SSN for example.  This is less widely used and most customers use TDE instead.

 External Encryption - In some cases the data stored in the database may already be encrypted by the application.

 

 NOTE: 

1. If the data is compressed and/or encrypted in these manors it will continue in that format when backed up.  

  • Any data that encrypted in the database will remain encrypted in the backups
  • Any data that is compressed in the database will remain compressed in the backups
  • Backups of data that is compressed and/encrypted will get little to no compression when backed up


2. RMAN does not know that the data  is either compressed or encrypted, and querying the RMAN views will not tell you that either has occurred.


3. Having data encrypted and/or compressed in the database may not stop you from further compressing and/or encrypted the backups.


ZDLRA

Compression

Datafile Compression - With Datafile compression you have 2 choices to compress the backups

    • RA_FORMAT = TRUE - This  compresses all datafile backups in the new ZDLRA 23.1 format.  If the datafile is part of a TDE tablespace, the blocks will be decrypted prior to compression to ensure the best compression ratio.  
    • RA_FORMAT not set or  FALSE - Backups of datafiles will be sent as uncompressed (unless you create a RMAN compressed backupset which the ZDLRA will uncompress before ingesting).  Once they are received on the ZDLRA they will be compressed in storage on ZDLRA.  When replicated to another ZDLRA, or restored, they are uncompressed.

Real-time Redo Compression - When sending real-time redo to the ZDLRA you can have the ZDLRA create an RMAN compressed backupset for the archive logs.  The level of compression can be set on the policy.  Once stored in an RMAN compressed backupset format, it is replicated and restored as a compressed backupset.  

          NOTE: If the Redo stream contains changes to a TDE tablespace, or you are                                            configuring encryption on the RA as destination, you may get little to no actual compression 

SPFILE, Controfile, archivelog backups - The ZDLRA will NOT attempt to compress these backupsets internally.  Only datafile backups are compressed on the ZDLRA.

 

Encryption

Datafile Encryption - Whether a datafile is encrypted by the ZDLRA in the new ZDLRA 23.1 format depends on these 2 conditions.

    • RA_FORMAT = TRUE and "RMAN Encryption ON" - If the datafile is NOT part of a TDE tablespace, this will force BOTH compression and encryption of that datafile backup.
    • RA_FORMAT = TRUE and "RMAN Encryption OFF" - If the datafile is part of a TDE tablespace, the backup of this datafile will remain encrypted.  If the datafile is NOT part of a TDE tablespace, the backup will NOT be encrypted.

Real-time Redo Encryption - If real-time redo is utilized and your database has implemented TDE, the change data in the archive log backups will be encrypted.  However, this backup is not considered RMAN encrypted, and ENCRYPTION=ENABLED must be set on the destination definition to ensure that the real-time redo backupsets are considered fully encrypted by RMAN.

SPFILE, Controlfile, archivelog backup Encryption - These are not encrypted by the ZDLRA.

 

 NOTE: 

1. The new Space Efficient Encrypted backup feature of the ZDLRA only affects datafile backups.

2. Real-time redo backups can be compressed and/or encrypted by the ZDLRA.

3. If you are using the new RA_FORMAT=TRUE for non-TDE datafile backup, you will only get a compressed a backupset.  You have set RMAN Encryption on with RA_FORMAT=TRUE in order to encrypt the backupset.

4. If you are backing up a non-TDE  datafile, and wish to encrypt it with the library, it will also be compressed.  You cannot encrypt without compression, but you can compress without encryption.

5. If datafile backups are sent to the ZDLRA  without RA_FORMAT=TRUE, they will appear as compressed in the RMAN catalog.  With RA_FORMAT=TRUE they will not appear as compressed.

6.If real-time redo is sent to the ZDLRA, and the profile for the database is set to compress the archivelogs, they will appear as compressed in the RMAN catalog. 

 

RMAN

Compression

Datafile Compression - With Datafile compression you have 2 choices to compress the backups

  • RA_FORMAT = TRUE - RMAN compression is ignored when this option is set.  
  • RA_FORMAT not set or  FALSE - RMAN can create a compressed backupset for datafiles.  If the datafile is part of a TDE tablespace, this datafile will not be able to create a virtual full.  If the Datafile is NOT part of a TDE tablespace, the backset will be decompressed on the ZDLRA and will not be stored as a Compressed backupset.


SPFILE, Controfile, archivelog backups - The ZDLRA will NOT attempt to compress these backupsets internally.  They remain compressed.

 

Encryption

Datafile Encryption - RMAN Encrypt ON  creates an Encrypted backupset which cannot be virtualized by the ZDLRA.  This should only be set when using RA_FORMAT=TRUE which bypasses RMAN encryption


SPFILE, Controlfile, archivelog backup Encryption - These can be encrypted by setting RMAN Encryption on.

 NOTE: 

1. The new Space Efficient Encrypted backup feature of the ZDLRA only affects datafile backups.

2. Real-time redo backups can be compressed and/or encrypted by the ZDLRA.

3. If you are using the new RA_FORMAT=TRUE for non-TDE datafile backup, you will only get a compressed a backupset.  You have set RMAN Encryption on with RA_FORMAT=TRUE in order to encrypt the backupset.

4. If you are backing up a non-TDE  datafile, and wish to encrypt it with the library, it will also be compressed.  You cannot separate encryption from compression, but you can compress only.