Essential Configuration Settings for Securing Your PostgreSQL Database
Secure PostgreSQL with pg_hba.conf rules, SCRAM authentication, TLS enforcement, limited listeners, least privilege, and audit logs.
Essential Configuration Settings for Securing Your PostgreSQL Database
Securing PostgreSQL starts with a simple question: who is allowed to connect, from where, and with what authentication method? If pg_hba.conf is too broad or the server listens on more interfaces than it needs, your database has a larger attack surface than necessary.
This guide covers the PostgreSQL security settings you should review first: pg_hba.conf, SCRAM password authentication, TLS, network listeners, role permissions, and logs.
1. Hardening Client Authentication with pg_hba.conf
The Host-Based Authentication file (pg_hba.conf) dictates which hosts can connect, which PostgreSQL users they can connect as, which databases they can access, and most importantly, the authentication method required for that connection.
Understanding pg_hba.conf Structure
Each line in pg_hba.conf follows a specific format:
TYPE DATABASE USER ADDRESS METHOD [OPTIONS]
- TYPE: Connection type (e.g.,
local,host,hostnossl,hostssl). - DATABASE: Target database name(s).
- USER: Target database role(s).
- ADDRESS: Client IP address range.
- METHOD: Authentication mechanism (e.g.,
scram-sha-256,md5,reject,trust).
Best Practices for Authentication Methods
Never use the trust method in production, as it allows anyone matching the connection criteria to connect without a password. The recommended modern authentication methods are:
Recommended: scram-sha-256
SCRAM (Salted Challenge Response Authentication Mechanism) offers significant improvements over older password methods like md5 by using stronger hashing and preventing replay attacks. This should be your default choice for remote connections.
# Enforce SCRAM for remote connections from an application subnet
host appdb app_user 10.20.30.0/24 scram-sha-256
Set password_encryption = 'scram-sha-256' in postgresql.conf before creating or rotating passwords. Existing passwords stored with older hashes are not automatically converted; reset them after enabling SCRAM.
password_encryption = 'scram-sha-256'
Avoid broad rules like this unless another network control already restricts access:
host all all 0.0.0.0/0 scram-sha-256
Local Connections
For connections originating from the server itself (e.g., applications running on the same machine), use local sockets. The most secure setting is often peer (for Unix domain sockets) or scram-sha-256 if sockets are disabled or restricted.
# Use peer authentication for local connections via Unix socket
local all all peer
Explicitly Rejecting Connections
Use the reject method to explicitly block connections from dangerous or untrusted networks.
# Block all connections from a known insecure IP range
host all all 192.168.1.0/24 reject
Actionable Tip: After modifying
pg_hba.conf, reload PostgreSQL for changes to take effect, for example withsudo systemctl reload postgresqlorSELECT pg_reload_conf();.
2. Implementing SSL/TLS Encryption
To prevent sensitive data (including passwords) from being intercepted over the network, enforcing SSL/TLS encryption for all remote connections is mandatory.
Configuration in postgresql.conf
Ensure these parameters are set correctly in your primary configuration file:
ssl = on: Enables SSL support globally.ssl_cert_file: Path to the server certificate file (e.g.,server.crt).ssl_key_file: Path to the server private key file (e.g.,server.key).
Enforcing SSL in pg_hba.conf
To force clients to use SSL, change the connection type in pg_hba.conf from host to hostssl:
# Only allow connections via SSL/TLS
hostssl all all 0.0.0.0/0 scram-sha-256
hostssl only matches SSL connections. Make sure you do not also have a later or earlier host rule that allows the same users without TLS. To make the policy obvious, add a reject rule for non-SSL connections:
hostnossl all all 0.0.0.0/0 reject
3. Minimizing the Attack Surface Area
Security involves reducing the exposure of the database server to external threats. This is primarily managed through network configuration and disabling unnecessary features.
Limiting Network Listen Address
PostgreSQL commonly defaults to listening on localhost, but packaged deployments and managed images can differ. Explicitly configure it to listen only on the specific interface that requires access, or keep it on localhost if only local applications connect.
In postgresql.conf:
# Listen only on localhost (127.0.0.1) if possible
listen_addresses = 'localhost'
# OR, listen only on a specific private network interface
# listen_addresses = '192.168.1.10'
Security Warning: If
listen_addressesis set to*, all interfaces will be used. Ensurepg_hba.confstrictly controls which IP ranges can connect.
Disabling Unnecessary Extensions and Features
Every enabled extension adds potential complexity and attack vectors. Regularly audit installed extensions and remove any that are not actively used for your production workload. This minimizes the overall attack surface.
Password Security and Roles
Ensure all administrative roles (like the default postgres user) have strong, complex passwords set using ALTER USER:
ALTER USER postgres WITH PASSWORD 'YourStrongAndComplexPassword123!';
Use the principle of least privilege: application users should only have SELECT, INSERT, UPDATE, and DELETE permissions on the specific tables they need, rather than superuser status.
4. Auditing and Logging Configuration
While not strictly an access control mechanism, robust logging is crucial for detecting and investigating security incidents. Configure logging parameters in postgresql.conf to capture relevant events.
Key settings for security auditing:
log_statement = 'ddl'or'all': Logs all Data Definition Language (DDL) commands, such asCREATE TABLEandALTER USER. Use'all'carefully because it can create high log volume and may capture sensitive query text.log_connections = on: Logs every successful connection attempt.log_disconnections = on: Logs when clients disconnect.log_duration = on: Logs the execution time of all statements, which can sometimes reveal unusual activity patterns.
By combining strict access rules in pg_hba.conf, enforced encryption via SSL, a restricted listening address, and comprehensive logging, you establish a solid foundation for securing your PostgreSQL deployment.
Essential Security Steps
- Update
pg_hba.conf: Usescram-sha-256orpeerfor authentication methods. - Enforce Encryption: Set
ssl = oninpostgresql.confand usehostsslentries inpg_hba.conf. - Restrict Listening: Configure
listen_addressesto only necessary interfaces, avoiding the default*if possible. - Enforce Least Privilege: Limit database roles to only the permissions absolutely required for their function.
- Reload Configuration: Always reload or restart PostgreSQL after modifying security files to apply changes.
These settings are the foundation. After you apply them, test from an allowed client, test from a blocked client, and verify that logs show the connection behavior you expected.