Updated 2 hours ago
PostgreSQL listens on port 5432 by default. Every query, every transaction, every administrative command flows through this single door. That makes it both the gateway to your data and the chokepoint where security either holds or fails.
The Single Door
When PostgreSQL starts, it binds to port 5432 and waits. The port number itself is arbitrary—assigned by IANA, changeable in postgresql.conf—but nearly universal across installations. This universality makes it a known target. Anyone scanning a network knows exactly where to look.
All PostgreSQL traffic shares this port: local applications, remote services, administrative tools. There's no separate management port, no out-of-band channel. Everything enters through the same door, which means securing that door is everything.
Local vs. Remote: Two Different Worlds
PostgreSQL treats local and remote connections differently, and for good reason.
Local connections—where the client runs on the same machine as the database—can bypass TCP entirely. Unix domain sockets let applications talk to PostgreSQL without touching the network stack. Faster, and one less attack surface.
Remote connections must use TCP/IP. By default, PostgreSQL refuses them entirely. You have to explicitly open the door.
Opening that door requires two changes:
-
postgresql.conf: Set
listen_addressesto specify which interfaces PostgreSQL listens on. The default ('localhost') accepts only local connections. Setting it to '*' listens on all interfaces. -
pg_hba.conf: Define who can connect, to what, and how they prove they're allowed.
The first change determines whether PostgreSQL can hear remote connections. The second determines whether it lets them in.
pg_hba.conf: The Bouncer
The pg_hba.conf file is PostgreSQL's access control list. Each line is a rule: connection type, database, user, client address, authentication method. PostgreSQL reads these rules top to bottom, stopping at the first match.
Put a permissive rule at the top, and everything below it becomes decoration. This is where most security mistakes happen—not from missing rules, but from rules in the wrong order.
A typical entry looks like:
This says: SSL connections to the production database from the 10.0.1.0/24 network, authenticating as app_user with scram-sha-256, are allowed.
Authentication methods range from trusting everyone (never in production) to requiring cryptographic proof:
- trust: No authentication. The database believes whoever claims to be connecting. Development only.
- scram-sha-256: Modern password authentication. The password never crosses the wire in recoverable form.
- cert: The client proves identity with an SSL certificate. No password to steal, no credential to phish.
- peer: For local connections, matches the operating system username to the database username. If the OS says you're "postgres," the database believes it.
For production, scram-sha-256 is the minimum. Certificate authentication is better when you can manage the PKI.
SSL/TLS: Encrypting the Pipe
Without SSL, everything over port 5432 travels in plaintext. Passwords, queries, results—readable by anyone who can see the traffic.
Enabling SSL requires a certificate and private key. Self-signed works for development; production needs certificates from a trusted authority.
The pg_hba.conf file controls SSL requirements through connection types:
- hostssl: Requires SSL. Unencrypted connections are rejected.
- hostnossl: Forbids SSL. Rarely useful.
- host: Accepts either.
For remote connections over any network you don't completely control, use hostssl exclusively.
Clients must also be configured. The sslmode parameter controls what the client requires:
- disable: Never use SSL.
- require: Use SSL, but don't verify the certificate.
- verify-full: Use SSL, verify the certificate is trusted and matches the server hostname.
Only verify-full protects against man-in-the-middle attacks. With anything less, you're encrypting your connection to whoever intercepted it.
Defense in Depth
Port 5432 should never face the public Internet directly. Not because PostgreSQL can't be secured, but because reducing attack surface is free and forgiveness is expensive.
Network isolation: Put databases on private networks. Access them through VPNs, SSH tunnels, or bastion hosts. Firewalls should whitelist specific IPs, not ranges.
Strong authentication: scram-sha-256 minimum, certificates when possible. Never store superuser credentials in application configs.
Least privilege: Application users get only the permissions they need. Read-only replicas for reporting. Separate users for separate applications.
Monitoring: Log connection attempts, failed authentications, unusual query patterns. PostgreSQL's logging is comprehensive when configured.
Rate limiting: Firewalls or tools like fail2ban can block IPs after repeated failed attempts. Brute-force attacks against port 5432 are common; make them futile.
Connection Pooling: PgBouncer
PostgreSQL spawns a process for every connection. For applications that connect and disconnect frequently, this overhead adds up.
PgBouncer sits between applications and PostgreSQL, maintaining a pool of persistent connections. Applications connect to PgBouncer (typically port 6432), which multiplexes them onto fewer PostgreSQL connections.
Three pooling modes:
- Session: One PostgreSQL connection per client session. Maximum compatibility, minimum pooling benefit.
- Transaction: Connections return to the pool after each transaction. More clients share fewer connections, but session-level features break.
- Statement: Connections return after each statement. Aggressive but incompatible with transactions.
Transaction pooling hits the sweet spot for most applications.
PgBouncer also tightens security. Configure PostgreSQL to accept connections only from PgBouncer's IP. Now the database has exactly one client to trust, and PgBouncer handles the complexity of authenticating many.
Frequently Asked Questions About Port 5432
Was this page helpful?