Percona-PostgreSQL TDE機能(pg_tde)

Percona PostgreSQL16のTDE機能をまとめていきます
 <H1> PostgreSQL各EditionのTDE機能比較 </H1>

| Category         |       Edition     |      TDE機能有無    |
|:-----------------|:-----------------:|:------------------:|
| 有償版            |        EDB        |        あり         |
| 有償版            |     PowerGres     |       あり          |
| 無償版            |Community PostgreSQL|        なし         |
| 無償版            | Percona PostgreSQL|      あり           |
<H1> Percona PostgreSQL TDE機能概要 </H1>
    Percona PostgreSQL16以後のバージョンはTDE機能を提供されています、TDEはOption:USING pg_tdeでテーブル単位での暗号化になります。
    
    例：
    CREATE TABLE albums (
    album_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    artist_id INTEGER,
    title TEXT NOT NULL,
    released DATE NOT NULL
    ) USING pg_tde;
<H1>Percona-PostgreSQL TDE機能検証 </H1>
検証のため、RockyLinux9のVMサーバーを２台準備して、２台共に下記の手順でPostgreSQL16及びpg-tdeをinstallします。
 <br>
<H4> ・Percona PostgreSQL16 install </H4>

    # S/W install
    sudo dnf module disable postgresql llvm-toolset
    sudo yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    sudo percona-release enable-only ppg-16.2 testing
    sudo yum -y install percona-postgresql-client-common percona-postgresql-common percona-postgresql-server-dev-all percona-postgresql16 percona-postgresql16-contrib percona-postgresql16-devel percona-postgresql16-libs

<H4> ・Percona TDE install </H4>

    # TDE install
    sudo yum install percona-pg_tde_16
    
    # initial db
    sudo /usr/pgsql-16/bin/postgresql-16-setup initdb

    # start postgresql
    sudo systemctl start postgresql-16

    #version 確認
    psql --version
    psql (PostgreSQL) 16.2 - Percona Distribution
    
    
<H4> ・TDE setup </H4>

    sudo su - postgres
    psql
    postgres=# ALTER SYSTEM SET shared_preload_libraries = 'pg_tde';
    postgres=# exit
    exit

    # postgresql restart
    sudo systemctl restart postgresql-16

    sudo su - postgres
    mkdir -p /var/lib/pgsql/16/keyring

    #psqlでpostgresqlに接続
    psql
    # pg_tde extension create
    postgres=#  CREATE EXTENSION pg_tde;
    
    # TDE keyring file create
    postgres=#  SELECT pg_tde_add_key_provider_file('pgtdename','/var/lib/pgsql/16/keyring/tde.file');
    
    # TDE key create
    postgres=#  SELECT pg_tde_set_master_key('tde-20240814-1', 'pgtde-name');
    postgres=#  exit

    #keyring file confirm
    pwd
    /var/lib/pgsql/16/data/keyring
    ls -lt
    total 4
    -rw------- 1 postgres postgres 292 Aug 14 10:21 tde.file  

<H4> ・TDE 機能検証 </H4>
一台目のサーバーにてTDE暗号テーブル及びデータ作成します

    # TDE暗号化テーブル作成
    CREATE TABLE albums_tde (
        album_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
        artist_id INTEGER,
        title TEXT NOT NULL,
        released date NOT NULL
    ) USING pg_tde;
    
    # 一件データInsert
    insert into albums_tde(artist_id,title,released) values(1,'line20240814',now());
    
    # TDE暗号化しないテーブル作成
    CREATE TABLE albums(
        album_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
        artist_id INTEGER,
        title TEXT NOT NULL,
        released date NOT NULL
    ) ;
    
    # 一件データInsert
    insert into albums(artist_id,title,released) values(1,'line20240814',now());

pg_basebackupを利用して２台目のinstanceにデータリストアします、ただTDE keyring fileはコピーしないです

    例：pg_basebackup -R -D ${PGDATA} -h source_db_ip -p port -U postgres
keyring file: /var/lib/pgsql/16/keyring/tde.file コピーされてないことを確認

    ls -lt /var/lib/pgsql/16/data/keyring
    total 0
<h4> ・データ確認 </H4>
データリストア先の２台目のサーバーにてデータ確認します

    #二つテーブル確認
    postgres=# \dt
           List of relations
     Schema |    Name    | Type  |  Owner
    --------+------------+-------+----------
     public | albums     | table | postgres
     public | albums_tde | table | postgres
    (2 rows)

     # TDE暗号されてないテーブルへのSELECT
    postgres=# select * from albums;
     album_id | artist_id |    title     |  released
    ----------+-----------+--------------+------------
        1 |         1 | line20240814 | 2024-08-14
    (1 row)

     # TDE暗号されているテーブルへのSELECT
    postgres=# select * from albums_tde;
    ERROR:  failed to retrieve master key "tde-20240814-1" from keyring.
 
↑ 暗号キーファイルはコピーされてない場合、TDE暗号化されてないテーブルは普通にSELECT可能だが、TDE暗号化されているテーブルにSELECTできないことを確認できました。

<H1> まとめ </H1>
Percona PostgreSQL 16 以後のバージョンはpg_tdeという拡張extensionでテーブル単位で暗号化可能になりました。

<H1> 注意点 </H1>

- TDE暗号キーファイルはユーザーデータと別のフォルダーに置く必要があります
    - 例：ユーザーデータが$PGHOME/dataの場合、キーファイルが＄PGHOME/keyringにします。
    - data配下になると、pg_rman等のバックアップツールで丸コピーされるため、暗号化意味がなくなります。
    - キーファイルのバックアップはユーザーデータファイルと別途バックアップして、別の場所に保管します。
- WALログの内部までは暗号化されません。
- pg_tdeというextensionはPercona PostgreSQL専用のため、community版では利用できません。