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:
- Restart services:
systemctl restart postgresql service iptables restart
- Test connectivity from client:
psql -h postgres-server-ip -U username -d database_name telnet postgres-server-ip 5432
- 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