G.13. TDE — защитное преобразование на уровне страницы #
- G.13.1. Обзор прозрачного защитного преобразования данных (TDE)
- G.13.2. Цели TDE
- G.13.3. Механизмы работы TDE
- G.13.4. Установка
- G.13.5. Использование TDE
- G.13.6. Обновление ключей
- G.13.7. Приложения, на которые влияет pgpro_tde
- G.13.8. Ограничения
- G.13.9. TDE и HashiCorp Vault
- G.13.10. Интеграция HashiCorp Vault
- G.13.2. Цели TDE
В этом разделе рассматривается механизм TDE (Transparent Data Encoding, Прозрачное защитное преобразование данных), позволяющий реализовать защитное преобразование на уровне страниц в Postgres Pro Enterprise при помощи расширения pgpro_tde.
G.13.1. Обзор прозрачного защитного преобразования данных (TDE) #
Прозрачное защитное преобразование данных (Transparent Data Encoding, TDE) — это защитное преобразование файлов базы данных на уровне страниц.
pgpro_tde преобразовывает:
Файлы таблиц, индексы, последовательности и другие файлы отношений, включая все версии.
Журнал предзаписи (WAL).
Временные файлы, создаваемые сервером PostgreSQL во время операций сортировок при выходе за пределы объёма памяти.
Сжатые блоки данных при использовании вместе с CFS. За подробной информацией обратитесь к Подразделу G.13.5.1.
Данные преобразуются при отправке на диск.
G.13.2. Цели TDE #
С помощью защитного преобразования данных на диске TDE предотвращает несанкционированное чтение этих данных. Неавторизованные пользователи не смогут получить доступ к данным в следующих случаях:
есть доступ к архивам резервных копий
есть доступ к резервным копиям в момент записи
есть права чтения с сервера
G.13.3. Механизмы работы TDE #
G.13.3.1. Алгоритмы защитного преобразования #
Защитное преобразование данных потребляет значительную часть ресурсов процессора и усложняет процесс работы с технической поддержкой. В целях минимизации этих последствий Postgres Pro Enterprise позволяет преобразовывать лишь конфиденциальные данные путём перемещения их в специальное табличное пространство. Процесс защитного и обратного защитного преобразования происходит на лету и не приводит к недоступности СУБД для пользователей. Кроме того, он не влияет на приложения, работающие в СУБД, поскольку запросы к защищённым данным БД обрабатываются прозрачно, как если бы они не были защищены.
Для защитного и обратного защитного преобразования с помощью алгоритма AES pgpro_tde вызывает библиотеку OpenSSL. При этом используется OpenSSL, поставляемая в рамках сертифицированных ОС. Преобразование файлов данных происходит с помощью алгоритма симметричного ключа AES-256-GCM, что обеспечивает подлинность, целостность и конфиденциальность данных. Сегменты WAL же преобразовываются с помощью AES-256-CTR по LSN.
OpenSSL использует расширения к командам векторизации, например AVX-512 для GCM. Благодаря этому AES-256-GCM работает на порядок быстрее. Чтобы добиться такой высокой производительности при работе TDE, убедитесь, что ваше аппаратное и программное обеспечение по виртуализации поддерживает такие расширенные команды.
G.13.3.2. Ключи защитного преобразования #
Postgres Pro Enterprise преобразовывает файлы отношений в специальном табличном пространстве с использованием соответствующих ключей защитного преобразования для этого табличного пространства, а файлы WAL — с использованием специальных ключей защитного преобразования WAL. Эти ключи — уникальная последовательность байтов, которая хранится в защищённом файле $PGDATA/pg_encryption/keys. При запуске система обращается к внешней защитной системе, чтобы обратно преобразовать этот файл, после чего хранит эти ключи в своей памяти.
У внешней защитной системы есть свой главный ключ, который она использует для защитного преобразования и обратного защитного преобразования набора ключей для ключей табличного пространства системы и WAL. Такой главный ключ генерируется и хранится во внешней системе управления ключами. Более подробная информация описана в Подразделе G.13.10.
Для каждого кластера существует один файл с набором ключей, который называется keys, он содержит все ключи защитного преобразования для табличного пространства и WAL. Файл хранится в каталоге $PGDATA/pg_encryption. При создании новых ключей (например, после ротации) в системе вызывается внешняя защитная система, которая преобразовывает новые ключи и затем добавляет в конец того же файла. Postgres Pro Enterprise никогда не хранит ключи в текстовом, непреобразованном виде.
Для ещё большего повышения безопасности используйте ротацию ключей, что позволит ограничить данные, преобразованные одним и тем же ключом защитного преобразования табличного пространства. При ротации генерируется новый ключ табличного пространства, который используется для преобразования всех новых данных. Старые данные всё ещё могут быть обратно преобразованы с помощью старого ключа, с которым они были преобразованы. При обновлении страницы файла с данными они заново преобразовываются, уже с новым ключом. Ротация ключей происходит на лету и не требует перезапуска сервера. Чтобы ротировать отдельные ключи табличных пространств, выполните одну из этих команд:
SELECT pg_rotate_encryption_key(tablespace oid)
Или
select pg_rotate_encryption_key((select oid from pg_tablespace where spcname='my-encrypted-tablespace-name'))
G.13.4. Установка #
Расширение pgpro_tde поставляется в рамках Postgres Pro Enterprise как отдельный пакет pgpro-tde-ent. Для включения pgpro_tde выполните следующие шаги:
Добавьте имя библиотеки в параметр
shared_preload_librariesв файлеpostgresql.conf:shared_preload_libraries = 'pgpro_tde'
Обратите внимание, что названия библиотек в переменной
shared_preload_librariesдолжны идти в определённом порядке.Перезагрузите сервер БД, чтобы изменения вступили в силу.
Чтобы проверить, что библиотека
pgpro_tdeуспешно установлена, запустите следующую команду:SHOW shared_preload_libraries;
Перед запуском pgpro_tde настройте любую внешнюю систему управления ключами. В целях демонстрации будет использоваться HashiCorp Vault. Более подробная информация представлена в Подразделе G.13.10.
Разрешите кластеру Postgres Pro Enterprise доступ к внешней системе управления ключами.
Остановите ведущий и резервный сервера.
Примените файлы WAL на резервные сервера.
Обновите файл
postgresql.confс информацией изPGDATA/pg_encryption/keysи следующими параметрами:encryption=on encryption_key_wrap_command = ... encryption_key_unwrap_command = ...
postgresql.confнеобходимо изменить на ведущем и всех резервных серверах. За подробной информацией и инструкцией по настройке на примере HashiCorp обратитесь к данному разделу.Запустите ведущий сервер. После запуска файлы WAL будут преобразованы в соответствующих каталогах
$PGDATA/pg_wal.Скопируйте файл
$PGDATA/pg_encryption/keysс ведущего сервера в каталогиpg_encryptionвсех резервных серверов.Запустите резервные сервера. После запуска файлы WAL в каталогах
$PGDATA/pg_walбудут преобразованы с тем же ключом WAL, что и на ведущем сервере. Это позволяет обмениваться преобразованными записями WAL между ведущим и резервными серверами.
Необходимо выполнять резервное копирование файла PGDATA/pg_encryption/keys и файлов метаданных (файлы с суффиксом -tde, которые хранят информацию о защитном преобразовании), поскольку в случае их потери прочесть преобразованные файлы будет невозможно.
G.13.5. Использование TDE #
pgpro_tde можно включить только для отдельных табличных пространств. Чтобы преобразовать табличное пространство, включите параметр encryption при создании нового табличного пространства. Например:
CREATE TABLESPACE secure_tablespace LOCATION '/My/Data/Dir' WITH (encryption=on);
Параметр защитного преобразования табличного пространства нельзя изменить после того, как он был задан. Поэтому нельзя преобразовать табличное пространство, если в нём уже находятся данные в чистом виде, или обратно преобразовать табличное пространство, в котором уже находятся защищённые данные.
Чтобы преобразовать таблицу, поместите её в преобразованное табличное пространство с помощью команды ALTER TABLE имя_таблицы SET TABLESPACE преобразованное_табличное_пространство;. Для этого понадобятся права владельца таблицей и право использования данного табличного пространства. Однако достаточно обычных прав на такие таблицы, чтобы использовать операторы SELECT, UPDATE, INSERT, UPDATE, DELETE и TRUNCATE для их непреобразованных данных.
Если это первая операция по защитному преобразованию для данного табличного пространства, то сервером будет создан первый ключ защитного преобразования табличного пространства. Ведущий сервер отправляет этот ключ через специальную запись в файле WAL на все резервные сервера, чтобы применить на них к соответствующим табличным пространствам.
Обратите внимание, что все новые ключи защитного преобразования автоматически реплицируются с ведущего сервера на резервные.
Чтобы произвести обратное защитное преобразование таких данных, переместите их из защищённого табличного пространства в любое другое.
Вы можете проверить, включено ли pgpro_tde на сервере, с помощью запроса \db+, который выводит список табличных пространств. У защищённых табличных пространств будет задано значение encrypted=on. Например:
postgres=# \db+
List of tablespaces
Name | Owner | Location | Access privileges | Options | Size | Description
------------+----------+------------------------------------------+-------------------+-----------------+--------+-------------
encrypted | postgres | /var/lib/pgpro/ent-17/meta/pg_encryption | | {encryption=on} | 68 kB |
pg_default | postgres | | | | 22 MB |
pg_global | postgres | | | | 667 kB |
(3 rows)G.13.5.1. Совместное использование TDE и CFS #
TDE и Сжатую файловую систему (CFS) можно использовать вместе, благодаря чему данные в одном табличном пространстве могут быть одновременно преобразованы и сжаты.
Чтобы создать защищённое табличное пространство со сжатием, при его создании включите оба параметра — encryption и compression. Например:
CREATE TABLESPACE secure_tablespace LOCATION '/var/data/encryption' WITH (encryption=true, compression=true);
Все таблицы, создаваемые в этом табличном пространстве, будут защищены преобразованием и сжиматься с использованием алгоритма zstd по умолчанию.
Вместо значения true можно явно указать алгоритм сжатия. Возможные значения: zstd, default (действует так же, как zstd), pglz, zlib и lz4. Например, чтобы использовать zlib, создайте табличное пространство так:
CREATE TABLESPACE secure_tablespace LOCATION '/var/data/encryption' WITH (encryption=true, compression='zlib');
За подробной информацией о параметре compression и доступных алгоритмах сжатия обратитесь к Главе 33.
Примечание
В настоящее время pg_rewind нельзя использовать в табличных пространствах, которые одновременно и защищены преобразованием, и сжаты. За полным списком ограничений обратитесь к Подразделу G.13.8.
G.13.6. Обновление ключей #
G.13.6.1. Обновление главного ключа #
Если у вашего главного ключа истёк срок жизни или он был скомпрометирован, необходимо сгенерировать и применить новый главный ключ. В зависимости от выбранного решения это можно сделать по-разному. В демонстрационных целях используется HashiCorp Vault.
В Postgres Pro Enterprise ключи хранятся в каталоге ${PGDATA}/pg_encryption/keys. В целях безопасности все ключи этого файла преобразованы с помощью главного ключа, хранящегося в HashiCorp Vault. Для настройки хранилища необходим адрес приёмника и токен экземпляра. Установка производится через переменные окружения, в качестве примера приведены VAULT_ADDR и VAULT_TOKEN:
echo VAULT_ADDR='http://127.0.0.1:8200' > /etc/env.d/99vault echo VAULT_TOKEN="hvs.C77DySgOTjliYqmtp3yA4osP" >> /etc/env.d/99vault
Включить транзит с помощью HashiCorp Vault Transit Secrets Engine:
vault secrets enable transit
Создать новый ключ и задать ему новое уникальное имя:
vault write -f transit/keys/pg-tde-new-master-key
Когда новый ключ готов, необходимо заново преобразовать ваш файл ключей с помощью нового главного ключа:
cat keys | vault write -field=plaintext transit/decrypt/pg-tde-master-key ciphertext=- | vault write -field=ciphertext transit/encrypt/pg-tde-new-master-key plaintext=- > keys
По умолчанию HashiCorp Vault работает с 256-битными ключам. При необходимости работы с другими ключами обратитесь к администратору сервера HashiCorp Vault для изменения конфигурации.
G.13.6.2. Обновление ключей табличного пространства #
Для обновления ключей табличного пространства администратор СУБД должен вызывать функцию pg_rotate_encryption_key с oid табличного пространства для генерации нового ключа:
postgres=# \db+
List of tablespaces
Name | Owner | Location | Access privileges | Options | Size | Description
------------+----------+------------------------------------------+-------------------+-----------------+--------+-------------
encrypted | postgres | /var/lib/pgpro/ent-17/meta/pg_encryption | | {encryption=on} | 68 kB |
pg_default | postgres | | | | 22 MB |
pg_global | postgres | | | | 667 kB |
(3 rows)
postgres=# select * from pg_tablespace where spcname='encrypted';
oid | spcname | spcowner | spcacl | spcoptions
-------+-----------+----------+--------+-----------------
24587 | encrypted | 10 | | {encryption=on}
(1 row)
postgres=# select pg_rotate_encryption_key(24587);
pg_rotate_encryption_key
--------------------------
t
(1 row)G.13.7. Приложения, на которые влияет pgpro_tde #
У следующих приложений есть параметры, специфичные для TDE, что обеспечивает особую обработку данных в файлах БД: pg_rewind и pg_waldump с параметром -D.
Каждое из них может работать как с защищёнными данными, так и с обычными. Они обнаруживают команды warp/unwarp и параметры защитного преобразования в файле postgresql.conf. Далее они находят файл postgresql.conf в каталоге данных (задаётся через PGDATA/). Если каталог PGDATA/ не задан или является некорректным, его можно задать с помощью -D --pgdata. Такой подход обеспечивает максимальный уровень обратной совместимости с незащищённым режимом.
G.13.8. Ограничения #
Работа с pg_probackup ограничена следующими операциями при значении
encryption=on:Резервное копирование в режимах FULL и DELTA с помощью режима ARCHIVE WAL
Восстановление кластера (с указанием резервной копии и без)
Проверка резервных копий (с параметром
--walили без)Слияние резервных копий FULL и DELTA с параметром
--merge-expired, что объединяет самую старую инкрементальную копию, удовлетворяющую требованиям политики хранения, с её родительскими копиями, срок хранения которых истёк.
Восстановление на момент времени (PITR), а также восстановление по указанным LSN или XID поддерживаются на главном и резервных серверах, но не поддерживаются для удалённого режима работы pg_probackup.
Даже при включённом расширении pgpro_tde утилита pg_dump использует для извлечения данных из базы данных команду
SELECT, получая тем самым непреобразованные данные. Это значит, что pg_dump всегда сохраняет данные в чистом виде. Чтобы выполнить резервное копирование преобразованных данных, используйте pg_basebackup или pg_probackup.Нет поддержки pg_transfer.
Утилита pg_rewind не может использоваться в табличных пространствах, которые одновременно и преобразованы с помощью pgpro_tde, и сжаты.
G.13.9. TDE и HashiCorp Vault #
В данном разделе описана интеграция прозрачного защитного преобразования данных (TDE) с внешней системой управления ключами HashiCorp Vault.
G.13.10. Интеграция HashiCorp Vault #
G.13.10.1. Создание главного ключа и конфигурация Pro Enterprise #
В Postgres Pro Enterprise ключи хранятся в каталоге ${PGDATA}/pg_encryption/keys. В целях безопасности все ключи этого файла преобразованы с помощью главного ключа, хранящегося в HashiCorp Vault.
Для настройки хранилища необходим адрес приёмника и токен экземпляра. Установка производится через переменные окружения, в качестве примера приведены VAULT_ADDR и VAULT_TOKEN:
echo VAULT_ADDR='http://127.0.0.1:8200' > /etc/env.d/99vault echo VAULT_TOKEN="hvs.C77DySgOTjliYqmtp3yA4osP" >> /etc/env.d/99vault
Включит транзит с помощью HashiCorp Vault Transit Secrets Engine:
vault secrets enable transit
Создайте ключ и назовите его:
vault write -f transit/keys/pg-tde-master-key
По умолчанию HashiCorp Vault работает с 256-битными ключам. При необходимости работы с другими ключами обратитесь к администратору сервера HashiCorp Vault для изменения конфигурации.
G.13.10.2. Тестирование TDE #
Чтобы убедиться в верности конфигурации, запустите экспресс-тесты:
Подключитесь к
psqlс правами суперпользователя и запустите одну из следующих команд:ALTER SYSTEM SET encryption_key_wrap_command='base64 | vault write -field=ciphertext transit/encrypt/pg-tde-master-key plaintext=- > %p'; ALTER SYSTEM SET encryption_key_unwrap_command='cat %p | vault write -field=plaintext transit/decrypt/pg-tde-master-key ciphertext=- | base64 --decode';
Перезапустите сервер командой
pg_ctl restart, чтобы изменения вступили в силу.Когда сервер запустится, выполните следующие команды:
CREATE TABLESPACE encrypted LOCATION ':PGDATA/encrypted_ts'; ALTER TABLESPACE encrypted SET (encryption=on); CREATE TABLE test_table TABLESPACE encrypted AS (SELECT * FROM generate_series(1, 100) AS col1);
Если всё настроено правильно, в >${PGDATA}/pg_encryption/encryption_keys будут такие данные:
vault:v1:rdaF+sSfkKn9HBzdalat7mnynRRR6b00FQS159PCUMGmMZJYMNm/hWxbFFIeV8C43nO3UV4dmgn7pxnJkwo4IYq2+sUHSWT/
G.13.10.3. Рекомендации по установке HashiCorp Vault #
Предполагается, что HashiCorp Vault уже интегрирован вашей компанией и управляется администраторами. Однако в целях тестирования может понадобится отдельный экземпляр сервера с хранилищем, которое настроено специально под работу с Postgres Pro Enterprise TDE.
G.13.10.3.1. Установка HashiCorp Vault #
Настоятельно рекомендуется использовать репозиторий вашей ОС для установки HashiCorp Vault. Для Ubuntu:
apt-get install -y wget net-tools apt-transport-https wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor > /tmp/hashicorp.gpg mv /tmp/hashicorp.gpg /etc/apt/trusted.gpg.d/ chown root:root /etc/apt/trusted.gpg.d/hashicorp.gpg chmod ugo+r /etc/apt/trusted.gpg.d/hashicorp.gpg chmod go-w /etc/apt/trusted.gpg.d/hashicorp.gpg echo "deb https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list apt-get update apt-get install vault
После установки команда vault --version вернёт текущую версию хранилища, например:
Vault v1.15.6, built 2024-09-17T15:25:10Z
Вы также можете запустить временное тестовое хранилище с ограниченным сроком работы в среде разработки. Для этого запустите команду vault server -dev в отдельной командной строке. Обратите внимание, что любые данные на таком экземпляре ограничены временем работы обслуживающего процесса. При каждом запуске такого тестового хранилища генерируется новый ключ распечатки, что создаёт новый корневой токен, заданный в переменной VAULT_TOKEN.
Для постоянного хранилища необходимо настроить службу так, чтобы она запускалась автоматически. Для операционных систем на базе openrc и systemd команды конфигурации будут отличаться. Для Ubuntu:
systemctl enable vault --now
Для получения статуса службы:
systemctl status vault
G.13.10.3.2. Конфигурация HashiCorp Vault #
Служба хранилища требует минимального ручного вмешательства. Ей требуется только указать обслуживающий процесс. По умолчанию приёмник будет доступен по протоколу HTTPS. Его можно переключить на HTTP или отключить аутентификацию для CLI. При работе по протоколу HTTPS самоподписанный сертификат не проходит проверку, поэтому его нужно отключить:
typeset -x VAULT_SKIP_VERIFY=true
Ниже приведён пример правильной конфигурации:
api_addr = "https://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8210"
cluster_name = "local-vault-cluster"
disable_mlock = true
ui = true
backend "raft" {
node_id = "local-vault-server"
path = "/var/lib/vault"
}
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8210"
tls_cert_file = "/var/lib/vault/cert.pem"
tls_key_file = "/var/lib/vault/key.pem"
}
listener "tcp" {
address = "127.0.0.1:8201"
cluster_address = "127.0.0.1:8210"
tls_disable = 1
}Для создания самоподписанного сертификата:
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 \
-nodes -keyout /var/lib/vault/key.pem -out /var/lib/vault/cert.pem \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"При такой конфигурации необходимо, чтобы каталог /var/lib/vault был доступен для чтения и записи тем пользователям, под которыми запущена служба. При этом raftdb задаётся в качестве обслуживающего процесса с двумя приёмниками: локальным и глобальным с TLS.
Чтобы распечатать службу перед запуском необходимо получить ключ и корневой токен:
vault operator init -key-shares=1 -key-threshold=1 vault operator unseal key
После этого необходимо авторизовать CLI:
vault login token
После этого шага VAULT_TOKEN для CLI больше не требуется. По его завершении хранилище готово к работе с TDE.
G.13. TDE — enable page level encryption #
This section describes the Transparent Data Encryption (TDE) feature, which enables page level encryption in Postgres Pro Enterprise with the pgpro_tde extension.
G.13.1. Transparent Data Encryption (TDE) Overview #
Transparent Data Encryption (TDE) is encryption of the database files that is done at the page level.
pgpro_tde encrypts:
Files of the tables, indexes, sequences and other relations files including all forks.
Write-ahead log (WAL).
Temporary files that PostgreSQL server creates during its data processing for operations, such as sorting data that exceeds its memory limit.
Compressed data blocks, when used together with CFS. For more information, refer to Section G.13.5.1.
Data is encrypted when it is sent to the disk.
G.13.2. Why Use TDE? #
TDE prevents unauthorized viewing of data with encrypting data on disk. Unauthorized users can't access data if they:
have access to backup archives
had access to backups while they were being written
have reading privilege to a server
G.13.3. How Does TDE Work? #
G.13.3.1. Encryption Algorithms #
Data encryption consumes a significant part of the CPU resources and adds complexity to collaboration with technical support. To minimize these repercussions, Postgres Pro Enterprise allows encrypting only confidential data by moving them to special tablespaces. Encryption and decryption processes happen on the fly and do not cause any DBMS unavailability for the users. It also doesn't affect applications, working with DBMS, as all the queries to the DB encrypted data is processed transparently, as if it was unencrypted.
pgpro_tde calls an OpenSSL library to encrypt and decrypt data with AES algorithm. It uses OpenSSL, provided within the certified OS. It encrypts data files using the AES-256-GCM symmetric key algorithm that provides both data authenticity (integrity) and confidentiality. It encrypts WAL files using AES-256-CTR, incorporating LSN (log sequence number) as the counter component.
OpenSSL utilizes vectorization command extensions like AVX-512 for GCM encryption method. With this extension AES-256-GCM gets a dramatic performance boost. Check if your hardware and virtualization software support this extended commands set to ensure superior TDE performance.
G.13.3.2. Encrypting Keys #
Postgres Pro Enterprise encrypts relation files in the dedicated tablespaces using respective tablespace encryption keys, and encrypts WAL files using a special WAL encryption key. These keys are unique sequences of bytes and the system keeps them securely encrypted in the $PGDATA/pg_encryption/keys file. On start-up, the system calls for an external security system to decrypt this file data and then keeps these keys in its memory.
The external security system, mentioned above, has its own main master key, which it uses to encrypt and decrypt keyset of the system's tablespace and WAL encryption keys. The master key is generated by and stored in an external key management system. For more details, see Section G.13.10.
There is one key set file per cluster named keys that contains all the tablespace and WAL encryption keys. The system keeps it located under the $PGDATA/pg_encryption folder. When new keys are created (e.g. after rotation), the system calls an external system to encrypt them and stores them at the end of the same file. Postgres Pro Enterprise never stores the keys in plaintext without encryption.
To boost security even more, mind the key rotation that allows limiting the data encrypted with a single tablespace encryption key. Rotation generates a new tablespace key, which encrypts all the new data. The old data is still available encrypted by means of the old keys it was encrypted with. When the DBMS updates a data file page, it re-encrypts it with a new key. Keys rotation occurs on-the-fly and doesn't require restarting the database server. To rotate a specific tablespace keys, run this command:
SELECT pg_rotate_encryption_key(tablespace oid)
Or
select pg_rotate_encryption_key((select oid from pg_tablespace where spcname='my-encrypted-tablespace-name'))
G.13.4. Installation #
The pgpro_tde extension is provided with Postgres Pro Enterprise as a separate package pgpro-tde-ent. To enable pgpro_tde, complete the following steps:
Add the library name to the
shared_preload_librariesparameter in thepostgresql.conffile:shared_preload_libraries = 'pgpro_tde'
Note that the library names in the
shared_preload_librariesvariable must be added in the specific order.Reload the database server for the changes to take effect.
To verify that the
pgpro_tdelibrary was installed correctly, you can run the following command:SHOW shared_preload_libraries;
Before enabling pgpro_tde, set up your external key management system of your choice. For the purposes of this manual, HashiCorp Vault is used. For more details, see Section G.13.10.
Allow Postgres Pro Enterprise cluster access your external key management system.
Stop your master and standby servers.
Apply all the WAL files on standby servers.
Update your
postgresql.confwithPGDATA/pg_encryption/keysinformation and the following parameters:encryption=on encryption_key_wrap_command = ... encryption_key_unwrap_command = ...
postgresql.confmust be modified both on your master and all its standby servers. For more details on this configuration for HashiCorp as an example, refer to this section.Start the master server. Once started, they will encrypt WAL files in their respective
$PGDATA/pg_waldirectories.Copy
$PGDATA/pg_encryption/keysfile from the master server to thepg_encryptiondirectories of all its standby servers.Start standby servers. Once started, they encrypt the WAL files in their
$PGDATA/pg_waldirectories with the same WAL key as the master server. It allows exchanging WAL encrypted records between master and standby servers.
PGDATA/pg_encryption/keys and meta data files (-tde files that store encryption-specific information) require back up, as in case of loss you will not be able to read the encrypted files.
G.13.5. Using TDE #
pgpro_tde can only be enabled for separate tablespaces. To encrypt a tablespace, you should enable the encryption option when creating this tablespace. For example:
CREATE TABLESPACE secure_tablespace LOCATION '/My/Data/Dir' WITH (encryption=on);
Once set, the tablespace encryption option cannot be altered, so you cannot encrypt or decrypt a tablespace that already has encrypted or clear data files.
To encrypt a table, you should move it to an encrypted tablespace using ALTER TABLE name SET TABLESPACE encrypted_tablespace;. For this you must have the owner permissions of the table and privileges to use this encrypted tablespace. However, operating with decrypted data of these tables is possible with just having regular permissions for the SELECT, UPDATE, INSERT, UPDATE, DELETE, and TRUNCATE statements.
If this is the first encryption operation on the tablespace, then the server creates the first tablespace encryption key. Master server sends this key via a special WAL file record to all the standby servers for applying to the corresponding tablespaces there.
Note that the new encryption keys are replicated from the primary server to its standby servers with no additional action required.
To decrypt this data, move it from an encrypted tablespace to any other tablespace that is not yet encrypted.
You can find out whether pgpro_tde is enabled on a server by querying \db+ that will result in a list of tablespaces. The encrypted tablespaces have encrypted=on value. For example:
postgres=# \db+
List of tablespaces
Name | Owner | Location | Access privileges | Options | Size | Description
------------+----------+------------------------------------------+-------------------+-----------------+--------+-------------
encrypted | postgres | /var/lib/pgpro/ent-17/meta/pg_encryption | | {encryption=on} | 68 kB |
pg_default | postgres | | | | 22 MB |
pg_global | postgres | | | | 667 kB |
(3 rows)
G.13.5.1. Using TDE and CFS Together #
TDE and the Compressed File System (CFS) can be used together, allowing data in the same tablespace to be both encrypted and compressed.
To create an encrypted tablespace with compression enabled, specify both the encryption and compression options when creating the tablespace. For example:
CREATE TABLESPACE secure_tablespace LOCATION '/var/data/encryption' WITH (encryption=true, compression=true);
All tables created in this tablespace will be both encrypted and compressed using zstd, which is the default compression library.
Instead of true, you can explicitly specify the compression algorithm. The supported values are zstd, default (same as zstd), pglz, zlib, and lz4. For example, to use zlib, create the tablespace as follows:
CREATE TABLESPACE secure_tablespace LOCATION '/var/data/encryption' WITH (encryption=true, compression='zlib');
For more information about the compression option and available compression algorithms, refer to Chapter 33.
Note
pg_rewind cannot be currently used for tablespaces that are both encrypted and compressed. For the full list of limitations, refer to Section G.13.8.
G.13.6. Updating Keys #
G.13.6.1. Updating Master Key #
If your master key expired or was compromised, a new master key must be generated and applied. The way it can be done depends on your selected solution. For demonstration purposes, HashiCorp Vault is used.
Postgres Pro Enterprise stores keys under ${PGDATA}/pg_encryption/keys. For safety purposes, all the keys in this file are encrypted with a master key that is stored in the HashiCorp Vault. To set the vault up, the listener address and the instance token are required. The setup is done with the environment variables, here VAULT_ADDR and VAULT_TOKEN are given as an example:
echo VAULT_ADDR='http://127.0.0.1:8200' > /etc/env.d/99vault echo VAULT_TOKEN="hvs.C77DySgOTjliYqmtp3yA4osP" >> /etc/env.d/99vault
Enable transit with HashiCorp Vault Transit Secrets Engine:
vault secrets enable transit
Create a new key and give it a new unique name:
vault write -f transit/keys/pg-tde-new-master-key
When a new key is issued, you should re-encrypt your keyset file with the new master key.
cat keys | vault write -field=plaintext transit/decrypt/pg-tde-master-key ciphertext=- | vault write -field=ciphertext transit/encrypt/pg-tde-new-master-key plaintext=- > keys
By default, HashiCorp Vault works with the 256-bit keys. If any other keys are required, address HashiCorp Vault server admins to update the settings.
G.13.6.2. Updating Tablespace Keys #
To update your tablespace keys, the DBMS admin must call the SQL function pg_rotate_encryption_key with a tablespace oid to generate a new key:
postgres=# \db+
List of tablespaces
Name | Owner | Location | Access privileges | Options | Size | Description
------------+----------+------------------------------------------+-------------------+-----------------+--------+-------------
encrypted | postgres | /var/lib/pgpro/ent-17/meta/pg_encryption | | {encryption=on} | 68 kB |
pg_default | postgres | | | | 22 MB |
pg_global | postgres | | | | 667 kB |
(3 rows)
postgres=# select * from pg_tablespace where spcname='encrypted';
oid | spcname | spcowner | spcacl | spcoptions
-------+-----------+----------+--------+-----------------
24587 | encrypted | 10 | | {encryption=on}
(1 row)
postgres=# select pg_rotate_encryption_key(24587);
pg_rotate_encryption_key
--------------------------
t
(1 row)
G.13.7. Applications Affected by pgpro_tde #
The following applications have a TDE-specific option, allowing special processing of data in database data files: pg_rewind and pg_waldump with the -D option.
Any of them can be used with both encrypted and unencrypted data. They find warp/unwarp commands and encryption options under the postgresql.conf file. Then they find postgresql.conf under the data directory (defined under PGDATA/). If PGDATA/ is not specified or corrupted, it can be defined with -D --pgdata. This approach provides the highest level of the backward compatibility with unencrypted mode.
G.13.8. Limitations #
Work with pg_probackup is limited to the following operations when
encryption=on:Taking FULL or DELTA backups with the ARCHIVE WAL delivery mode
Restoring a cluster (both with specifying the backup and without)
Validating backups (with or without the
--waloption)Merging FULL and DELTA backups with
--merge-expiredthat merges the oldest incremental backup that satisfies the requirements of retention policy with its parent backups that have already expired.
Point-in-time recovery (PITR) and restoring with the specified LSN or XID are supported on primary and standby servers but are not supported for the pg_probackup remote mode.
Even if pgpro_tde is enabled, pg_dump uses
SELECTto retrieve data from a database, thus accessing decrypted information. This means pg_dump always saves clear data. To perform encrypted backups, use pg_basebackup or pg_probackup.Using pg_transfer is not supported.
pg_rewind cannot be used for tablespaces that are both encrypted by pgpro_tde and compressed.
G.13.9. TDE and HashiCorp Vault #
This section describes the Transparent Data Encryption (TDE) integration with the external key management system of HashiCorp Vault.
G.13.10. HashiCorp Vault integration #
G.13.10.1. How to Create Master Key And Configure Pro Enterprise #
Postgres Pro Enterprise stores keys under ${PGDATA}/pg_encryption/encryption_keys. For safety purposes, all the keys in this file are encrypted with a master key that is stored in the HashiCorp Vault.
To set the vault up, the listener address an the instance token are required. The setup is done with the environment variables, here VAULT_ADDR and VAULT_TOKEN are given as an example:
echo VAULT_ADDR='http://127.0.0.1:8200' > /etc/env.d/99vault echo VAULT_TOKEN="hvs.C77DySgOTjliYqmtp3yA4osP" >> /etc/env.d/99vault
Enable transit with HashiCorp Vault Transit Secrets Engine:
vault secrets enable transit
Create a key and give it a name:
vault write -f transit/keys/pg-tde-master-key
By default, HashiCorp Vault works with the 256-bit keys. If any other keys are required, address HashiCorp Vault server admins to update the settings.
G.13.10.2. Testing TDE #
To make sure everything is set up properly, run express tests:
Access
psqlwith superuser privileges and run the following commands:ALTER SYSTEM SET encryption_key_wrap_command='base64 | vault write -field=ciphertext transit/encrypt/pg-tde-master-key plaintext=- > %p'; ALTER SYSTEM SET encryption_key_unwrap_command='cat %p | vault write -field=plaintext transit/decrypt/pg-tde-master-key ciphertext=- | base64 --decode';
Restart the server with
pg_ctl restartfor the changes to take effect.Once the server is up, run these commands:
CREATE TABLESPACE encrypted LOCATION ':PGDATA/encrypted_ts'; ALTER TABLESPACE encrypted SET (encryption=on); CREATE TABLE test_table TABLESPACE encrypted AS (SELECT * FROM generate_series(1, 100) AS col1);
If set up correctly, >${PGDATA}/pg_encryption/encryption_keys will contain this type of data:
vault:v1:rdaF+sSfkKn9HBzdalat7mnynRRR6b00FQS159PCUMGmMZJYMNm/hWxbFFIeV8C43nO3UV4dmgn7pxnJkwo4IYq2+sUHSWT/
G.13.10.3. HashiCorp Vault Setup Recommendations #
It is advised that HashiCorp Vault is already integrated and managed by our company admins. However, for testing purposes you may need an independent instance of the vault server that is configured for the Postgres Pro Enterprise TDE specifically.
G.13.10.3.1. HashiCorp Vault Installation #
It is highly recommended to use your OS repository to install HashiCorp Vault. For Ubuntu:
apt-get install -y wget net-tools apt-transport-https wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor > /tmp/hashicorp.gpg mv /tmp/hashicorp.gpg /etc/apt/trusted.gpg.d/ chown root:root /etc/apt/trusted.gpg.d/hashicorp.gpg chmod ugo+r /etc/apt/trusted.gpg.d/hashicorp.gpg chmod go-w /etc/apt/trusted.gpg.d/hashicorp.gpg echo "deb https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list apt-get update apt-get install vault
After installation vault --version returns the current version of the vault, for example:
Vault v1.15.6, built 2024-09-17T15:25:10Z
You can also run a temporary test vault in dev environment with a limited time-to-life by running vault server -dev in a separate command line. Note that any data on this instance is limited by the backend process time. Each time this dev vault is started, a new unseal key is generated, which creates a new root token specified under the VAULT_TOKEN variable.
For a persistent vault, configure the vault service to run automatically. The configuration commands are different for openrc-based and systemd-based OS. For Ubuntu:
systemctl enable vault --now
To get service status:
systemctl status vault
G.13.10.3.2. HashiCorp Vault Configuration #
Vault service requires minimum manual configuration. It only needs a backend specified. By default, the listener is available via HTTPS. You can switch to HTTP or disable authentication for CLI. In case of using HTTPS the self-signed certificate will not pass verification, so the latter should be disabled:
typeset -x VAULT_SKIP_VERIFY=true
Below is an example of the valid configuration:
api_addr = "https://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8210"
cluster_name = "local-vault-cluster"
disable_mlock = true
ui = true
backend "raft" {
node_id = "local-vault-server"
path = "/var/lib/vault"
}
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8210"
tls_cert_file = "/var/lib/vault/cert.pem"
tls_key_file = "/var/lib/vault/key.pem"
}
listener "tcp" {
address = "127.0.0.1:8201"
cluster_address = "127.0.0.1:8210"
tls_disable = 1
}
To create self-signed certificate:
openssl req -x509 -newkey rsa:4096 -sha256 -days 365 \
-nodes -keyout /var/lib/vault/key.pem -out /var/lib/vault/cert.pem \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
This configuration requires the directory /var/lib/vault to be available for reading and writing for the user this service runs under. raftdb is defined as a backend, with two listeners: local and global with TLS.
To unseal the service before start, receive the key and the root token:
vault operator init -key-shares=1 -key-threshold=1 vault operator unseal key
Then authorize CLI:
vault login token
VAULT_TOKEN for CLI is not required after this step. Once done, the vault is ready to be used with TDE.