Cookbook recipe

SSL Not Enforced

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Scenario A compliance audit requires all database connections to be encrypted in transit. PostgreSQL has SSL configured (ssl = on, certificates present) but pg_stat_ssl shows 80% of active connections have ssl = false. The DBA checks…

Investigation Path

Scenario

A compliance audit requires all database connections to be encrypted in transit. PostgreSQL has SSL configured (ssl = on, certificates present) but pg_stat_ssl shows 80% of active connections have ssl = false. The DBA checks pg_hba.conf and finds it uses host (not hostssl) for all rules — clients can choose to connect with or without SSL, and most don’t bother enabling it.

How to Identify

Conditions:

  • pg_stat_ssl shows many connections with ssl = false
  • pg_hba.conf uses host type (allows both SSL and non-SSL)
  • ssl = on in postgresql.conf but not enforced at connection level
  • Application connection strings don’t specify sslmode=require
  • ssl_min_protocol_version not set — old TLS versions allowed

Analysis Steps

-- Check how many connections are unencrypted
SELECT
    ssl,
    count(*) AS connections,
    round(100.0 * count(*) / sum(count(*)) OVER (), 1) AS pct
FROM pg_stat_ssl
JOIN pg_stat_activity USING (pid)
WHERE backend_type = 'client backend'
GROUP BY ssl;

-- See encryption details for current connections
SELECT a.pid, a.usename, a.client_addr, s.ssl, s.version, s.cipher, s.bits
FROM pg_stat_ssl s
JOIN pg_stat_activity a USING (pid)
WHERE a.backend_type = 'client backend'
ORDER BY s.ssl, a.usename;

-- Check SSL configuration
SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;
SHOW ssl_min_protocol_version;

-- Check pg_hba.conf for SSL enforcement
SELECT line_num, type, database, user_name, address, auth_method
FROM pg_hba_file_rules
ORDER BY line_num;
-- 'host' = allows SSL or non-SSL
-- 'hostssl' = requires SSL
-- 'hostnossl' = requires non-SSL (for internal trusted networks)

Pitfalls

  • ssl = on in postgresql.conf only enables SSL — it does not require it. Clients can still connect without SSL unless hostssl is used in pg_hba.conf.
  • Changing host to hostssl in pg_hba.conf only requires a reload — but application connection strings must also specify sslmode=require or sslmode=verify-full to actually use SSL.
  • ssl_min_protocol_version = 'TLSv1.2' prevents downgrade attacks to older TLS versions (SSLv3, TLSv1.0, TLSv1.1).
  • sslmode=verify-full in the client connection string verifies both encryption and that the server’s certificate matches the hostname — best security but requires proper certificate setup.
  • Self-signed certificates work for encryption but not for certificate verification (verify-full) — use a CA-signed certificate for production compliance.

Resolution Approach

Replace host with hostssl in pg_hba.conf for all rules that should require encryption. Set ssl_min_protocol_version = 'TLSv1.2'. Update application connection strings to sslmode=require. Reload PostgreSQL configuration.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Mitigation Actions
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes