QSS Secure Storage Module
QSS (Quantum Secure Storage) is a DBMS «Quantum Hybrid Base» secure storage module that allows you to create tables that are encrypted using the "Kuznechik" cryptoalgorithm (GOST 34.12-2018) in MGM mode (R 1323565.1.026–2019) when writing to disk.
Description
Encryption is performed by separate software — the Cryptographic Information Protection Facility (CIPF) Quantum Secure Storage (QSS).
Note
This product is purchased and licensed separately.
The QSS server can be installed either simultaneously with QHB, or after, i.e. you can install and start to use QSS when QHB is already in operation.
The QSS server should be run on the same host as the QHB server, otherwise there can be a significant performance decrease. The client libraries required for QHB to interact with QSS are installed in the same package as the QSS server. The user as which the QHB runs, must be added to a special group qss-client (the group is created automatically when installing QSS). You should also create a working key in QSS, which will be used for encryption.
See the QSS documentation for detailed information on how to install, configure QSS, and create keys in it.
Usage
Capabilities
Encryption executes at the table level. Enabling table encryption also includes encryption of indexes on this table, the associated TOAST table, and WAL messages about actions in this table. However, columns of certain types that are not stored in the table's main file or in TOAST table (e.g., large objects (LOBs), type rbytea) will not be encrypted.
See the Rbytea description for information on how to enable RBytea encryption.
Encryption of individual columns is not implemented and unreasonable, since the encryption overhead is essentially independent of the length of the encrypted blocks.
Encryption of the materialized view is also implemented. It is recommend to use the materialized view encryption if it contains encrypted data. However, note that data encryption is not automatically enabled when creating an encrypted materialized view.
Catalog table encryption cannot be enabled (for example, encrypting the text of stored procedures in SQL).
IMPORTANT!
If the encrypted table has DEFAULT CONSTRAINT, then the default value is stored in the catalog in unencrypted form. The same is true for text of triggers that fill the encrypted table.
Also, you cannot enable encryption of partitioned tables.
Data on disk and in the operating system cache is encrypted (and this is an advantage over disk-level encryption), data in QHB memory is not encrypted, because it requires online access.
Copying an encrypted table from a template database to a new database during
CREATE DATABASE is not supported; in particular, you cannot create encrypted
tables in the database template1.
Configuration Parameters
The QSS settings are located in a separate configuration file qss2_config.toml; example file is generated during cluster initialization (using initdb).
key = "key_name" # ID of the key existing in QSS, which will be used for encryption
shmem = true # whether encryption will be performed via shared memory
provider = "compressed-append" # "compressed-append" or "two-phase" – method to store nonce and tag attributes of encrypted pages in QHB files
socket_address = "/run/qss/client.socket" # for communication with the qss server; there is no need to change this when installing QSS by default
It is not recommended to change the shmem and provider parameters without consulting with technical support, since the default values provide the best performance. The provider parameter cannot be changed when there is already encrypted data.
In the main configuration file, the use of QSS is enabled by the parameter qss_mode = 2 (historically this is an integer parameter, valid values are 2 and 0).
-
When running with qss_mode = 2, the validity of the QSS configuration is checked, and if any problems are detected, QHB is not started.
-
Running with qss_mode = 0 when there are encrypted tables is allowed, but it will be impossible to access encrypted tables.
Table Creating
When creating a table or materialized view, you must specify USING qss clause.
CREATE TABLE tab_qss(c1 int, c2 text) USING qss;
CREATE MATERIALIZED VIEW mat_view_qss USING qss AS
SELECT c1, string_agg(c2, ','), count(1) FROM tab_qss GROUP BY c1;
It is not possible to convert an already created table into an encrypted one or
vice versa (using ALTER TABLE).
RBytea
The RBytea module allows you to create rbytea columns.
Encryption of all rbytea columns is controlled by a single parameter, rather than separately for each table. However, it is possible to have both encrypted and unencrypted rbytea values at the same time. Each individual value is encrypted (or not encrypted) depending on the parameter setting at any particular moment. Thus, you can turn RBytea encryption on and off.
The parameter
rbytea.filesystem_qss_mode = 2
If qss_mode = 0, the value of this parameter is ignored.
For more information on RBytea configuration parameters, see Section Configuration.
Note
When encrypting rbytea, it is not possible to use values of this type in such a mode, when rbytea data is stored in a single copy for several cluster nodes on network storage, since different nodes will use different QSS keys.
Statistics Encryption
Statistics on table data may contain sensitive information, such as the most common values in each column. It is advisable to encrypt statistics on encrypted tables as well. To do this, you need to additionally enable qss_encrypt_statistic parameter.
After this, statistics are placed instead of catalog tables pg_statistic, pg_statistic_ext_data into similar encrypted tables qss_statistic, qss_statistic_ext_data. Statistics for unencrypted tables will also be stored there.
After switching, statistics will not be immediately available, which may lead to bad query execution plans. You have the following options for how to fill them:
- to execute
VACUUM ANALYZE; - to wait for autovacuum to do the same (i.e. if you do nothing, then statistics will be collected "themselves");
- to copy the existing statistics using the query so as not to wait for
VACUUM ANALYZE:
DELETE FROM qss_statistic;
INSERT INTO qss_statistic SELECT * FROM pg_statistic;
DELETE FROM qss_statistic_ext_data;
INSERT INTO qss_statistic_ext_data SELECT * FROM pg_statistic_ext_data;
(When qss_encrypt_statistic is turned off, a reverse copy occurs.)
After enabling statistics encryption, it is recommended to delete unencrypted ones:
DELETE FROM pg_statistic;
DELETE FROM pg_statistic_ext_data;
CAUTION
The pg_statistic_ext table must not be touched in any scenarios!
Maintenance
In this section, the terms "decrypt table" / "encrypt table" mean dumping the contents of the table and then recreating it. This can be done in a number of ways, such as transferring the data to another table in the same database. In doing so, you may need to drop and recreate constraints, indexes, etc.
Note
General recommendations for ETL (Extract, Transform, Load) apply to these operations.
You cannot load data into an encrypted table using QDL. You can use this module with an unencrypted table, but this feature is not useful in the scenarios described below.
Key Changing
CAUTION
Do not change the key if you have encrypted data. Changing the key is possible only if you have a current active key. It will not be possible to change the key after the key on which the data is encrypted has expired.
- Decrypt all data.
- Make sure that there are no encrypted tables.
- If encrypted statistics were used, then this data must be deleted — turn off qss_encrypt_statistic, then execute:
TRUNCATE TABLE qss_statistic;
TRUNCATE TABLE qss_statistic_ext_data;
(For encrypted tables, the TRUNCATE TABLE operation can be performed even
with QSS disabled).
4. Create another key in QSS, write this key to the qss2_config.toml
file, and restart QHB.
5. Encrypt the tables again.
6. Enable statistics encryption if desired.
Do not allow the key to expire, otherwise it will be impossible to read the data. You can find out the key expiration date in the QSS administrative application.
Migration from QSS 1.0
Migration from QSS version 1.0 will be done simultaneously with migration to another version of QHB. You need to decrypt all tables, migrate, then encrypt the tables again.
Creating Backup
The backup can only be restored to the same host, because the encryption keys are binded to the host and cannot be transferred to another machine (this is the main rule of using QSS, related to security requirements). If the host where QSS and QHB were previously located is no longer usable for some reason (e.g., a technical failure), then it is possible to restore QHB on another machine, provided that it is restored from a backup of the QSS keys (for information on backing up keys, see the documentation supplied with the QSS product).
It is recommended to create a backup using the qbackup. In this case, the backup is created in the usual way, but it is not recommended to use streaming backup with parameter wal-method=stream. To create an encrypted streaming backup, you need to have continuous WAL archiving and streaming backup in the wal-method=fetch or wal-method=none mode.
Also, automatic failover of the cluster node from which the backup is performed cannot be used. Backup files taken from different hosts should not end up in the same backup directory, so automatic failover of the master should not cause the backup to failover to another node.
See the QSS documentation for details.
Replication
Each node needs its own QSS server. Each node will have its own key, the names of the keys can be the same, since the keys will still be different. This will allow all nodes to have identical qss2_config.toml files.
The following replication options are possible (see Section Comparison of Different Solutions):
- Streaming replication (synchronous and asynchronous)
- Logical replication
- Trigger-based primary-standby replication
- SQL-based replication middleware (via query repeater, etc.)
Replication options that will not work with QSS:
- On shared disks (network drive or FS-level replication)
- Write-ahead log shipping
Each node must have the same value for the qss_mode parameter. When enabling and configuring encryption on the master, it is mandatory to enable and configure encryption on the replica before starting to populate the encrypted table with data. Otherwise, the replication node will stop functioning
IMPORTANT!
You can connect a node to streaming replication only if there are no encrypted tables. In particular, statistics encryption should not be enabled, the qss_statistic and qss_statistic_ext_data tables should be empty.
Features and Limitations of Encryption in QHB
-
It is not possible to encrypt and decrypt (using the
ALTER TABLEcommand) a table that was already created. -
When encrypting RBytea, you cannot store data of this type in a single copy for several cluster nodes in network storage.
-
Re-encryption is only possible by decryption and re-encryption.
-
It is not possible to load data into encrypted tables using the QDL module.
-
A backup can only be restored to the same host from which it was made.
-
All cluster nodes must be created before encryption starts. You cannot connect a new streaming replication node after encryption has started.
-
Unable to encrypt partitioned tables.
-
Unable to use the APPEND_ONLY parameter for encrypted tables.
-
Unable to encrypt catalog tables (e.g., stored procedures).
-
Unable to encrypt individual columns
-
A database that contains encrypted tables cannot be used as a template in
CREATE DATABASE.
See Also
Installing the QSS Encryption Module Using the Sobol PRNG HSS