How to Fix Firewall Rules for PostgreSQL Remote Access on CentOS (iptables Configuration Guide)


9 views

When setting up remote PostgreSQL access on CentOS, the difference between these two error messages reveals crucial firewall configuration insights:

# Timeout error indicates blocked traffic
Ncat: connection timed out

# Connection refused suggests PostgreSQL isn't listening
Ncat: Connection refused

First verify PostgreSQL is actually configured to listen:

# Check postgresql.conf
grep listen_addresses /var/lib/pgsql/data/postgresql.conf
# Should show:
listen_addresses = '*'

# Verify pg_hba.conf has appropriate host entries
host    all             all             0.0.0.0/0               md5

The guide's recommended rules need refinement. Here's what actually works:

# Inbound rule (NEW connections)
-A INPUT -p tcp -m tcp --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT

# Outbound rule (responses)
-A OUTPUT -p tcp -m tcp --sport 5432 -m state --state ESTABLISHED -j ACCEPT

# Alternative for specific IP access
-A INPUT -p tcp -s 192.168.1.100 --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT

When troubleshooting:

# Check current iptables rules
iptables -L -n -v

# Test basic connectivity
telnet your_server_ip 5432

# Verify PostgreSQL is running
systemctl status postgresql

# Check listening ports
netstat -tulnp | grep 5432
  • SELinux blocking connections (check with getenforce)
  • Network Address Translation (NAT) issues when connecting through VPN
  • Multiple firewall systems running simultaneously (firewalld vs iptables)

For a server allowing connections from 192.168.1.0/24:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# PostgreSQL Rules
-A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -d 192.168.1.0/24 -p tcp -m tcp --sport 5432 -m state --state ESTABLISHED -j ACCEPT

# Default deny
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

Save to /etc/sysconfig/iptables and restart with systemctl restart iptables


When configuring remote PostgreSQL access on CentOS 7 with iptables, you're likely encountering two distinct network-level errors:

  • Connection timed out - Indicates packets aren't reaching the PostgreSQL service (firewall blocking)
  • Connection refused - Means packets reach the host but PostgreSQL isn't listening (service configuration issue)

Here's the proper ruleset that handles both inbound and outbound traffic for PostgreSQL:

# Allow new and established inbound connections
-A INPUT -p tcp -s 192.168.1.0/24 --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT

# Allow established outbound connections
-A OUTPUT -p tcp --sport 5432 -m state --state ESTABLISHED -j ACCEPT

# For specific IP access (replace 1.2.3.4 with client IP)
-A INPUT -p tcp -s 1.2.3.4 --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT

Before firewall adjustments, ensure PostgreSQL is properly configured:

# In postgresql.conf (usually /var/lib/pgsql/data/postgresql.conf)
listen_addresses = '*'

# In pg_hba.conf
host    all             all             192.168.1.0/24          md5
host    all             all             1.2.3.4/32              md5

After implementing changes:

  1. Restart services:
    systemctl restart postgresql
    service iptables restart
  2. Test connectivity from client:
    psql -h postgres-server-ip -U username -d database_name
    telnet postgres-server-ip 5432
  3. Check service status:
    ss -tulnp | grep postgres
    journalctl -xe

For CentOS 7 with iptables (firewalld disabled):

# Save current rules
iptables-save > /etc/sysconfig/iptables

# Make rules persistent
systemctl enable iptables
systemctl start iptables

Consider using a dedicated chain for PostgreSQL rules for better management:

# Create chain
iptables -N POSTGRESQL

# Add rules to chain
iptables -A POSTGRESQL -p tcp --dport 5432 -j ACCEPT

# Reference chain in INPUT
iptables -A INPUT -j POSTGRESQL