Tight pg_hba.conf rules decide who gets a seat at the PostgreSQL table and who gets shown the door, making them a primary control for preventing accidental exposure of port 5432.
The file contains host-based authentication (HBA) records that match on connection type (local for Unix sockets, host for TCP), target database, role name, and client address. PostgreSQL evaluates the file from top to bottom and applies the first matching record to every new connection attempt, so specificity and ordering determine the effective access policy.
A single permissive line near the top can override intended restrictions, and an overly strict change can lock out remote administration. Always locate the live file using SHOW hba_file;, prefer scram-sha-256 over legacy md5 where possible, and reload the server so only new connections see the updated policy.
Related: How to restrict remote access in PostgreSQL \\
Related: How to enable SSL for PostgreSQL connections
Steps to configure pg_hba.conf in PostgreSQL:
- Print the active pg_hba.conf path from the running server.
$ sudo -u postgres psql -Atc 'SHOW hba_file;' /etc/postgresql/16/main/pg_hba.conf
- Create a backup copy of the current pg_hba.conf before editing.
$ sudo cp -a /etc/postgresql/16/main/pg_hba.conf /etc/postgresql/16/main/pg_hba.conf.bak
- Open the active pg_hba.conf file for editing with sudo privileges.
$ sudoedit /etc/postgresql/16/main/pg_hba.conf
- Add a specific allow rule for the intended database, role, and client network near the top of the file.
# TYPE DATABASE USER ADDRESS METHOD host appdb appuser 192.0.2.0/24 scram-sha-256
Records are whitespace-separated fields in the order TYPE, DATABASE, USER, ADDRESS, and METHOD.
- Use the most specific address matches first to avoid broader rules catching the connection earlier.
# A single host should appear above a broader subnet match. host appdb appuser 192.0.2.40/32 scram-sha-256 host appdb appuser 192.0.2.0/24 scram-sha-256
Use hostssl instead of host to require TLS at the server side for that rule.
- Place broad matches and explicit denies below the specific allow rules to preserve first-match behavior.
# Allow the trusted subnet first. host appdb appuser 192.0.2.0/24 scram-sha-256 # Reject everything else over TCP. host all all 0.0.0.0/0 reject host all all ::/0 reject
A broad allow rule above specific entries can silently punch a hole through the policy, and a catch-all reject blocks loopback TCP unless explicit 127.0.0.1/32 and ::1/128 rules appear above it.
- Reload PostgreSQL to apply the updated pg_hba.conf rules without restarting the server.
$ sudo -u postgres psql -c "SELECT pg_reload_conf();" pg_reload_conf ---------------- t (1 row)
Existing sessions remain connected, and only new connections are checked against the updated rules.
- Confirm the file parses cleanly by checking for errors in pg_hba_file_rules.
$ sudo -u postgres psql -c 'SELECT line_number, error FROM pg_hba_file_rules WHERE error IS NOT NULL;' line_number | error -------------+------- (0 rows)
Switching to scram-sha-256 requires role passwords stored in SCRAM format and clients new enough to support SCRAM.
- Test a TCP connection that should be allowed by the new rule from a host inside the permitted network.
$ psql "host=host.example.net dbname=appdb user=appuser sslmode=require" -c 'SELECT current_user, inet_client_addr();' current_user | inet_client_addr --------------+----------------- appuser | 192.0.2.40 (1 row)
- Test a TCP connection that should be rejected from an untrusted network to confirm the deny rules are effective.
$ psql "host=203.0.113.50 dbname=appdb user=appuser sslmode=disable" -c 'SELECT 1;' psql: error: connection to server at "203.0.113.50", port 5432 failed: FATAL: pg_hba.conf rejects connection for host "203.0.113.55", user "appuser", database "appdb", no encryption
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
