CIS PostgreSQL 16 Benchmark
Secure configuration guidelines for PostgreSQL 16 database server
v1.0.0 August 2024Overview
▶This CIS Benchmark provides prescriptive guidance for establishing a secure configuration posture for PostgreSQL 16. Recommendations cover installation hardening, access control, logging, authentication, SSL/TLS, and replication security.
| Section | Area | Focus |
|---|---|---|
| 1 | Installation & Patches | Secure install, version management, updates |
| 2 | Directory & File Permissions | Data directory, config file permissions |
| 3 | Logging & Auditing | Log destination, content, rotation |
| 4 | User Access & Authorization | Superuser, roles, privileges, schemas |
| 5 | Connection & Authentication | pg_hba.conf, SSL/TLS, password encryption |
| 6 | Replication & Backup | Streaming replication, WAL, backup config |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Server | Essential database hardening with minimal operational impact. |
| L2 | Level 2 — Server | Advanced defense-in-depth. May require application changes. |
1 — Installation & Patches
▶1.1 Installation
▶This recommendation verifies that PostgreSQL Is Installed from Official Repositories on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to postgreSQL Is Installed from Official Repositories may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
psql --version # Verify installed from PGDG or OS vendor packages rpm -qi postgresql16-server 2>/dev/null || dpkg -s postgresql-16 2>/dev/null
Install PostgreSQL 16 from the official PostgreSQL Global Development Group (PGDG) repository: https://www.postgresql.org/download/
This recommendation verifies that a Dedicated OS Account for PostgreSQL on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to a Dedicated OS Account for PostgreSQL may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
id postgres # Should exist with a dedicated home directory and nologin or restricted shell
# The 'postgres' OS user is created by default during installation. # Ensure it has a restricted shell: usermod -s /sbin/nologin postgres
This recommendation verifies that Only Required Extensions Are Installed on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to only Required Extensions Are Installed may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT name, installed_version FROM pg_available_extensions WHERE installed_version IS NOT NULL;
-- Remove unnecessary extensions: DROP EXTENSION IF EXISTS <extension_name>;
1.2 Patches & Updates
▶This recommendation verifies that the Latest Security Patches Are Applied on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to the Latest Security Patches Are Applied may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT version(); -- Compare against https://www.postgresql.org/support/versioning/
# Update to latest minor version: dnf update postgresql16-server # or apt upgrade postgresql-16
2 — Directory & File Permissions
▶2.1 Data Directory
▶This setting ensures that PGDATA Permissions is restricted on the PostgreSQL 16 database server. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted PGDATA Permissions could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the PostgreSQL 16 database server is essential for defense in depth.
SHOW data_directory; -- Then check: ls -ld /var/lib/pgsql/16/data/ # Should be drwx------ (0700) owned by postgres:postgres
chmod 700 /var/lib/pgsql/16/data/ chown postgres:postgres /var/lib/pgsql/16/data/
This setting ensures that WAL Directory Permissions is restricted on the PostgreSQL 16 database server. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted WAL Directory Permissions could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the PostgreSQL 16 database server is essential for defense in depth.
ls -ld /var/lib/pgsql/16/data/pg_wal/ # Should be drwx------ (0700) owned by postgres:postgres
chmod 700 /var/lib/pgsql/16/data/pg_wal/ chown postgres:postgres /var/lib/pgsql/16/data/pg_wal/
2.2 Configuration Files
▶File and directory permissions for postgresql.conf should be set to 600. Overly permissive access controls can allow unauthorized users to read, modify, or execute sensitive files, potentially compromising the PostgreSQL 16 database server.
Incorrect permissions on postgresql.conf could allow unauthorized reading, writing, or execution of critical files. Proper file permissions are a foundational control that prevents privilege escalation and data tampering.
SHOW config_file; -- Check permissions: stat -c '%a %U %G' /var/lib/pgsql/16/data/postgresql.conf # Should be 600 postgres postgres
chmod 600 /var/lib/pgsql/16/data/postgresql.conf chown postgres:postgres /var/lib/pgsql/16/data/postgresql.conf
File and directory permissions for pg_hba.conf should be set to 600. Overly permissive access controls can allow unauthorized users to read, modify, or execute sensitive files, potentially compromising the PostgreSQL 16 database server.
Incorrect permissions on pg_hba.conf could allow unauthorized reading, writing, or execution of critical files. Proper file permissions are a foundational control that prevents privilege escalation and data tampering.
SHOW hba_file; -- Check permissions: stat -c '%a %U %G' /var/lib/pgsql/16/data/pg_hba.conf # Should be 600 postgres postgres
chmod 600 /var/lib/pgsql/16/data/pg_hba.conf chown postgres:postgres /var/lib/pgsql/16/data/pg_hba.conf
3 — Logging & Auditing
▶3.1 Log Settings
▶This setting controls whether Logging is enabled on the PostgreSQL 16 database server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via postgresql.conf, pg_hba.conf, or SQL commands.
Without Logging enabled, the PostgreSQL 16 database server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
SHOW logging_collector; -- Should be: on
-- postgresql.conf: logging_collector = on
This recommendation addresses the proper configuration of Log Destination on the PostgreSQL 16 database server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of Log Destination can lead to security gaps that may be exploited by attackers. A properly configured PostgreSQL 16 database server reduces exposure to both known vulnerabilities and configuration drift.
SHOW log_destination; -- Should be: stderr or csvlog (or syslog)
-- postgresql.conf: log_destination = 'stderr' log_directory = 'log' log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
This recommendation addresses the proper configuration of Log Rotation on the PostgreSQL 16 database server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of Log Rotation can lead to security gaps that may be exploited by attackers. A properly configured PostgreSQL 16 database server reduces exposure to both known vulnerabilities and configuration drift.
SHOW log_rotation_age; SHOW log_rotation_size; -- Recommended: log_rotation_age = 1d
-- postgresql.conf: log_rotation_age = 1d log_rotation_size = 100MB log_truncate_on_rotation = on
3.2 Log Content
▶This setting controls whether log_connections is enabled on the PostgreSQL 16 database server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via postgresql.conf, pg_hba.conf, or SQL commands.
Without log_connections enabled, the PostgreSQL 16 database server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
SHOW log_connections; -- Should be: on
-- postgresql.conf: log_connections = on
This setting controls whether log_disconnections is enabled on the PostgreSQL 16 database server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via postgresql.conf, pg_hba.conf, or SQL commands.
Without log_disconnections enabled, the PostgreSQL 16 database server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
SHOW log_disconnections; -- Should be: on
-- postgresql.conf: log_disconnections = on
This recommendation configures log_statement to DDL or All on the PostgreSQL 16 database server. Setting this value appropriately ensures the system operates within the security parameters defined by the CIS benchmark.
An improperly configured value for log_statement could weaken security controls or allow unintended behavior. Setting this to DDL or All ensures the PostgreSQL 16 database server operates within a well-defined security boundary.
SHOW log_statement; -- Should be: ddl or all
-- postgresql.conf: log_statement = 'ddl'
This recommendation addresses the proper configuration of log_line_prefix on the PostgreSQL 16 database server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of log_line_prefix can lead to security gaps that may be exploited by attackers. A properly configured PostgreSQL 16 database server reduces exposure to both known vulnerabilities and configuration drift.
SHOW log_line_prefix; -- Should include timestamp, user, database, and process ID
-- postgresql.conf: log_line_prefix = '%m [%p] %u@%d '
This setting controls whether pgAudit Extension is enabled on the PostgreSQL 16 database server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via postgresql.conf, pg_hba.conf, or SQL commands.
Without pgAudit Extension enabled, the PostgreSQL 16 database server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
SHOW shared_preload_libraries; -- Should include: pgaudit SELECT * FROM pg_available_extensions WHERE name = 'pgaudit';
-- postgresql.conf: shared_preload_libraries = 'pgaudit' -- After restart: CREATE EXTENSION pgaudit; -- Configure audit settings: pgaudit.log = 'write, ddl, role'
4 — User Access & Authorization
▶4.1 Superuser Access
▶This recommendation verifies that Superuser Accounts Are Minimized on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to superuser Accounts Are Minimized may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT rolname FROM pg_roles WHERE rolsuper = true; -- Should only show 'postgres'
-- Remove superuser from unnecessary accounts: ALTER ROLE <rolename> NOSUPERUSER;
This recommendation verifies that the postgres Superuser Has a Strong Password on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to the postgres Superuser Has a Strong Password may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
-- Verify password is set (not trust or peer-only): SELECT rolpassword IS NOT NULL as has_password FROM pg_authid WHERE rolname = 'postgres';
\password postgres -- Enter a strong password (14+ characters, mixed case, numbers, special)
4.2 Roles & Privileges
▶This recommendation verifies that No Roles Have CREATEDB Unnecessarily on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to no Roles Have CREATEDB Unnecessarily may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT rolname FROM pg_roles WHERE rolcreatedb = true AND rolname != 'postgres';
ALTER ROLE <rolename> NOCREATEDB;
This recommendation verifies that No Roles Have CREATEROLE Unnecessarily on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to no Roles Have CREATEROLE Unnecessarily may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT rolname FROM pg_roles WHERE rolcreaterole = true AND rolname != 'postgres';
ALTER ROLE <rolename> NOCREATEROLE;
This recommendation verifies that PUBLIC Schema Has Restricted Privileges on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to pUBLIC Schema Has Restricted Privileges may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'public'; -- Should NOT have broad CREATE or USAGE for PUBLIC
REVOKE CREATE ON SCHEMA public FROM PUBLIC; REVOKE ALL ON DATABASE <dbname> FROM PUBLIC;
This recommendation verifies that Row-Level Security Is Used Where Appropriate on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to row-Level Security Is Used Where Appropriate may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE rowsecurity = true;
-- For multi-tenant tables:
ALTER TABLE <tablename> ENABLE ROW LEVEL SECURITY;
CREATE POLICY <policy_name> ON <tablename>
USING (tenant_id = current_setting('app.current_tenant')::int);5 — Connection & Authentication
▶5.1 pg_hba.conf
▶"trust" Authentication should not be used on the PostgreSQL 16 database server. Removing or disabling this component reduces the attack surface and prevents potential exploitation of unnecessary services or features.
If "trust" Authentication remains used, it presents an unnecessary risk vector that attackers could exploit. Removing or disabling unused components is a fundamental principle of secure system hardening.
grep -v '^#' /var/lib/pgsql/16/data/pg_hba.conf | grep trust -- Or via SQL: SELECT * FROM pg_hba_file_rules WHERE auth_method = 'trust';
# Replace 'trust' with 'scram-sha-256' in pg_hba.conf: # local all all scram-sha-256 # host all all 127.0.0.1/32 scram-sha-256 SELECT pg_reload_conf();
"password" Authentication should not be used on the PostgreSQL 16 database server. Removing or disabling this component reduces the attack surface and prevents potential exploitation of unnecessary services or features.
If "password" Authentication remains used, it presents an unnecessary risk vector that attackers could exploit. Removing or disabling unused components is a fundamental principle of secure system hardening.
SELECT * FROM pg_hba_file_rules WHERE auth_method = 'password';
-- Should return 0 rows ("password" sends cleartext)# Replace 'password' with 'scram-sha-256' in pg_hba.conf # Requires password_encryption = scram-sha-256 in postgresql.conf
This recommendation verifies that password_encryption Is scram-sha-256 on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to password_encryption Is scram-sha-256 may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SHOW password_encryption; -- Should be: scram-sha-256
-- postgresql.conf: password_encryption = 'scram-sha-256' -- Reset existing md5 passwords after changing: ALTER ROLE <rolename> PASSWORD '<new_password>';
5.2 SSL/TLS
▶This setting controls whether SSL is enabled on the PostgreSQL 16 database server. Enabling this feature strengthens the security posture by enforcing the recommended configuration via postgresql.conf, pg_hba.conf, or SQL commands.
Without SSL enabled, the PostgreSQL 16 database server may lack critical protections against known attack vectors. Enabling this control mitigates risk and aligns the deployment with industry-accepted security baselines.
SHOW ssl; -- Should be: on
-- postgresql.conf: ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key' ssl_ca_file = 'root.crt'
This recommendation verifies that Only Strong SSL Ciphers Are Used on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to only Strong SSL Ciphers Are Used may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SHOW ssl_ciphers; SHOW ssl_min_protocol_version; -- Should be TLSv1.2 or TLSv1.3 minimum
-- postgresql.conf: ssl_min_protocol_version = 'TLSv1.2' ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
This setting enforces that SSL Client Authentication is required on the PostgreSQL 16 database server. Making this mandatory ensures consistent security policy enforcement across the environment.
Failure to sSL Client Authentication Is Required may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check pg_hba.conf for 'hostssl' entries with 'cert' auth_method grep hostssl /var/lib/pgsql/16/data/pg_hba.conf
# pg_hba.conf: hostssl all all 0.0.0.0/0 cert
6 — Replication & Backup
▶6.1 Replication Settings
▶This recommendation verifies that Replication Users Are Minimized on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to replication Users Are Minimized may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
SELECT rolname FROM pg_roles WHERE rolreplication = true; -- Should only show dedicated replication accounts
ALTER ROLE <rolename> NOREPLICATION;
This setting ensures that Replication uses encryption on the PostgreSQL 16 database server. Encrypting data in transit and at rest protects sensitive information from interception and unauthorized disclosure.
Without encryption, Replication may transmit or store sensitive information in cleartext, exposing it to interception, eavesdropping, or tampering. Encryption is a critical control for data confidentiality and integrity.
# Check pg_hba.conf for replication entries: grep replication /var/lib/pgsql/16/data/pg_hba.conf -- Should use hostssl, not host
# pg_hba.conf: hostssl replication replicator 10.0.0.0/24 scram-sha-256
6.2 Backup Configuration
▶This recommendation addresses the proper configuration of WAL Archiving on the PostgreSQL 16 database server. Proper configuration ensures the component operates securely and in accordance with organizational security policies.
Misconfiguration of WAL Archiving can lead to security gaps that may be exploited by attackers. A properly configured PostgreSQL 16 database server reduces exposure to both known vulnerabilities and configuration drift.
SHOW archive_mode; SHOW archive_command; -- archive_mode should be 'on', archive_command should be set
-- postgresql.conf: archive_mode = on archive_command = 'cp %p /var/lib/pgsql/wal_archive/%f'
This recommendation verifies that Regular Backups Are Tested on the PostgreSQL 16 database server. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to regular Backups Are Tested may leave the PostgreSQL 16 database server vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
Review backup schedules, retention policies, and documented test results for pg_basebackup or pgBackRest operations.
# Schedule regular base backups: pg_basebackup -D /var/lib/pgsql/backups -Ft -z -P -U replicator # Or use pgBackRest for enterprise backup management