2 Décembre 2019
Hello !!
Depuis le temps qu'on se dit avec Laurent qu'il faut remettre le pied à l'étrier, et bien oui ça y est, c'est bientôt Noël alors pour fêter ça, un nouvel article ! Certains vont probablement avoir quelques vacances, du coup pour passer le temps voici un nouvel article concernant évidemment Oracle & TDE , pour mettre en bouche avant la dinde de noël et le foie gras ...
Allez hop, en voiture Simone !
-----------------------------------------
Contexte technique :
-> Une VM RedHat 7.6 avec une instance Oracle en 12.2 dessus, dans mon contexte nommée BATMAN,
-> Mode multitenant avec 2 pluggables databases, nommées BATPDB et ROBIN.
-> Un schéma de test nommé "micka" dans la pluggable BATPDB.
L'objectif de cet article reste simple : activer TDE et configurer l'encryption des données niveau tablespace, uniquement sur une pluggable "BATPDB".
-----------------------------------------
Déjà : Mais qu'est ce donc que cette bebète "TDE" ? Un rapide résumé s'impose !
TDE, ou Transparent Data Encryption, permet de crypter l'accès aux données d'une bdd (ou plutôt d'une ou plusieurs tables) soit de façon globale, on parle alors de TDE niveau Tablespace, ou soit de façon plus fine, on parle alors de cryptage de colonne d'une ou plusieurs table(s).
Attention cependant car les données en tant que telles ne sont pas cryptées, comme par exemple via l'utilisation de DBMS_CRYPTO ou d'une anonymisation, mais elles sont rendues non lisibles de part le fait qu'elles sont stockés dans un tablespace qui lui est crypté.
=> L'idée est donc de ne pas avoir accès aux données en tant que telles sans avoir de clé de décryptage.
Idéalement on ne va crypter qu'une production, car très peu d’intérêt sur de la non prod (sauf si obligatoire ou autres raisons).
Il est important de dire également qu'à chaque implémentation de fonctionnalités Oracle, il y a un impact à coté : Les exports datapump par exemple sont concernés et devront tenir compte de cette spécificité, et les backups rman pourront être cryptés, ce qui sera étudié dans un second temps.
TDE supporte les algorithmes de cryptage suivant : 3DES168, AES128, AES192, AES256. Il utilise donc une clé pour crypter et décrypter la donnée , clé qui se trouve dans un WALLET (ou encore KEYSTORE depuis la version 12c) externe à la base.
-> En règle générale et par expérience on gère le KEYSTORE via un fichier spécifique dans un FS ou répertoire dédié, mais il peut se trouver dans un disque ASM.
-> Il est tout à fait possible d'activer TDE uniquement sur une pluggable database, ou plusieurs.
En effet, même si des actions sont à réaliser sur la container database (CDB), cela ne sous entend pas que toutes les pluggables sont concernées. Tant qu'aucune configuration de clé n'a été faite sur un tablespace ou colonne de table d'une pluggable, il n'y aura pas d'impact.
Petite information mais non des moindres importantes : TDE est disponible et utilisable en ENTERPRISE EDITION avec l'option Oracle Advanced Security (cf https://docs.oracle.com/en/database/oracle/oracle-database/12.2/dblic/Licensing-Information.html#GUID-AB56CEE3-955E-4E56-8B44-6075E889C283)
-----------------------------------------
Dans les grandes lignes il s'agira donc ici de :
-> Créer le keystore depuis la CDB,
-> ouvrir le keystore depuis la CDB,
-> Créer une clé de crypage uniquement sur un tablespace d'une pluggable.
La mise en place :
Tout d'abord, il nous faut adapter notre SQLNET. C'est en effet à travers ce fichier que l'on va indiquer où est stocké le wallet / keystore. On va donc ajouter simplement le bloc ci dessous dans notre fichier, en prenant soin d'adapter le répertoire cible en fonction du contexte.
Dans mon cas, le répertoire qui va stocker le Keystore sera /oracle/admin/BATMAN/keystore, donc :
ENCRYPTION_WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /oracle/admin/BATMAN/keystore)
)
)
--> On crée bien sur ce répertoire s'il n'existe pas.
Ensuite nous allons créer notre Keystore en base et l'ouvrir. Pour cela on se connecte à notre container CDB et on lance les commandes ci dessous, la encore il faut adapter en fonction du contexte.
Dans mon exemple, je me connecte en sysdba sur la database container (CDB) mais il est intéressant d'indiquer que depuis la version 12c il y a un nouveau ROLE system disponible nommé SYSKM, qui permet à un user spécifique de gérer les keystore, plutôt que d'avoir à utiliser le compte sysdba.
Bref, passons à la démo :
[oracle@ora-batman admin]$ sqlplus / as sysdba SQL*Plus: Release 12.2.0.1.0 Production on Mon Aug 19 14:18:08 2019 Copyright (c) 1982, 2016, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production SQL> ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/oracle/admin/BATMAN/keystore' identified by "Goth@M" ; keystore altered.
-> Le KeyStore a été crée sur mon instance Oracle, avec password "Goth@M" .
Je vais maintenant l'ouvrir sur ma container CDB ainsi que toutes les pluggables :
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "Goth@M" container = ALL;
keystore altered.
option "container=ALL" : Si cette option n'est pas spécifiée, par défaut Oracle va ouvrir le keystore uniquement sur le container sur lequel nous sommes connecté. Si l'on veut l'ouvrir pour toutes les pluggables y compris la CDB alors il faut spécifier container=ALL.
Dans mon cas, même si l'encryption tablespace ne concernera que ma pluggable BATPDB, j'ouvre le keystore pour toutes les PDBS (si un jour une autre est concernée je n'aurais pas à me poser de questions)
Si l'on veut éviter d'avoir à ouvrir notre keystore à chaque fois manuellement sur la CDB, on peut configurer l'autologin (ce que je vais évidemment faire)
SQL> ADMINISTER KEY MANAGEMENT CREATE LOCAL AUTO_LOGIN KEYSTORE from KEYSTORE '/oracle/admin/BATMAN/keystore' IDENTIFIED BY "Goth@M" ;
keystore altered.
Cette commande va générer un fichier dédié dans /oracle/admin/BATMAN/keystore nommé CWALLET.SSO :
[oracle@ora-batman admin]$ ls -l /oracle/admin/BATMAN/keystore/cwallet*.*
total 40
-rw------- 1 oracle oinstall 6995 Aug 19 15:28 cwallet.sso
Note : Pour supprimer l'autologin il suffira de renommer le fichier ci dessus.
On fait un petit arrêt relance de l'instance et on vérifie que le keystore soit bien ouvert :
SQL> select status from v$encryption_wallet; STATUS ------------------------------ OPEN
A ce stade, nous pouvons passer directement sur la pluggable Database cible, sauf si l'encryption concerne également des tablespaces appartenant à la container CDB, auquel cas il faudra créer la clé de cryptage et l'activer. Si nous souhaitons que toutes les PDBs utilise la même clé, il faut ajouter l'option "container=ALL" à la commande de création de clé.
Dans mon cas je n'ai pas de cryptage à faire sur ma container CDB et je veux une clé dédiée, je me place donc sur la pluggable cible "BATPDB" pour créer ma clé de cryptage.
Création de la clé de cryptage sur ma pdb :
SQL> alter session set container=BATPDB; Session altered. SQL> ADMINISTER KEY MANAGEMENT CREATE ENCRYPTION KEY USING TAG 'BATPDB_key' FORCE KEYSTORE IDENTIFIED BY "Goth@M" WITH BACKUP USING 'Before_create_encrypt_BATPDB_key'; keystore altered.
Configuration de la clé de cryptage, en récupérant en amont l'ID de la clé précédemment créée :
SQL> column key_id new_value new_key_id SQL> select key_id from v$encryption_keys where con_id = 3 and tag = 'BATPDB_key'; KEY_ID ------------------------------------------------------------------------------ ATvbKzmW9k81vyOfzoWiSXcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA SQL> ADMINISTER KEY MANAGEMENT USE ENCRYPTION KEY 'ATvbKzmW9k81vyOfzoWiSXcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' USING TAG 'BATPDB_key' FORCE KEYSTORE IDENTIFIED BY "Goth@M" WITH BACKUP USING 'Before_activate_encrypt_BATPDB_key'; keystore altered.
Attention : pour cette pluggable je part du principe où le keystore est déjà ouvert. Si ce n'est pas le cas alors il faut l'ouvrir avant de lancer la commande de création de clé de cryptage (au pire cela ne marche pas et un joli message d'erreur indique que le keystore n'est pas ouvert..)
Voila, c'est fini pour cette partie car il reste désormais à créer / modifier les tablespaces cibles pour être cryptés, mais la mise en place est terminée.
En ce qui concerne ma seconde pluggable "ROBIN", vu qu'il n'y a eu aucune configuration il n'y a aucun impact.
Soyons fou et vérifions, la confiance n'exclue pas le contrôle comme dirait le chef
SQL> alter session set container=BATPDB; Session altered. SQL> set lines 200 SQL> col tag for a25 SQL> col CREATION_TIME for a45 SQL> select USER_ID,KEY_USE,KEYSTORE_TYPE,TAG,CREATION_TIME,BACKED_UP FROM v$encryption_keys; USER_ID KEY_USE KEYSTORE_TYPE TAG CREATION_TIME BACKED_UP ---------- ---------- ----------------- ------------------------- --------------------------------------------- --------- 0 TDE IN PDB SOFTWARE KEYSTORE BATPDB_key 19-AUG-19 01.24.55.614922 PM +00:00 NO
=> on a bien TDE activé et clé configuré sur ma pluggable BATPDB
SQL> alter session set container=ROBIN; Session altered. SQL> select USER_ID,KEY_USE,KEYSTORE_TYPE,TAG,CREATION_TIME,BACKED_UP FROM v$encryption_keys; no rows selected
=> Et on a rien sur notre seconde pluggable ROBIN.
Maintenant il s'agit d'ajouter de la donnée et de la lire pour vérifier tout cela, toujours sur la pluggable db BATPDB.
--> Pour ce test, deux tables vont être crées : l'une dans un tablespace standard et la seconde dans un tablespace crypté.
Mon user qui sera propriétaire des tables dans cette pluggable se nomme "micka".
SQL> alter session set container=BATPDB; Session altered. SQL> CREATE TABLESPACE NON_CRYPT_TBS DATAFILE SIZE 1M autoextend off; Tablespace created. SQL> CREATE TABLESPACE ENCRYPT_TBS DATAFILE SIZE 100M autoextend off ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT); Tablespace created. SQL> alter user micka quota unlimited on ENCRYPT_TBS; User altered. SQL> alter user micka quota unlimited on NON_CRYPT_TBS; User altered. [oracle@ora-batman admin]$ sqlplus micka@BATPDB; SQL*Plus: Release 12.2.0.1.0 Production on Mon Aug 19 16:41:30 2019 Copyright (c) 1982, 2016, Oracle. All rights reserved. Enter password: Last Successful login time: Mon Aug 19 2019 16:41:19 +02:00 Connected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production SQL> show con_name CON_NAME ------------------------------ BATPDB SQL> CREATE TABLE bat_test ( id NUMBER(10), data VARCHAR2(50) ) TABLESPACE NON_CRYPT_TBS; Table created. SQL> INSERT INTO bat_test VALUES (1, 'This is not a secret'); 1 row created. SQL> COMMIT; Commit complete. SQL> CREATE TABLE bat_test_crypt ( id NUMBER(10), data VARCHAR2(50) ) TABLESPACE ENCRYPT_TBS; Table created. SQL> INSERT INTO bat_test_crypt VALUES (1, 'This is BATMAN !!'); 1 row created. SQL> COMMIT; Commit complete.
Je vérifie, sachant que puisque le keystore est ouvert je dois avoir accès à ma donnée :
SQL> select a.data from bat_test a ; DATA -------------------------------------------------- This is not a secret SQL> select b.data from bat_test_crypt b ; DATA -------------------------------------------------- This is BATMAN !!
Maintenant, je désactive l'autologin du keystore, et je relance ma base pour qu'il ne soit plus ouvert (et oui, on ne peux pas fermer un keystore si l'autologin est configuré)
SQL> conn / as sysdba Connected. SQL> !mv /oracle/admin/BATMAN/keystore/cwallet.sso /oracle/admin/BATMAN/keystore/cwallet.sso.OFF SQL> shutdown Database closed. Database dismounted. ORACLE instance shut down. SQL> startup ORACLE instance started. Total System Global Area 2516582400 bytes Fixed Size 8795904 bytes Variable Size 671090944 bytes Database Buffers 1828716544 bytes Redo Buffers 7979008 bytes Database mounted. Database opened. SQL> select status from v$encryption_wallet; STATUS ------------------------------ CLOSED SQL> connect micka@BATPDB Enter password: Connected. SQL> select a.data from bat_test a ; DATA -------------------------------------------------- This is not a secret SQL> select b.data from bat_test_crypt b ; select b.data from bat_test_crypt b * ERROR at line 1: ORA-28365: wallet is not open
Bien, le keystore n'est pas ouvert je le fais donc manuellement :
SQL> conn / as sysdba Connected. SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY "Goth@M" container = ALL; keystore altered. SQL> connect micka@BATPDB Enter password: Connected. SQL> select b.data from bat_test_crypt b ; DATA -------------------------------------------------- -------------------------------------------------- This is BATMAN !!
Et voila le tour est joué ! Nous verrons dans un second article comment jouer avec Datapump et TDE, car comme je l'indiquait au début, à chaque fois qu'on met une nouvelle fonctionnalité, nous avons souvent un petit lot de changements qui va avec :-D
D'ici là, bon préparatifs de noyel et soyez sages pour avoir vos cadeaux ! :-D
Micka